1b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/**
2b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * @fileoverview gl-matrix - High performance matrix and vector operations
3b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * @author Brandon Jones
4b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * @author Colin MacKenzie IV
5b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik * @version 2.3.1
6b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik */
7b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
8b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
9b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
10b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikPermission is hereby granted, free of charge, to any person obtaining a copy
11b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikof this software and associated documentation files (the "Software"), to deal
12b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikin the Software without restriction, including without limitation the rights
13b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikto use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikcopies of the Software, and to permit persons to whom the Software is
15b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfurnished to do so, subject to the following conditions:
16b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
17b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikThe above copyright notice and this permission notice shall be included in
18b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikall copies or substantial portions of the Software.
19b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
20b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikTHE SOFTWARE. */
27b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
28b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik(function webpackUniversalModuleDefinition(root, factory) {
29b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	if(typeof exports === 'object' && typeof module === 'object')
30b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		module.exports = factory();
31b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	else if(typeof define === 'function' && define.amd)
32b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		define(factory);
33b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	else {
34b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		var a = factory();
35b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
36b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
37b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik})(this, function() {
38b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikreturn /******/ (function(modules) { // webpackBootstrap
39b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	// The module cache
40b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	var installedModules = {};
41b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
42b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	// The require function
43b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	function __webpack_require__(moduleId) {
44b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
45b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 		// Check if module is in cache
46b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 		if(installedModules[moduleId])
47b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 			return installedModules[moduleId].exports;
48b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
49b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 		// Create a new module (and put it into the cache)
50b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 		var module = installedModules[moduleId] = {
51b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 			exports: {},
52b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 			id: moduleId,
53b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 			loaded: false
54b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 		};
55b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
56b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 		// Execute the module function
57b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
58b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
59b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 		// Flag the module as loaded
60b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 		module.loaded = true;
61b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
62b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 		// Return the exports of the module
63b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 		return module.exports;
64b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	}
65b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
66b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
67b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	// expose the modules object (__webpack_modules__)
68b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	__webpack_require__.m = modules;
69b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
70b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	// expose the module cache
71b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	__webpack_require__.c = installedModules;
72b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
73b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	// __webpack_public_path__
74b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	__webpack_require__.p = "";
75b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
76b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	// Load entry module and return exports
77b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ 	return __webpack_require__(0);
78b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ })
79b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/************************************************************************/
80b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ ([
81b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/* 0 */
82b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ function(module, exports, __webpack_require__) {
83b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
84b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
85b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @fileoverview gl-matrix - High performance matrix and vector operations
86b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @author Brandon Jones
87b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @author Colin MacKenzie IV
88b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @version 2.3.1
89b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
90b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
91b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
92b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
93b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	Permission is hereby granted, free of charge, to any person obtaining a copy
94b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	of this software and associated documentation files (the "Software"), to deal
95b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	in the Software without restriction, including without limitation the rights
96b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
97b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	copies of the Software, and to permit persons to whom the Software is
98b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	furnished to do so, subject to the following conditions:
99b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	The above copyright notice and this permission notice shall be included in
101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	all copies or substantial portions of the Software.
102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE. */
110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	// END HEADER
111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	exports.glMatrix = __webpack_require__(1);
113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	exports.mat2 = __webpack_require__(2);
114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	exports.mat2d = __webpack_require__(3);
115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	exports.mat3 = __webpack_require__(4);
116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	exports.mat4 = __webpack_require__(5);
117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	exports.quat = __webpack_require__(6);
118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	exports.vec2 = __webpack_require__(9);
119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	exports.vec3 = __webpack_require__(7);
120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	exports.vec4 = __webpack_require__(8);
121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ },
123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/* 1 */
124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ function(module, exports, __webpack_require__) {
125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	Permission is hereby granted, free of charge, to any person obtaining a copy
129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	of this software and associated documentation files (the "Software"), to deal
130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	in the Software without restriction, including without limitation the rights
131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	copies of the Software, and to permit persons to whom the Software is
133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	furnished to do so, subject to the following conditions:
134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	The above copyright notice and this permission notice shall be included in
136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	all copies or substantial portions of the Software.
137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE. */
145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @class Common utilities
148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @name glMatrix
149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var glMatrix = {};
151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
152b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	// Constants
153b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	glMatrix.EPSILON = 0.000001;
154b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	glMatrix.ARRAY_TYPE = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
155b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	glMatrix.RANDOM = Math.random;
156b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
157b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
158b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Sets the type of array used when creating new vectors and matrices
159b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
160b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Type} type Array type, such as Float32Array or Array
161b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
162b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	glMatrix.setMatrixArrayType = function(type) {
163b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    GLMAT_ARRAY_TYPE = type;
164b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
165b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
166b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var degree = Math.PI / 180;
167b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
168b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
169b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	* Convert Degree To Radian
170b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	*
171b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	* @param {Number} Angle in Degrees
172b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	*/
173b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	glMatrix.toRadian = function(a){
174b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	     return a * degree;
175b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
176b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
177b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	module.exports = glMatrix;
178b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
179b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
180b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ },
181b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/* 2 */
182b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ function(module, exports, __webpack_require__) {
183b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
184b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
185b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
186b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	Permission is hereby granted, free of charge, to any person obtaining a copy
187b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	of this software and associated documentation files (the "Software"), to deal
188b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	in the Software without restriction, including without limitation the rights
189b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
190b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	copies of the Software, and to permit persons to whom the Software is
191b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	furnished to do so, subject to the following conditions:
192b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
193b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	The above copyright notice and this permission notice shall be included in
194b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	all copies or substantial portions of the Software.
195b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
196b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
197b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
199b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
200b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
201b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
202b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE. */
203b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
204b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var glMatrix = __webpack_require__(1);
205b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
206b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
207b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @class 2x2 Matrix
208b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @name mat2
209b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
210b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var mat2 = {};
211b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
212b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
213b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new identity mat2
214b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
215b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} a new 2x2 matrix
216b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
217b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.create = function() {
218b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(4);
219b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1;
220b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
221b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
222b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 1;
223b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
224b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
225b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
226b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
227b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new mat2 initialized with values from an existing matrix
228b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
229b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} a matrix to clone
230b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} a new 2x2 matrix
231b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
232b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.clone = function(a) {
233b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(4);
234b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
235b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
236b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
237b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
238b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
239b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
240b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
241b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
242b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Copy the values from one mat2 to another
243b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
244b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} out the receiving matrix
245b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} a the source matrix
246b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} out
247b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
248b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.copy = function(out, a) {
249b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
250b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
251b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
252b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
253b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
254b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
255b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
256b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
257b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Set a mat2 to the identity matrix
258b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
259b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} out the receiving matrix
260b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} out
261b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
262b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.identity = function(out) {
263b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1;
264b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
265b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
266b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 1;
267b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
268b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
269b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
270b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
271b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transpose the values of a mat2
272b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
273b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} out the receiving matrix
274b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} a the source matrix
275b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} out
276b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
277b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.transpose = function(out, a) {
278b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // If we are transposing ourselves we can skip a few steps but have to cache some values
279b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (out === a) {
280b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        var a1 = a[1];
281b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[1] = a[2];
282b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[2] = a1;
283b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    } else {
284b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[0] = a[0];
285b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[1] = a[2];
286b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[2] = a[1];
287b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[3] = a[3];
288b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
289b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
290b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
291b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
292b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
293b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
294b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Inverts a mat2
295b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
296b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} out the receiving matrix
297b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} a the source matrix
298b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} out
299b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
300b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.invert = function(out, a) {
301b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
302b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
303b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        // Calculate the determinant
304b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        det = a0 * a3 - a2 * a1;
305b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
306b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (!det) {
307b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return null;
308b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
309b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    det = 1.0 / det;
310b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
311b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] =  a3 * det;
312b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = -a1 * det;
313b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = -a2 * det;
314b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] =  a0 * det;
315b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
316b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
317b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
318b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
319b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
320b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the adjugate of a mat2
321b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
322b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} out the receiving matrix
323b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} a the source matrix
324b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} out
325b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
326b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.adjoint = function(out, a) {
327b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Caching this value is nessecary if out == a
328b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a0 = a[0];
329b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] =  a[3];
330b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = -a[1];
331b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = -a[2];
332b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] =  a0;
333b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
334b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
335b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
336b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
337b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
338b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the determinant of a mat2
339b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
340b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} a the source matrix
341b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} determinant of a
342b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
343b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.determinant = function (a) {
344b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return a[0] * a[3] - a[2] * a[1];
345b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
346b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
347b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
348b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Multiplies two mat2's
349b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
350b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} out the receiving matrix
351b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} a the first operand
352b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} b the second operand
353b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} out
354b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
355b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.multiply = function (out, a, b) {
356b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
357b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
358b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a0 * b0 + a2 * b1;
359b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a1 * b0 + a3 * b1;
360b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a0 * b2 + a2 * b3;
361b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a1 * b2 + a3 * b3;
362b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
363b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
364b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
365b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
366b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link mat2.multiply}
367b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
368b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
369b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.mul = mat2.multiply;
370b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
371b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
372b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotates a mat2 by the given angle
373b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
374b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} out the receiving matrix
375b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} a the matrix to rotate
376b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
377b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} out
378b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
379b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.rotate = function (out, a, rad) {
380b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
381b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        s = Math.sin(rad),
382b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        c = Math.cos(rad);
383b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a0 *  c + a2 * s;
384b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a1 *  c + a3 * s;
385b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a0 * -s + a2 * c;
386b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a1 * -s + a3 * c;
387b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
388b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
389b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
390b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
391b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Scales the mat2 by the dimensions in the given vec2
392b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
393b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} out the receiving matrix
394b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} a the matrix to rotate
395b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} v the vec2 to scale the matrix by
396b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} out
397b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 **/
398b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.scale = function(out, a, v) {
399b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
400b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        v0 = v[0], v1 = v[1];
401b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a0 * v0;
402b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a1 * v0;
403b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a2 * v1;
404b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a3 * v1;
405b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
406b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
407b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
408b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
409b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a given angle
410b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
411b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
412b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat2.identity(dest);
413b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat2.rotate(dest, dest, rad);
414b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
415b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} out mat2 receiving operation result
416b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
417b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} out
418b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
419b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.fromRotation = function(out, rad) {
420b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var s = Math.sin(rad),
421b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        c = Math.cos(rad);
422b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = c;
423b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = s;
424b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = -s;
425b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = c;
426b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
427b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
428b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
429b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
430b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a vector scaling
431b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
432b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
433b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat2.identity(dest);
434b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat2.scale(dest, dest, vec);
435b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
436b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} out mat2 receiving operation result
437b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} v Scaling vector
438b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2} out
439b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
440b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.fromScaling = function(out, v) {
441b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = v[0];
442b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
443b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
444b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = v[1];
445b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
446b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
447b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
448b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
449b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns a string representation of a mat2
450b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
451b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} mat matrix to represent as a string
452b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {String} string representation of the matrix
453b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
454b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.str = function (a) {
455b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
456b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
457b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
458b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
459b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns Frobenius norm of a mat2
460b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
461b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} a the matrix to calculate Frobenius norm of
462b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} Frobenius norm
463b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
464b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.frob = function (a) {
465b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2)))
466b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
467b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
468b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
469b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix
470b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} L the lower triangular matrix
471b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} D the diagonal matrix
472b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} U the upper triangular matrix
473b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} a the input matrix to factorize
474b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
475b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
476b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2.LDU = function (L, D, U, a) {
477b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    L[2] = a[2]/a[0];
478b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    U[0] = a[0];
479b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    U[1] = a[1];
480b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    U[3] = a[3] - L[2] * U[1];
481b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return [L, D, U];
482b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
483b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
484b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
485b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	module.exports = mat2;
486b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
487b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
488b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ },
489b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/* 3 */
490b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ function(module, exports, __webpack_require__) {
491b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
492b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
493b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
494b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	Permission is hereby granted, free of charge, to any person obtaining a copy
495b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	of this software and associated documentation files (the "Software"), to deal
496b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	in the Software without restriction, including without limitation the rights
497b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
498b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	copies of the Software, and to permit persons to whom the Software is
499b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	furnished to do so, subject to the following conditions:
500b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
501b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	The above copyright notice and this permission notice shall be included in
502b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	all copies or substantial portions of the Software.
503b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
504b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
505b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
506b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
507b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
508b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
509b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
510b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE. */
511b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
512b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var glMatrix = __webpack_require__(1);
513b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
514b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
515b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @class 2x3 Matrix
516b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @name mat2d
517b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
518b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @description
519b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * A mat2d contains six elements defined as:
520b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * <pre>
521b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * [a, c, tx,
522b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *  b, d, ty]
523b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * </pre>
524b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is a short form for the 3x3 matrix:
525b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * <pre>
526b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * [a, c, tx,
527b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *  b, d, ty,
528b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *  0, 0, 1]
529b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * </pre>
530b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * The last row is ignored so the array is shorter and operations are faster.
531b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
532b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var mat2d = {};
533b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
534b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
535b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new identity mat2d
536b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
537b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} a new 2x3 matrix
538b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
539b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.create = function() {
540b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(6);
541b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1;
542b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
543b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
544b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 1;
545b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
546b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 0;
547b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
548b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
549b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
550b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
551b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new mat2d initialized with values from an existing matrix
552b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
553b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} a matrix to clone
554b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} a new 2x3 matrix
555b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
556b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.clone = function(a) {
557b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(6);
558b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
559b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
560b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
561b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
562b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a[4];
563b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a[5];
564b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
565b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
566b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
567b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
568b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Copy the values from one mat2d to another
569b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
570b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} out the receiving matrix
571b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} a the source matrix
572b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} out
573b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
574b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.copy = function(out, a) {
575b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
576b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
577b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
578b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
579b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a[4];
580b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a[5];
581b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
582b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
583b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
584b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
585b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Set a mat2d to the identity matrix
586b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
587b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} out the receiving matrix
588b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} out
589b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
590b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.identity = function(out) {
591b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1;
592b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
593b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
594b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 1;
595b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
596b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 0;
597b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
598b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
599b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
600b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
601b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Inverts a mat2d
602b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
603b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} out the receiving matrix
604b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} a the source matrix
605b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} out
606b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
607b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.invert = function(out, a) {
608b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var aa = a[0], ab = a[1], ac = a[2], ad = a[3],
609b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        atx = a[4], aty = a[5];
610b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
611b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var det = aa * ad - ab * ac;
612b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if(!det){
613b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return null;
614b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
615b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    det = 1.0 / det;
616b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
617b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = ad * det;
618b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = -ab * det;
619b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = -ac * det;
620b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = aa * det;
621b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = (ac * aty - ad * atx) * det;
622b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = (ab * atx - aa * aty) * det;
623b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
624b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
625b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
626b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
627b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the determinant of a mat2d
628b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
629b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} a the source matrix
630b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} determinant of a
631b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
632b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.determinant = function (a) {
633b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return a[0] * a[3] - a[1] * a[2];
634b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
635b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
636b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
637b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Multiplies two mat2d's
638b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
639b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} out the receiving matrix
640b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} a the first operand
641b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} b the second operand
642b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} out
643b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
644b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.multiply = function (out, a, b) {
645b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
646b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3], b4 = b[4], b5 = b[5];
647b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a0 * b0 + a2 * b1;
648b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a1 * b0 + a3 * b1;
649b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a0 * b2 + a2 * b3;
650b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a1 * b2 + a3 * b3;
651b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a0 * b4 + a2 * b5 + a4;
652b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a1 * b4 + a3 * b5 + a5;
653b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
654b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
655b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
656b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
657b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link mat2d.multiply}
658b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
659b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
660b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.mul = mat2d.multiply;
661b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
662b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
663b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotates a mat2d by the given angle
664b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
665b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} out the receiving matrix
666b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} a the matrix to rotate
667b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
668b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} out
669b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
670b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.rotate = function (out, a, rad) {
671b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
672b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        s = Math.sin(rad),
673b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        c = Math.cos(rad);
674b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a0 *  c + a2 * s;
675b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a1 *  c + a3 * s;
676b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a0 * -s + a2 * c;
677b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a1 * -s + a3 * c;
678b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a4;
679b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a5;
680b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
681b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
682b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
683b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
684b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Scales the mat2d by the dimensions in the given vec2
685b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
686b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} out the receiving matrix
687b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} a the matrix to translate
688b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} v the vec2 to scale the matrix by
689b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} out
690b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 **/
691b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.scale = function(out, a, v) {
692b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
693b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        v0 = v[0], v1 = v[1];
694b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a0 * v0;
695b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a1 * v0;
696b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a2 * v1;
697b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a3 * v1;
698b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a4;
699b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a5;
700b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
701b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
702b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
703b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
704b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Translates the mat2d by the dimensions in the given vec2
705b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
706b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} out the receiving matrix
707b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} a the matrix to translate
708b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} v the vec2 to translate the matrix by
709b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} out
710b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 **/
711b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.translate = function(out, a, v) {
712b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3], a4 = a[4], a5 = a[5],
713b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        v0 = v[0], v1 = v[1];
714b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a0;
715b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a1;
716b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a2;
717b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a3;
718b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a0 * v0 + a2 * v1 + a4;
719b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a1 * v0 + a3 * v1 + a5;
720b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
721b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
722b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
723b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
724b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a given angle
725b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
726b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
727b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat2d.identity(dest);
728b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat2d.rotate(dest, dest, rad);
729b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
730b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} out mat2d receiving operation result
731b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
732b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} out
733b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
734b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.fromRotation = function(out, rad) {
735b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var s = Math.sin(rad), c = Math.cos(rad);
736b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = c;
737b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = s;
738b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = -s;
739b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = c;
740b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
741b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 0;
742b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
743b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
744b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
745b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
746b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a vector scaling
747b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
748b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
749b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat2d.identity(dest);
750b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat2d.scale(dest, dest, vec);
751b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
752b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} out mat2d receiving operation result
753b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} v Scaling vector
754b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} out
755b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
756b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.fromScaling = function(out, v) {
757b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = v[0];
758b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
759b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
760b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = v[1];
761b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
762b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 0;
763b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
764b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
765b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
766b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
767b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a vector translation
768b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
769b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
770b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat2d.identity(dest);
771b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat2d.translate(dest, dest, vec);
772b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
773b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} out mat2d receiving operation result
774b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} v Translation vector
775b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat2d} out
776b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
777b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.fromTranslation = function(out, v) {
778b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1;
779b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
780b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
781b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 1;
782b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = v[0];
783b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = v[1];
784b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
785b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
786b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
787b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
788b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns a string representation of a mat2d
789b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
790b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} a matrix to represent as a string
791b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {String} string representation of the matrix
792b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
793b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.str = function (a) {
794b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' +
795b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	                    a[3] + ', ' + a[4] + ', ' + a[5] + ')';
796b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
797b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
798b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
799b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns Frobenius norm of a mat2d
800b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
801b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} a the matrix to calculate Frobenius norm of
802b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} Frobenius norm
803b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
804b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat2d.frob = function (a) {
805b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + 1))
806b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
807b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
808b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	module.exports = mat2d;
809b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
810b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
811b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ },
812b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/* 4 */
813b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ function(module, exports, __webpack_require__) {
814b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
815b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
816b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
817b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	Permission is hereby granted, free of charge, to any person obtaining a copy
818b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	of this software and associated documentation files (the "Software"), to deal
819b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	in the Software without restriction, including without limitation the rights
820b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
821b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	copies of the Software, and to permit persons to whom the Software is
822b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	furnished to do so, subject to the following conditions:
823b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
824b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	The above copyright notice and this permission notice shall be included in
825b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	all copies or substantial portions of the Software.
826b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
827b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
828b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
829b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
830b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
831b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
832b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
833b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE. */
834b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
835b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var glMatrix = __webpack_require__(1);
836b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
837b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
838b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @class 3x3 Matrix
839b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @name mat3
840b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
841b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var mat3 = {};
842b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
843b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
844b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new identity mat3
845b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
846b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} a new 3x3 matrix
847b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
848b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.create = function() {
849b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(9);
850b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1;
851b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
852b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
853b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
854b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 1;
855b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 0;
856b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
857b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
858b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 1;
859b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
860b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
861b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
862b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
863b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Copies the upper-left 3x3 values into the given mat3.
864b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
865b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out the receiving 3x3 matrix
866b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a   the source 4x4 matrix
867b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
868b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
869b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.fromMat4 = function(out, a) {
870b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
871b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
872b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
873b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[4];
874b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a[5];
875b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a[6];
876b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a[8];
877b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a[9];
878b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = a[10];
879b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
880b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
881b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
882b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
883b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new mat3 initialized with values from an existing matrix
884b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
885b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} a matrix to clone
886b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} a new 3x3 matrix
887b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
888b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.clone = function(a) {
889b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(9);
890b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
891b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
892b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
893b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
894b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a[4];
895b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a[5];
896b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a[6];
897b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a[7];
898b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = a[8];
899b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
900b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
901b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
902b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
903b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Copy the values from one mat3 to another
904b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
905b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out the receiving matrix
906b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} a the source matrix
907b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
908b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
909b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.copy = function(out, a) {
910b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
911b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
912b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
913b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
914b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a[4];
915b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a[5];
916b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a[6];
917b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a[7];
918b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = a[8];
919b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
920b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
921b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
922b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
923b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Set a mat3 to the identity matrix
924b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
925b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out the receiving matrix
926b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
927b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
928b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.identity = function(out) {
929b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1;
930b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
931b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
932b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
933b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 1;
934b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 0;
935b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
936b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
937b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 1;
938b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
939b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
940b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
941b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
942b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transpose the values of a mat3
943b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
944b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out the receiving matrix
945b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} a the source matrix
946b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
947b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
948b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.transpose = function(out, a) {
949b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // If we are transposing ourselves we can skip a few steps but have to cache some values
950b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (out === a) {
951b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        var a01 = a[1], a02 = a[2], a12 = a[5];
952b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[1] = a[3];
953b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[2] = a[6];
954b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[3] = a01;
955b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[5] = a[7];
956b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[6] = a02;
957b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[7] = a12;
958b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    } else {
959b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[0] = a[0];
960b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[1] = a[3];
961b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[2] = a[6];
962b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[3] = a[1];
963b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[4] = a[4];
964b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[5] = a[7];
965b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[6] = a[2];
966b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[7] = a[5];
967b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[8] = a[8];
968b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
969b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
970b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
971b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
972b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
973b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
974b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Inverts a mat3
975b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
976b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out the receiving matrix
977b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} a the source matrix
978b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
979b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
980b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.invert = function(out, a) {
981b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a00 = a[0], a01 = a[1], a02 = a[2],
982b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[3], a11 = a[4], a12 = a[5],
983b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[6], a21 = a[7], a22 = a[8],
984b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
985b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b01 = a22 * a11 - a12 * a21,
986b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b11 = -a22 * a10 + a12 * a20,
987b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b21 = a21 * a10 - a11 * a20,
988b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
989b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        // Calculate the determinant
990b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        det = a00 * b01 + a01 * b11 + a02 * b21;
991b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
992b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (!det) {
993b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return null;
994b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
995b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    det = 1.0 / det;
996b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
997b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = b01 * det;
998b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = (-a22 * a01 + a02 * a21) * det;
999b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = (a12 * a01 - a02 * a11) * det;
1000b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = b11 * det;
1001b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = (a22 * a00 - a02 * a20) * det;
1002b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = (-a12 * a00 + a02 * a10) * det;
1003b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = b21 * det;
1004b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = (-a21 * a00 + a01 * a20) * det;
1005b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = (a11 * a00 - a01 * a10) * det;
1006b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1007b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1008b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1009b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1010b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the adjugate of a mat3
1011b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1012b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out the receiving matrix
1013b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} a the source matrix
1014b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
1015b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1016b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.adjoint = function(out, a) {
1017b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a00 = a[0], a01 = a[1], a02 = a[2],
1018b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[3], a11 = a[4], a12 = a[5],
1019b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[6], a21 = a[7], a22 = a[8];
1020b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1021b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = (a11 * a22 - a12 * a21);
1022b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = (a02 * a21 - a01 * a22);
1023b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = (a01 * a12 - a02 * a11);
1024b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = (a12 * a20 - a10 * a22);
1025b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = (a00 * a22 - a02 * a20);
1026b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = (a02 * a10 - a00 * a12);
1027b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = (a10 * a21 - a11 * a20);
1028b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = (a01 * a20 - a00 * a21);
1029b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = (a00 * a11 - a01 * a10);
1030b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1031b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1032b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1033b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1034b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the determinant of a mat3
1035b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1036b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} a the source matrix
1037b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} determinant of a
1038b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1039b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.determinant = function (a) {
1040b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a00 = a[0], a01 = a[1], a02 = a[2],
1041b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[3], a11 = a[4], a12 = a[5],
1042b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[6], a21 = a[7], a22 = a[8];
1043b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1044b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
1045b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1046b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1047b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1048b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Multiplies two mat3's
1049b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1050b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out the receiving matrix
1051b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} a the first operand
1052b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} b the second operand
1053b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
1054b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1055b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.multiply = function (out, a, b) {
1056b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a00 = a[0], a01 = a[1], a02 = a[2],
1057b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[3], a11 = a[4], a12 = a[5],
1058b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[6], a21 = a[7], a22 = a[8],
1059b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1060b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b00 = b[0], b01 = b[1], b02 = b[2],
1061b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b10 = b[3], b11 = b[4], b12 = b[5],
1062b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b20 = b[6], b21 = b[7], b22 = b[8];
1063b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1064b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = b00 * a00 + b01 * a10 + b02 * a20;
1065b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = b00 * a01 + b01 * a11 + b02 * a21;
1066b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = b00 * a02 + b01 * a12 + b02 * a22;
1067b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1068b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = b10 * a00 + b11 * a10 + b12 * a20;
1069b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = b10 * a01 + b11 * a11 + b12 * a21;
1070b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = b10 * a02 + b11 * a12 + b12 * a22;
1071b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1072b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = b20 * a00 + b21 * a10 + b22 * a20;
1073b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = b20 * a01 + b21 * a11 + b22 * a21;
1074b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = b20 * a02 + b21 * a12 + b22 * a22;
1075b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1076b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1077b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1078b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1079b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link mat3.multiply}
1080b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
1081b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1082b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.mul = mat3.multiply;
1083b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1084b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1085b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Translate a mat3 by the given vector
1086b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1087b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out the receiving matrix
1088b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} a the matrix to translate
1089b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} v vector to translate by
1090b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
1091b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1092b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.translate = function(out, a, v) {
1093b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a00 = a[0], a01 = a[1], a02 = a[2],
1094b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[3], a11 = a[4], a12 = a[5],
1095b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[6], a21 = a[7], a22 = a[8],
1096b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        x = v[0], y = v[1];
1097b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1098b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a00;
1099b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a01;
1100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a02;
1101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a10;
1103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a11;
1104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a12;
1105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = x * a00 + y * a10 + a20;
1107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = x * a01 + y * a11 + a21;
1108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = x * a02 + y * a12 + a22;
1109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotates a mat3 by the given angle
1114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out the receiving matrix
1116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} a the matrix to rotate
1117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
1118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
1119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.rotate = function (out, a, rad) {
1121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a00 = a[0], a01 = a[1], a02 = a[2],
1122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[3], a11 = a[4], a12 = a[5],
1123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[6], a21 = a[7], a22 = a[8],
1124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        s = Math.sin(rad),
1126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        c = Math.cos(rad);
1127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = c * a00 + s * a10;
1129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = c * a01 + s * a11;
1130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = c * a02 + s * a12;
1131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = c * a10 - s * a00;
1133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = c * a11 - s * a01;
1134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = c * a12 - s * a02;
1135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a20;
1137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a21;
1138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = a22;
1139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Scales the mat3 by the dimensions in the given vec2
1144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out the receiving matrix
1146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} a the matrix to rotate
1147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} v the vec2 to scale the matrix by
1148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
1149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 **/
1150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.scale = function(out, a, v) {
1151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = v[0], y = v[1];
1152b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1153b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = x * a[0];
1154b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = x * a[1];
1155b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = x * a[2];
1156b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1157b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = y * a[3];
1158b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = y * a[4];
1159b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = y * a[5];
1160b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1161b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a[6];
1162b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a[7];
1163b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = a[8];
1164b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1165b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1166b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1167b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1168b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a vector translation
1169b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
1170b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1171b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat3.identity(dest);
1172b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat3.translate(dest, dest, vec);
1173b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1174b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out mat3 receiving operation result
1175b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} v Translation vector
1176b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
1177b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1178b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.fromTranslation = function(out, v) {
1179b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1;
1180b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
1181b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
1182b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
1183b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 1;
1184b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 0;
1185b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = v[0];
1186b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = v[1];
1187b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 1;
1188b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1189b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
1190b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1191b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1192b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a given angle
1193b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
1194b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1195b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat3.identity(dest);
1196b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat3.rotate(dest, dest, rad);
1197b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1198b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out mat3 receiving operation result
1199b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
1200b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
1201b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1202b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.fromRotation = function(out, rad) {
1203b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var s = Math.sin(rad), c = Math.cos(rad);
1204b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1205b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = c;
1206b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = s;
1207b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
1208b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1209b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = -s;
1210b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = c;
1211b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 0;
1212b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1213b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
1214b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
1215b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 1;
1216b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1217b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
1218b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1219b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1220b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a vector scaling
1221b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
1222b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1223b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat3.identity(dest);
1224b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat3.scale(dest, dest, vec);
1225b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1226b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out mat3 receiving operation result
1227b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} v Scaling vector
1228b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
1229b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1230b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.fromScaling = function(out, v) {
1231b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = v[0];
1232b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
1233b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
1234b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1235b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
1236b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = v[1];
1237b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 0;
1238b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1239b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
1240b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
1241b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 1;
1242b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1243b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
1244b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1245b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1246b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Copies the values from a mat2d into a mat3
1247b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1248b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} out the receiving matrix
1249b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} a the matrix to copy
1250b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat3} out
1251b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 **/
1252b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.fromMat2d = function(out, a) {
1253b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
1254b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
1255b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
1256b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1257b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[2];
1258b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a[3];
1259b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 0;
1260b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1261b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a[4];
1262b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a[5];
1263b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 1;
1264b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1265b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1266b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1267b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1268b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	* Calculates a 3x3 matrix from the given quaternion
1269b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	*
1270b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	* @param {mat3} out mat3 receiving operation result
1271b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	* @param {quat} q Quaternion to create matrix from
1272b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	*
1273b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	* @returns {mat3} out
1274b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	*/
1275b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.fromQuat = function (out, q) {
1276b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = q[0], y = q[1], z = q[2], w = q[3],
1277b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        x2 = x + x,
1278b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y2 = y + y,
1279b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z2 = z + z,
1280b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1281b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        xx = x * x2,
1282b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        yx = y * x2,
1283b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        yy = y * y2,
1284b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        zx = z * x2,
1285b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        zy = z * y2,
1286b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        zz = z * z2,
1287b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wx = w * x2,
1288b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wy = w * y2,
1289b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wz = w * z2;
1290b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1291b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1 - yy - zz;
1292b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = yx - wz;
1293b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = zx + wy;
1294b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1295b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = yx + wz;
1296b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 1 - xx - zz;
1297b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = zy - wx;
1298b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1299b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = zx - wy;
1300b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = zy + wx;
1301b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 1 - xx - yy;
1302b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1303b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1304b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1305b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1306b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1307b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	* Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
1308b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	*
1309b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	* @param {mat3} out mat3 receiving operation result
1310b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	* @param {mat4} a Mat4 to derive the normal matrix from
1311b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	*
1312b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	* @returns {mat3} out
1313b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	*/
1314b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.normalFromMat4 = function (out, a) {
1315b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
1316b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
1317b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
1318b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
1319b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1320b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b00 = a00 * a11 - a01 * a10,
1321b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b01 = a00 * a12 - a02 * a10,
1322b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b02 = a00 * a13 - a03 * a10,
1323b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b03 = a01 * a12 - a02 * a11,
1324b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b04 = a01 * a13 - a03 * a11,
1325b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b05 = a02 * a13 - a03 * a12,
1326b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b06 = a20 * a31 - a21 * a30,
1327b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b07 = a20 * a32 - a22 * a30,
1328b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b08 = a20 * a33 - a23 * a30,
1329b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b09 = a21 * a32 - a22 * a31,
1330b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b10 = a21 * a33 - a23 * a31,
1331b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b11 = a22 * a33 - a23 * a32,
1332b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1333b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        // Calculate the determinant
1334b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
1335b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1336b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (!det) {
1337b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return null;
1338b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
1339b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    det = 1.0 / det;
1340b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1341b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
1342b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
1343b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
1344b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1345b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
1346b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
1347b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
1348b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1349b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
1350b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
1351b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
1352b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1353b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1354b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1355b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1356b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1357b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns a string representation of a mat3
1358b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1359b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} mat matrix to represent as a string
1360b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {String} string representation of the matrix
1361b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1362b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.str = function (a) {
1363b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' +
1364b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	                    a[3] + ', ' + a[4] + ', ' + a[5] + ', ' +
1365b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	                    a[6] + ', ' + a[7] + ', ' + a[8] + ')';
1366b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1367b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1368b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1369b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns Frobenius norm of a mat3
1370b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1371b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} a the matrix to calculate Frobenius norm of
1372b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} Frobenius norm
1373b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1374b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat3.frob = function (a) {
1375b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2)))
1376b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1377b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1378b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1379b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	module.exports = mat3;
1380b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1381b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1382b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ },
1383b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/* 5 */
1384b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ function(module, exports, __webpack_require__) {
1385b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1386b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
1387b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1388b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	Permission is hereby granted, free of charge, to any person obtaining a copy
1389b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	of this software and associated documentation files (the "Software"), to deal
1390b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	in the Software without restriction, including without limitation the rights
1391b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1392b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	copies of the Software, and to permit persons to whom the Software is
1393b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	furnished to do so, subject to the following conditions:
1394b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1395b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	The above copyright notice and this permission notice shall be included in
1396b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	all copies or substantial portions of the Software.
1397b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1398b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1399b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1400b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1401b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1402b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1403b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1404b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE. */
1405b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1406b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var glMatrix = __webpack_require__(1);
1407b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1408b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1409b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @class 4x4 Matrix
1410b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @name mat4
1411b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1412b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var mat4 = {};
1413b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1414b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1415b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new identity mat4
1416b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1417b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} a new 4x4 matrix
1418b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1419b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.create = function() {
1420b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(16);
1421b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1;
1422b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
1423b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
1424b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
1425b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
1426b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 1;
1427b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
1428b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
1429b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 0;
1430b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = 0;
1431b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = 1;
1432b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
1433b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = 0;
1434b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = 0;
1435b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = 0;
1436b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
1437b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1438b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1439b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1440b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1441b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new mat4 initialized with values from an existing matrix
1442b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1443b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a matrix to clone
1444b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} a new 4x4 matrix
1445b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1446b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.clone = function(a) {
1447b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(16);
1448b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
1449b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
1450b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
1451b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
1452b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a[4];
1453b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a[5];
1454b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a[6];
1455b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a[7];
1456b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = a[8];
1457b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = a[9];
1458b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = a[10];
1459b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = a[11];
1460b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = a[12];
1461b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = a[13];
1462b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = a[14];
1463b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = a[15];
1464b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1465b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1466b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1467b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1468b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Copy the values from one mat4 to another
1469b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1470b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1471b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the source matrix
1472b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1473b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1474b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.copy = function(out, a) {
1475b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
1476b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
1477b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
1478b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
1479b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a[4];
1480b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a[5];
1481b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a[6];
1482b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a[7];
1483b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = a[8];
1484b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = a[9];
1485b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = a[10];
1486b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = a[11];
1487b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = a[12];
1488b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = a[13];
1489b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = a[14];
1490b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = a[15];
1491b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1492b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1493b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1494b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1495b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Set a mat4 to the identity matrix
1496b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1497b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1498b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1499b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1500b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.identity = function(out) {
1501b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1;
1502b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
1503b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
1504b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
1505b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
1506b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 1;
1507b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
1508b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
1509b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 0;
1510b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = 0;
1511b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = 1;
1512b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
1513b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = 0;
1514b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = 0;
1515b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = 0;
1516b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
1517b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1518b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1519b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1520b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1521b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transpose the values of a mat4
1522b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1523b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1524b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the source matrix
1525b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1526b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1527b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.transpose = function(out, a) {
1528b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // If we are transposing ourselves we can skip a few steps but have to cache some values
1529b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (out === a) {
1530b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        var a01 = a[1], a02 = a[2], a03 = a[3],
1531b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            a12 = a[6], a13 = a[7],
1532b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            a23 = a[11];
1533b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1534b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[1] = a[4];
1535b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[2] = a[8];
1536b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[3] = a[12];
1537b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[4] = a01;
1538b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[6] = a[9];
1539b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[7] = a[13];
1540b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[8] = a02;
1541b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[9] = a12;
1542b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[11] = a[14];
1543b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[12] = a03;
1544b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[13] = a13;
1545b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[14] = a23;
1546b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    } else {
1547b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[0] = a[0];
1548b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[1] = a[4];
1549b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[2] = a[8];
1550b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[3] = a[12];
1551b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[4] = a[1];
1552b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[5] = a[5];
1553b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[6] = a[9];
1554b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[7] = a[13];
1555b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[8] = a[2];
1556b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[9] = a[6];
1557b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[10] = a[10];
1558b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[11] = a[14];
1559b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[12] = a[3];
1560b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[13] = a[7];
1561b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[14] = a[11];
1562b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[15] = a[15];
1563b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
1564b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1565b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1566b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1567b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1568b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1569b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Inverts a mat4
1570b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1571b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1572b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the source matrix
1573b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1574b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1575b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.invert = function(out, a) {
1576b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
1577b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
1578b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
1579b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
1580b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1581b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b00 = a00 * a11 - a01 * a10,
1582b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b01 = a00 * a12 - a02 * a10,
1583b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b02 = a00 * a13 - a03 * a10,
1584b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b03 = a01 * a12 - a02 * a11,
1585b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b04 = a01 * a13 - a03 * a11,
1586b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b05 = a02 * a13 - a03 * a12,
1587b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b06 = a20 * a31 - a21 * a30,
1588b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b07 = a20 * a32 - a22 * a30,
1589b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b08 = a20 * a33 - a23 * a30,
1590b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b09 = a21 * a32 - a22 * a31,
1591b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b10 = a21 * a33 - a23 * a31,
1592b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b11 = a22 * a33 - a23 * a32,
1593b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1594b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        // Calculate the determinant
1595b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
1596b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1597b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (!det) {
1598b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return null;
1599b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
1600b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    det = 1.0 / det;
1601b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1602b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
1603b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
1604b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
1605b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
1606b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
1607b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
1608b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
1609b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
1610b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
1611b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
1612b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
1613b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
1614b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
1615b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
1616b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
1617b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
1618b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1619b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1620b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1621b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1622b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1623b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the adjugate of a mat4
1624b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1625b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1626b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the source matrix
1627b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1628b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1629b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.adjoint = function(out, a) {
1630b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
1631b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
1632b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
1633b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
1634b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1635b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0]  =  (a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22));
1636b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1]  = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
1637b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2]  =  (a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12));
1638b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3]  = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
1639b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4]  = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
1640b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5]  =  (a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22));
1641b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6]  = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
1642b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7]  =  (a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12));
1643b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8]  =  (a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21));
1644b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9]  = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
1645b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] =  (a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11));
1646b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
1647b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
1648b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] =  (a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21));
1649b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
1650b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] =  (a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11));
1651b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1652b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1653b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1654b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1655b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the determinant of a mat4
1656b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1657b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the source matrix
1658b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} determinant of a
1659b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1660b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.determinant = function (a) {
1661b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
1662b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
1663b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
1664b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
1665b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1666b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b00 = a00 * a11 - a01 * a10,
1667b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b01 = a00 * a12 - a02 * a10,
1668b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b02 = a00 * a13 - a03 * a10,
1669b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b03 = a01 * a12 - a02 * a11,
1670b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b04 = a01 * a13 - a03 * a11,
1671b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b05 = a02 * a13 - a03 * a12,
1672b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b06 = a20 * a31 - a21 * a30,
1673b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b07 = a20 * a32 - a22 * a30,
1674b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b08 = a20 * a33 - a23 * a30,
1675b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b09 = a21 * a32 - a22 * a31,
1676b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b10 = a21 * a33 - a23 * a31,
1677b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b11 = a22 * a33 - a23 * a32;
1678b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1679b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Calculate the determinant
1680b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
1681b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1682b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1683b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1684b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Multiplies two mat4's
1685b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1686b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1687b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the first operand
1688b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} b the second operand
1689b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1690b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1691b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.multiply = function (out, a, b) {
1692b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
1693b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
1694b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
1695b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
1696b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1697b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Cache only the current line of the second matrix
1698b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var b0  = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
1699b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
1700b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
1701b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
1702b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
1703b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1704b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];
1705b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
1706b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
1707b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
1708b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
1709b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1710b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];
1711b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
1712b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
1713b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
1714b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
1715b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1716b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];
1717b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
1718b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
1719b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
1720b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
1721b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1722b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1723b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1724b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1725b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link mat4.multiply}
1726b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
1727b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1728b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.mul = mat4.multiply;
1729b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1730b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1731b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Translate a mat4 by the given vector
1732b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1733b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1734b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the matrix to translate
1735b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} v vector to translate by
1736b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1737b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1738b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.translate = function (out, a, v) {
1739b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = v[0], y = v[1], z = v[2],
1740b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a00, a01, a02, a03,
1741b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10, a11, a12, a13,
1742b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20, a21, a22, a23;
1743b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1744b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (a === out) {
1745b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
1746b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
1747b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
1748b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
1749b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    } else {
1750b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
1751b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
1752b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
1753b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1754b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;
1755b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;
1756b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;
1757b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1758b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[12] = a00 * x + a10 * y + a20 * z + a[12];
1759b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[13] = a01 * x + a11 * y + a21 * z + a[13];
1760b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[14] = a02 * x + a12 * y + a22 * z + a[14];
1761b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[15] = a03 * x + a13 * y + a23 * z + a[15];
1762b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
1763b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1764b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1765b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1766b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1767b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1768b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Scales the mat4 by the dimensions in the given vec3
1769b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1770b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1771b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the matrix to scale
1772b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} v the vec3 to scale the matrix by
1773b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1774b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 **/
1775b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.scale = function(out, a, v) {
1776b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = v[0], y = v[1], z = v[2];
1777b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1778b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] * x;
1779b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] * x;
1780b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] * x;
1781b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3] * x;
1782b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a[4] * y;
1783b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a[5] * y;
1784b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a[6] * y;
1785b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a[7] * y;
1786b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = a[8] * z;
1787b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = a[9] * z;
1788b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = a[10] * z;
1789b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = a[11] * z;
1790b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = a[12];
1791b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = a[13];
1792b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = a[14];
1793b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = a[15];
1794b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1795b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1796b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1797b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1798b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotates a mat4 by the given angle around the given axis
1799b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1800b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1801b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the matrix to rotate
1802b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
1803b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} axis the axis to rotate around
1804b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1805b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1806b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.rotate = function (out, a, rad, axis) {
1807b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = axis[0], y = axis[1], z = axis[2],
1808b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        len = Math.sqrt(x * x + y * y + z * z),
1809b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        s, c, t,
1810b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a00, a01, a02, a03,
1811b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10, a11, a12, a13,
1812b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20, a21, a22, a23,
1813b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b00, b01, b02,
1814b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b10, b11, b12,
1815b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        b20, b21, b22;
1816b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1817b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (Math.abs(len) < glMatrix.EPSILON) { return null; }
1818b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1819b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    len = 1 / len;
1820b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    x *= len;
1821b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    y *= len;
1822b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    z *= len;
1823b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1824b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    s = Math.sin(rad);
1825b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    c = Math.cos(rad);
1826b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    t = 1 - c;
1827b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1828b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
1829b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
1830b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
1831b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1832b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Construct the elements of the rotation matrix
1833b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;
1834b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;
1835b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;
1836b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1837b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Perform rotation-specific matrix multiplication
1838b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a00 * b00 + a10 * b01 + a20 * b02;
1839b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a01 * b00 + a11 * b01 + a21 * b02;
1840b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a02 * b00 + a12 * b01 + a22 * b02;
1841b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a03 * b00 + a13 * b01 + a23 * b02;
1842b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a00 * b10 + a10 * b11 + a20 * b12;
1843b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a01 * b10 + a11 * b11 + a21 * b12;
1844b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a02 * b10 + a12 * b11 + a22 * b12;
1845b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a03 * b10 + a13 * b11 + a23 * b12;
1846b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = a00 * b20 + a10 * b21 + a20 * b22;
1847b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = a01 * b20 + a11 * b21 + a21 * b22;
1848b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = a02 * b20 + a12 * b21 + a22 * b22;
1849b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = a03 * b20 + a13 * b21 + a23 * b22;
1850b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1851b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (a !== out) { // If the source and destination differ, copy the unchanged last row
1852b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[12] = a[12];
1853b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[13] = a[13];
1854b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[14] = a[14];
1855b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[15] = a[15];
1856b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
1857b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1858b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1859b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1860b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1861b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotates a matrix by the given angle around the X axis
1862b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1863b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1864b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the matrix to rotate
1865b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
1866b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1867b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1868b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.rotateX = function (out, a, rad) {
1869b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var s = Math.sin(rad),
1870b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        c = Math.cos(rad),
1871b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[4],
1872b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a11 = a[5],
1873b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a12 = a[6],
1874b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a13 = a[7],
1875b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[8],
1876b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a21 = a[9],
1877b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a22 = a[10],
1878b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a23 = a[11];
1879b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1880b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (a !== out) { // If the source and destination differ, copy the unchanged rows
1881b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[0]  = a[0];
1882b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[1]  = a[1];
1883b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[2]  = a[2];
1884b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[3]  = a[3];
1885b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[12] = a[12];
1886b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[13] = a[13];
1887b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[14] = a[14];
1888b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[15] = a[15];
1889b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
1890b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1891b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Perform axis-specific matrix multiplication
1892b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a10 * c + a20 * s;
1893b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a11 * c + a21 * s;
1894b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a12 * c + a22 * s;
1895b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a13 * c + a23 * s;
1896b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = a20 * c - a10 * s;
1897b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = a21 * c - a11 * s;
1898b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = a22 * c - a12 * s;
1899b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = a23 * c - a13 * s;
1900b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1901b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1902b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1903b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1904b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotates a matrix by the given angle around the Y axis
1905b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1906b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1907b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the matrix to rotate
1908b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
1909b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1910b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1911b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.rotateY = function (out, a, rad) {
1912b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var s = Math.sin(rad),
1913b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        c = Math.cos(rad),
1914b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a00 = a[0],
1915b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a01 = a[1],
1916b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a02 = a[2],
1917b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a03 = a[3],
1918b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a20 = a[8],
1919b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a21 = a[9],
1920b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a22 = a[10],
1921b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a23 = a[11];
1922b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1923b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (a !== out) { // If the source and destination differ, copy the unchanged rows
1924b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[4]  = a[4];
1925b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[5]  = a[5];
1926b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[6]  = a[6];
1927b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[7]  = a[7];
1928b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[12] = a[12];
1929b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[13] = a[13];
1930b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[14] = a[14];
1931b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[15] = a[15];
1932b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
1933b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1934b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Perform axis-specific matrix multiplication
1935b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a00 * c - a20 * s;
1936b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a01 * c - a21 * s;
1937b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a02 * c - a22 * s;
1938b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a03 * c - a23 * s;
1939b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = a00 * s + a20 * c;
1940b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = a01 * s + a21 * c;
1941b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = a02 * s + a22 * c;
1942b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = a03 * s + a23 * c;
1943b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1944b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1945b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1946b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1947b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotates a matrix by the given angle around the Z axis
1948b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1949b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out the receiving matrix
1950b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the matrix to rotate
1951b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
1952b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1953b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
1954b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.rotateZ = function (out, a, rad) {
1955b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var s = Math.sin(rad),
1956b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        c = Math.cos(rad),
1957b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a00 = a[0],
1958b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a01 = a[1],
1959b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a02 = a[2],
1960b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a03 = a[3],
1961b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a10 = a[4],
1962b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a11 = a[5],
1963b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a12 = a[6],
1964b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        a13 = a[7];
1965b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1966b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (a !== out) { // If the source and destination differ, copy the unchanged last row
1967b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[8]  = a[8];
1968b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[9]  = a[9];
1969b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[10] = a[10];
1970b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[11] = a[11];
1971b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[12] = a[12];
1972b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[13] = a[13];
1973b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[14] = a[14];
1974b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[15] = a[15];
1975b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
1976b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1977b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Perform axis-specific matrix multiplication
1978b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a00 * c + a10 * s;
1979b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a01 * c + a11 * s;
1980b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a02 * c + a12 * s;
1981b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a03 * c + a13 * s;
1982b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = a10 * c - a00 * s;
1983b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = a11 * c - a01 * s;
1984b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = a12 * c - a02 * s;
1985b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = a13 * c - a03 * s;
1986b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
1987b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
1988b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
1989b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
1990b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a vector translation
1991b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
1992b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1993b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.identity(dest);
1994b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.translate(dest, dest, vec);
1995b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
1996b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 receiving operation result
1997b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} v Translation vector
1998b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
1999b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2000b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.fromTranslation = function(out, v) {
2001b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1;
2002b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
2003b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
2004b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
2005b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
2006b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 1;
2007b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
2008b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2009b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 0;
2010b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = 0;
2011b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = 1;
2012b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
2013b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = v[0];
2014b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = v[1];
2015b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = v[2];
2016b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
2017b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2018b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
2019b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2020b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2021b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a vector scaling
2022b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
2023b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2024b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.identity(dest);
2025b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.scale(dest, dest, vec);
2026b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2027b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 receiving operation result
2028b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} v Scaling vector
2029b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2030b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2031b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.fromScaling = function(out, v) {
2032b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = v[0];
2033b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
2034b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
2035b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
2036b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
2037b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = v[1];
2038b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
2039b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2040b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 0;
2041b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = 0;
2042b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = v[2];
2043b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
2044b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = 0;
2045b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = 0;
2046b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = 0;
2047b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
2048b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2049b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
2050b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2051b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2052b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a given angle around a given axis
2053b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
2054b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2055b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.identity(dest);
2056b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.rotate(dest, dest, rad, axis);
2057b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2058b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 receiving operation result
2059b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
2060b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} axis the axis to rotate around
2061b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2062b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2063b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.fromRotation = function(out, rad, axis) {
2064b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = axis[0], y = axis[1], z = axis[2],
2065b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        len = Math.sqrt(x * x + y * y + z * z),
2066b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        s, c, t;
2067b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2068b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (Math.abs(len) < glMatrix.EPSILON) { return null; }
2069b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2070b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    len = 1 / len;
2071b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    x *= len;
2072b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    y *= len;
2073b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    z *= len;
2074b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2075b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    s = Math.sin(rad);
2076b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    c = Math.cos(rad);
2077b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    t = 1 - c;
2078b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2079b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Perform rotation-specific matrix multiplication
2080b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = x * x * t + c;
2081b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = y * x * t + z * s;
2082b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = z * x * t - y * s;
2083b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
2084b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = x * y * t - z * s;
2085b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = y * y * t + c;
2086b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = z * y * t + x * s;
2087b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2088b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = x * z * t + y * s;
2089b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = y * z * t - x * s;
2090b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = z * z * t + c;
2091b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
2092b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = 0;
2093b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = 0;
2094b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = 0;
2095b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
2096b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2097b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
2098b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2099b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from the given angle around the X axis
2101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
2102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.identity(dest);
2104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.rotateX(dest, dest, rad);
2105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 receiving operation result
2107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
2108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.fromXRotation = function(out, rad) {
2111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var s = Math.sin(rad),
2112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        c = Math.cos(rad);
2113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Perform axis-specific matrix multiplication
2115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0]  = 1;
2116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1]  = 0;
2117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2]  = 0;
2118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3]  = 0;
2119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
2120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = c;
2121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = s;
2122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 0;
2124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = -s;
2125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = c;
2126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
2127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = 0;
2128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = 0;
2129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = 0;
2130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
2131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
2133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from the given angle around the Y axis
2136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
2137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.identity(dest);
2139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.rotateY(dest, dest, rad);
2140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 receiving operation result
2142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
2143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.fromYRotation = function(out, rad) {
2146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var s = Math.sin(rad),
2147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        c = Math.cos(rad);
2148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Perform axis-specific matrix multiplication
2150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0]  = c;
2151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1]  = 0;
2152b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2]  = -s;
2153b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3]  = 0;
2154b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
2155b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 1;
2156b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
2157b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2158b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = s;
2159b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = 0;
2160b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = c;
2161b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
2162b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = 0;
2163b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = 0;
2164b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = 0;
2165b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
2166b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2167b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
2168b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2169b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2170b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from the given angle around the Z axis
2171b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
2172b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2173b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.identity(dest);
2174b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.rotateZ(dest, dest, rad);
2175b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2176b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 receiving operation result
2177b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle to rotate the matrix by
2178b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2179b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2180b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.fromZRotation = function(out, rad) {
2181b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var s = Math.sin(rad),
2182b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        c = Math.cos(rad);
2183b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2184b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Perform axis-specific matrix multiplication
2185b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0]  = c;
2186b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1]  = s;
2187b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2]  = 0;
2188b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3]  = 0;
2189b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = -s;
2190b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = c;
2191b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
2192b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2193b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 0;
2194b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = 0;
2195b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = 1;
2196b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
2197b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = 0;
2198b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = 0;
2199b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = 0;
2200b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
2201b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2202b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
2203b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2204b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2205b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a quaternion rotation and vector translation
2206b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
2207b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2208b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.identity(dest);
2209b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.translate(dest, vec);
2210b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     var quatMat = mat4.create();
2211b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     quat4.toMat4(quat, quatMat);
2212b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.multiply(dest, quatMat);
2213b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2214b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 receiving operation result
2215b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat4} q Rotation quaternion
2216b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} v Translation vector
2217b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2218b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2219b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.fromRotationTranslation = function (out, q, v) {
2220b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Quaternion math
2221b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = q[0], y = q[1], z = q[2], w = q[3],
2222b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        x2 = x + x,
2223b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y2 = y + y,
2224b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z2 = z + z,
2225b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2226b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        xx = x * x2,
2227b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        xy = x * y2,
2228b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        xz = x * z2,
2229b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        yy = y * y2,
2230b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        yz = y * z2,
2231b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        zz = z * z2,
2232b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wx = w * x2,
2233b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wy = w * y2,
2234b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wz = w * z2;
2235b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2236b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1 - (yy + zz);
2237b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = xy + wz;
2238b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = xz - wy;
2239b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
2240b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = xy - wz;
2241b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 1 - (xx + zz);
2242b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = yz + wx;
2243b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2244b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = xz + wy;
2245b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = yz - wx;
2246b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = 1 - (xx + yy);
2247b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
2248b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = v[0];
2249b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = v[1];
2250b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = v[2];
2251b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
2252b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2253b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2254b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2255b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2256b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2257b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a quaternion rotation, vector translation and vector scale
2258b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
2259b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2260b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.identity(dest);
2261b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.translate(dest, vec);
2262b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     var quatMat = mat4.create();
2263b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     quat4.toMat4(quat, quatMat);
2264b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.multiply(dest, quatMat);
2265b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.scale(dest, scale)
2266b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2267b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 receiving operation result
2268b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat4} q Rotation quaternion
2269b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} v Translation vector
2270b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} s Scaling vector
2271b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2272b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2273b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.fromRotationTranslationScale = function (out, q, v, s) {
2274b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Quaternion math
2275b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = q[0], y = q[1], z = q[2], w = q[3],
2276b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        x2 = x + x,
2277b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y2 = y + y,
2278b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z2 = z + z,
2279b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2280b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        xx = x * x2,
2281b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        xy = x * y2,
2282b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        xz = x * z2,
2283b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        yy = y * y2,
2284b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        yz = y * z2,
2285b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        zz = z * z2,
2286b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wx = w * x2,
2287b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wy = w * y2,
2288b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wz = w * z2,
2289b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        sx = s[0],
2290b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        sy = s[1],
2291b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        sz = s[2];
2292b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2293b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = (1 - (yy + zz)) * sx;
2294b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = (xy + wz) * sx;
2295b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = (xz - wy) * sx;
2296b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
2297b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = (xy - wz) * sy;
2298b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = (1 - (xx + zz)) * sy;
2299b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = (yz + wx) * sy;
2300b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2301b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = (xz + wy) * sz;
2302b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = (yz - wx) * sz;
2303b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = (1 - (xx + yy)) * sz;
2304b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
2305b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = v[0];
2306b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = v[1];
2307b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = v[2];
2308b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
2309b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2310b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2311b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2312b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2313b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2314b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin
2315b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is equivalent to (but much faster than):
2316b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2317b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.identity(dest);
2318b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.translate(dest, vec);
2319b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.translate(dest, origin);
2320b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     var quatMat = mat4.create();
2321b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     quat4.toMat4(quat, quatMat);
2322b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.multiply(dest, quatMat);
2323b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.scale(dest, scale)
2324b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *     mat4.translate(dest, negativeOrigin);
2325b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2326b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 receiving operation result
2327b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat4} q Rotation quaternion
2328b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} v Translation vector
2329b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} s Scaling vector
2330b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} o The origin vector around which to scale and rotate
2331b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2332b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2333b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.fromRotationTranslationScaleOrigin = function (out, q, v, s, o) {
2334b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  // Quaternion math
2335b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  var x = q[0], y = q[1], z = q[2], w = q[3],
2336b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      x2 = x + x,
2337b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      y2 = y + y,
2338b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      z2 = z + z,
2339b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2340b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      xx = x * x2,
2341b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      xy = x * y2,
2342b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      xz = x * z2,
2343b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      yy = y * y2,
2344b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      yz = y * z2,
2345b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      zz = z * z2,
2346b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      wx = w * x2,
2347b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      wy = w * y2,
2348b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      wz = w * z2,
2349b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2350b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      sx = s[0],
2351b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      sy = s[1],
2352b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      sz = s[2],
2353b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2354b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      ox = o[0],
2355b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      oy = o[1],
2356b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      oz = o[2];
2357b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2358b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[0] = (1 - (yy + zz)) * sx;
2359b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[1] = (xy + wz) * sx;
2360b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[2] = (xz - wy) * sx;
2361b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[3] = 0;
2362b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[4] = (xy - wz) * sy;
2363b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[5] = (1 - (xx + zz)) * sy;
2364b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[6] = (yz + wx) * sy;
2365b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[7] = 0;
2366b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[8] = (xz + wy) * sz;
2367b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[9] = (yz - wx) * sz;
2368b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[10] = (1 - (xx + yy)) * sz;
2369b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[11] = 0;
2370b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[12] = v[0] + ox - (out[0] * ox + out[4] * oy + out[8] * oz);
2371b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[13] = v[1] + oy - (out[1] * ox + out[5] * oy + out[9] * oz);
2372b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[14] = v[2] + oz - (out[2] * ox + out[6] * oy + out[10] * oz);
2373b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[15] = 1;
2374b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2375b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  return out;
2376b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2377b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2378b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.fromQuat = function (out, q) {
2379b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = q[0], y = q[1], z = q[2], w = q[3],
2380b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        x2 = x + x,
2381b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y2 = y + y,
2382b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z2 = z + z,
2383b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2384b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        xx = x * x2,
2385b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        yx = y * x2,
2386b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        yy = y * y2,
2387b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        zx = z * x2,
2388b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        zy = z * y2,
2389b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        zz = z * z2,
2390b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wx = w * x2,
2391b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wy = w * y2,
2392b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        wz = w * z2;
2393b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2394b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 1 - yy - zz;
2395b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = yx + wz;
2396b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = zx - wy;
2397b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
2398b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2399b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = yx - wz;
2400b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = 1 - xx - zz;
2401b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = zy + wx;
2402b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2403b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2404b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = zx + wy;
2405b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = zy - wx;
2406b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = 1 - xx - yy;
2407b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
2408b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2409b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = 0;
2410b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = 0;
2411b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = 0;
2412b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
2413b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2414b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2415b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2416b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2417b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2418b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Generates a frustum matrix with the given bounds
2419b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2420b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 frustum matrix will be written into
2421b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} left Left bound of the frustum
2422b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} right Right bound of the frustum
2423b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} bottom Bottom bound of the frustum
2424b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} top Top bound of the frustum
2425b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} near Near bound of the frustum
2426b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} far Far bound of the frustum
2427b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2428b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2429b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.frustum = function (out, left, right, bottom, top, near, far) {
2430b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var rl = 1 / (right - left),
2431b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        tb = 1 / (top - bottom),
2432b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        nf = 1 / (near - far);
2433b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = (near * 2) * rl;
2434b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
2435b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
2436b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
2437b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
2438b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = (near * 2) * tb;
2439b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
2440b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2441b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = (right + left) * rl;
2442b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = (top + bottom) * tb;
2443b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = (far + near) * nf;
2444b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = -1;
2445b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = 0;
2446b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = 0;
2447b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = (far * near * 2) * nf;
2448b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 0;
2449b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2450b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2451b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2452b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2453b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Generates a perspective projection matrix with the given bounds
2454b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2455b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 frustum matrix will be written into
2456b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} fovy Vertical field of view in radians
2457b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} aspect Aspect ratio. typically viewport width/height
2458b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} near Near bound of the frustum
2459b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} far Far bound of the frustum
2460b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2461b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2462b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.perspective = function (out, fovy, aspect, near, far) {
2463b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var f = 1.0 / Math.tan(fovy / 2),
2464b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        nf = 1 / (near - far);
2465b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = f / aspect;
2466b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
2467b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
2468b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
2469b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
2470b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = f;
2471b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
2472b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2473b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 0;
2474b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = 0;
2475b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = (far + near) * nf;
2476b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = -1;
2477b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = 0;
2478b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = 0;
2479b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = (2 * far * near) * nf;
2480b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 0;
2481b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2482b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2483b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2484b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2485b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Generates a perspective projection matrix with the given field of view.
2486b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * This is primarily useful for generating projection matrices to be used
2487b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * with the still experiemental WebVR API.
2488b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2489b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 frustum matrix will be written into
2490b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees
2491b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} near Near bound of the frustum
2492b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} far Far bound of the frustum
2493b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2494b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2495b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.perspectiveFromFieldOfView = function (out, fov, near, far) {
2496b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var upTan = Math.tan(fov.upDegrees * Math.PI/180.0),
2497b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        downTan = Math.tan(fov.downDegrees * Math.PI/180.0),
2498b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        leftTan = Math.tan(fov.leftDegrees * Math.PI/180.0),
2499b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        rightTan = Math.tan(fov.rightDegrees * Math.PI/180.0),
2500b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        xScale = 2.0 / (leftTan + rightTan),
2501b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        yScale = 2.0 / (upTan + downTan);
2502b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2503b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = xScale;
2504b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0.0;
2505b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0.0;
2506b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0.0;
2507b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0.0;
2508b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = yScale;
2509b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0.0;
2510b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0.0;
2511b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = -((leftTan - rightTan) * xScale * 0.5);
2512b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = ((upTan - downTan) * yScale * 0.5);
2513b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = far / (near - far);
2514b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = -1.0;
2515b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = 0.0;
2516b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = 0.0;
2517b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = (far * near) / (near - far);
2518b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 0.0;
2519b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2520b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}
2521b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2522b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2523b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Generates a orthogonal projection matrix with the given bounds
2524b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2525b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 frustum matrix will be written into
2526b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} left Left bound of the frustum
2527b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} right Right bound of the frustum
2528b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} bottom Bottom bound of the frustum
2529b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} top Top bound of the frustum
2530b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} near Near bound of the frustum
2531b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} far Far bound of the frustum
2532b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2533b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2534b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.ortho = function (out, left, right, bottom, top, near, far) {
2535b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var lr = 1 / (left - right),
2536b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        bt = 1 / (bottom - top),
2537b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        nf = 1 / (near - far);
2538b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = -2 * lr;
2539b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
2540b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
2541b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
2542b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = 0;
2543b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = -2 * bt;
2544b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = 0;
2545b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2546b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = 0;
2547b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = 0;
2548b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = 2 * nf;
2549b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
2550b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = (left + right) * lr;
2551b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = (top + bottom) * bt;
2552b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = (far + near) * nf;
2553b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
2554b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2555b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2556b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2557b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2558b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Generates a look-at matrix with the given eye position, focal point, and up axis
2559b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2560b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} out mat4 frustum matrix will be written into
2561b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} eye Position of the viewer
2562b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} center Point the viewer is looking at
2563b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} up vec3 pointing up
2564b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {mat4} out
2565b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2566b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.lookAt = function (out, eye, center, up) {
2567b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x0, x1, x2, y0, y1, y2, z0, z1, z2, len,
2568b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        eyex = eye[0],
2569b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        eyey = eye[1],
2570b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        eyez = eye[2],
2571b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        upx = up[0],
2572b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        upy = up[1],
2573b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        upz = up[2],
2574b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        centerx = center[0],
2575b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        centery = center[1],
2576b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        centerz = center[2];
2577b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2578b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (Math.abs(eyex - centerx) < glMatrix.EPSILON &&
2579b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        Math.abs(eyey - centery) < glMatrix.EPSILON &&
2580b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        Math.abs(eyez - centerz) < glMatrix.EPSILON) {
2581b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return mat4.identity(out);
2582b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
2583b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2584b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    z0 = eyex - centerx;
2585b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    z1 = eyey - centery;
2586b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    z2 = eyez - centerz;
2587b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2588b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
2589b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    z0 *= len;
2590b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    z1 *= len;
2591b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    z2 *= len;
2592b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2593b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    x0 = upy * z2 - upz * z1;
2594b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    x1 = upz * z0 - upx * z2;
2595b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    x2 = upx * z1 - upy * z0;
2596b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
2597b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (!len) {
2598b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        x0 = 0;
2599b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        x1 = 0;
2600b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        x2 = 0;
2601b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    } else {
2602b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        len = 1 / len;
2603b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        x0 *= len;
2604b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        x1 *= len;
2605b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        x2 *= len;
2606b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
2607b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2608b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    y0 = z1 * x2 - z2 * x1;
2609b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    y1 = z2 * x0 - z0 * x2;
2610b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    y2 = z0 * x1 - z1 * x0;
2611b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2612b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
2613b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (!len) {
2614b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y0 = 0;
2615b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y1 = 0;
2616b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y2 = 0;
2617b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    } else {
2618b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        len = 1 / len;
2619b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y0 *= len;
2620b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y1 *= len;
2621b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y2 *= len;
2622b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
2623b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2624b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = x0;
2625b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = y0;
2626b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = z0;
2627b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
2628b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[4] = x1;
2629b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[5] = y1;
2630b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[6] = z1;
2631b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[7] = 0;
2632b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[8] = x2;
2633b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[9] = y2;
2634b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[10] = z2;
2635b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[11] = 0;
2636b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
2637b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
2638b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
2639b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[15] = 1;
2640b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2641b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2642b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2643b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2644b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2645b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns a string representation of a mat4
2646b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2647b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} mat matrix to represent as a string
2648b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {String} string representation of the matrix
2649b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2650b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.str = function (a) {
2651b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' +
2652b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	                    a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' +
2653b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	                    a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' +
2654b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	                    a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')';
2655b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2656b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2657b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2658b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns Frobenius norm of a mat4
2659b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2660b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} a the matrix to calculate Frobenius norm of
2661b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} Frobenius norm
2662b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2663b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	mat4.frob = function (a) {
2664b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return(Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2) + Math.pow(a[9], 2) + Math.pow(a[10], 2) + Math.pow(a[11], 2) + Math.pow(a[12], 2) + Math.pow(a[13], 2) + Math.pow(a[14], 2) + Math.pow(a[15], 2) ))
2665b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2666b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2667b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2668b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	module.exports = mat4;
2669b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2670b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2671b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ },
2672b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/* 6 */
2673b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ function(module, exports, __webpack_require__) {
2674b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2675b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
2676b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2677b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	Permission is hereby granted, free of charge, to any person obtaining a copy
2678b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	of this software and associated documentation files (the "Software"), to deal
2679b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	in the Software without restriction, including without limitation the rights
2680b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2681b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	copies of the Software, and to permit persons to whom the Software is
2682b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	furnished to do so, subject to the following conditions:
2683b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2684b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	The above copyright notice and this permission notice shall be included in
2685b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	all copies or substantial portions of the Software.
2686b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2687b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2688b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2689b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2690b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2691b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2692b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2693b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE. */
2694b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2695b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var glMatrix = __webpack_require__(1);
2696b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var mat3 = __webpack_require__(4);
2697b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var vec3 = __webpack_require__(7);
2698b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var vec4 = __webpack_require__(8);
2699b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2700b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2701b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @class Quaternion
2702b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @name quat
2703b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2704b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var quat = {};
2705b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2706b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2707b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new identity quat
2708b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2709b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} a new quaternion
2710b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2711b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.create = function() {
2712b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(4);
2713b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 0;
2714b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
2715b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
2716b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 1;
2717b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2718b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2719b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2720b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2721b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Sets a quaternion to represent the shortest rotation from one
2722b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * vector to another.
2723b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2724b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Both vectors are assumed to be unit length.
2725b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2726b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion.
2727b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the initial vector
2728b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the destination vector
2729b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2730b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2731b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.rotationTo = (function() {
2732b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var tmpvec3 = vec3.create();
2733b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var xUnitVec3 = vec3.fromValues(1,0,0);
2734b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var yUnitVec3 = vec3.fromValues(0,1,0);
2735b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2736b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return function(out, a, b) {
2737b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        var dot = vec3.dot(a, b);
2738b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if (dot < -0.999999) {
2739b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            vec3.cross(tmpvec3, xUnitVec3, a);
2740b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            if (vec3.length(tmpvec3) < 0.000001)
2741b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	                vec3.cross(tmpvec3, yUnitVec3, a);
2742b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            vec3.normalize(tmpvec3, tmpvec3);
2743b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            quat.setAxisAngle(out, tmpvec3, Math.PI);
2744b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            return out;
2745b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        } else if (dot > 0.999999) {
2746b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            out[0] = 0;
2747b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            out[1] = 0;
2748b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            out[2] = 0;
2749b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            out[3] = 1;
2750b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            return out;
2751b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        } else {
2752b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            vec3.cross(tmpvec3, a, b);
2753b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            out[0] = tmpvec3[0];
2754b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            out[1] = tmpvec3[1];
2755b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            out[2] = tmpvec3[2];
2756b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            out[3] = 1 + dot;
2757b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            return quat.normalize(out, out);
2758b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
2759b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    };
2760b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	})();
2761b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2762b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2763b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Sets the specified quaternion with values corresponding to the given
2764b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * axes. Each axis is a vec3 and is expected to be unit length and
2765b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * perpendicular to all other specified axes.
2766b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2767b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} view  the vector representing the viewing direction
2768b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} right the vector representing the local "right" direction
2769b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} up    the vector representing the local "up" direction
2770b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2771b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2772b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.setAxes = (function() {
2773b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var matr = mat3.create();
2774b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2775b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return function(out, view, right, up) {
2776b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        matr[0] = right[0];
2777b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        matr[3] = right[1];
2778b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        matr[6] = right[2];
2779b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2780b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        matr[1] = up[0];
2781b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        matr[4] = up[1];
2782b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        matr[7] = up[2];
2783b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2784b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        matr[2] = -view[0];
2785b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        matr[5] = -view[1];
2786b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        matr[8] = -view[2];
2787b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2788b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return quat.normalize(out, quat.fromMat3(out, matr));
2789b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    };
2790b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	})();
2791b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2792b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2793b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new quat initialized with values from an existing quaternion
2794b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2795b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a quaternion to clone
2796b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} a new quaternion
2797b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
2798b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2799b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.clone = vec4.clone;
2800b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2801b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2802b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new quat initialized with the given values
2803b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2804b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} x X component
2805b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} y Y component
2806b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} z Z component
2807b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} w W component
2808b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} a new quaternion
2809b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
2810b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2811b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.fromValues = vec4.fromValues;
2812b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2813b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2814b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Copy the values from one quat to another
2815b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2816b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
2817b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a the source quaternion
2818b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2819b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
2820b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2821b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.copy = vec4.copy;
2822b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2823b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2824b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Set the components of a quat to the given values
2825b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2826b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
2827b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} x X component
2828b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} y Y component
2829b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} z Z component
2830b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} w W component
2831b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2832b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
2833b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2834b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.set = vec4.set;
2835b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2836b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2837b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Set a quat to the identity quaternion
2838b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2839b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
2840b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2841b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2842b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.identity = function(out) {
2843b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 0;
2844b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
2845b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
2846b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 1;
2847b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2848b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2849b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2850b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2851b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Sets a quat from the given angle and rotation axis,
2852b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * then returns it.
2853b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2854b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
2855b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} axis the axis around which to rotate
2856b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} rad the angle in radians
2857b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2858b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 **/
2859b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.setAxisAngle = function(out, axis, rad) {
2860b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    rad = rad * 0.5;
2861b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var s = Math.sin(rad);
2862b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = s * axis[0];
2863b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = s * axis[1];
2864b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = s * axis[2];
2865b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = Math.cos(rad);
2866b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2867b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2868b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2869b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2870b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Adds two quat's
2871b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2872b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
2873b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a the first operand
2874b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} b the second operand
2875b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2876b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
2877b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2878b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.add = vec4.add;
2879b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2880b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2881b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Multiplies two quat's
2882b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2883b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
2884b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a the first operand
2885b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} b the second operand
2886b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2887b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2888b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.multiply = function(out, a, b) {
2889b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
2890b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        bx = b[0], by = b[1], bz = b[2], bw = b[3];
2891b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2892b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = ax * bw + aw * bx + ay * bz - az * by;
2893b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = ay * bw + aw * by + az * bx - ax * bz;
2894b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = az * bw + aw * bz + ax * by - ay * bx;
2895b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = aw * bw - ax * bx - ay * by - az * bz;
2896b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2897b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2898b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2899b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2900b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link quat.multiply}
2901b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
2902b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2903b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.mul = quat.multiply;
2904b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2905b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2906b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Scales a quat by a scalar number
2907b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2908b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving vector
2909b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a the vector to scale
2910b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} b amount to scale the vector by
2911b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2912b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
2913b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2914b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.scale = vec4.scale;
2915b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2916b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2917b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotates a quaternion by the given angle about the X axis
2918b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2919b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out quat receiving operation result
2920b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a quat to rotate
2921b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} rad angle (in radians) to rotate
2922b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2923b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2924b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.rotateX = function (out, a, rad) {
2925b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    rad *= 0.5;
2926b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2927b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
2928b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        bx = Math.sin(rad), bw = Math.cos(rad);
2929b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2930b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = ax * bw + aw * bx;
2931b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = ay * bw + az * bx;
2932b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = az * bw - ay * bx;
2933b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = aw * bw - ax * bx;
2934b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2935b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2936b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2937b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2938b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotates a quaternion by the given angle about the Y axis
2939b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2940b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out quat receiving operation result
2941b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a quat to rotate
2942b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} rad angle (in radians) to rotate
2943b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2944b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2945b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.rotateY = function (out, a, rad) {
2946b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    rad *= 0.5;
2947b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2948b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
2949b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        by = Math.sin(rad), bw = Math.cos(rad);
2950b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2951b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = ax * bw - az * by;
2952b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = ay * bw + aw * by;
2953b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = az * bw + ax * by;
2954b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = aw * bw - ay * by;
2955b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2956b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2957b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2958b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2959b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotates a quaternion by the given angle about the Z axis
2960b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2961b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out quat receiving operation result
2962b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a quat to rotate
2963b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {number} rad angle (in radians) to rotate
2964b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2965b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2966b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.rotateZ = function (out, a, rad) {
2967b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    rad *= 0.5;
2968b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2969b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
2970b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        bz = Math.sin(rad), bw = Math.cos(rad);
2971b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2972b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = ax * bw + ay * bz;
2973b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = ay * bw - ax * bz;
2974b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = az * bw + aw * bz;
2975b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = aw * bw - az * bz;
2976b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2977b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2978b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2979b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2980b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the W component of a quat from the X, Y, and Z components.
2981b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Assumes that quaternion is 1 unit in length.
2982b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Any existing W component will be ignored.
2983b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
2984b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
2985b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a quat to calculate W component of
2986b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
2987b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
2988b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.calculateW = function (out, a) {
2989b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0], y = a[1], z = a[2];
2990b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2991b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = x;
2992b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = y;
2993b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = z;
2994b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));
2995b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
2996b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
2997b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
2998b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
2999b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the dot product of two quat's
3000b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3001b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a the first operand
3002b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} b the second operand
3003b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} dot product of a and b
3004b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3005b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3006b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.dot = vec4.dot;
3007b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3008b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3009b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Performs a linear interpolation between two quat's
3010b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3011b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
3012b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a the first operand
3013b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} b the second operand
3014b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} t interpolation amount between the two inputs
3015b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
3016b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3017b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3018b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.lerp = vec4.lerp;
3019b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3020b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3021b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Performs a spherical linear interpolation between two quat
3022b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3023b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
3024b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a the first operand
3025b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} b the second operand
3026b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} t interpolation amount between the two inputs
3027b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
3028b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3029b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.slerp = function (out, a, b, t) {
3030b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // benchmarks:
3031b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    //    http://jsperf.com/quaternion-slerp-implementations
3032b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3033b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var ax = a[0], ay = a[1], az = a[2], aw = a[3],
3034b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        bx = b[0], by = b[1], bz = b[2], bw = b[3];
3035b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3036b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var        omega, cosom, sinom, scale0, scale1;
3037b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3038b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // calc cosine
3039b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    cosom = ax * bx + ay * by + az * bz + aw * bw;
3040b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // adjust signs (if necessary)
3041b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if ( cosom < 0.0 ) {
3042b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        cosom = -cosom;
3043b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        bx = - bx;
3044b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        by = - by;
3045b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        bz = - bz;
3046b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        bw = - bw;
3047b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
3048b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // calculate coefficients
3049b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if ( (1.0 - cosom) > 0.000001 ) {
3050b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        // standard case (slerp)
3051b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        omega  = Math.acos(cosom);
3052b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        sinom  = Math.sin(omega);
3053b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        scale0 = Math.sin((1.0 - t) * omega) / sinom;
3054b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        scale1 = Math.sin(t * omega) / sinom;
3055b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    } else {
3056b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        // "from" and "to" quaternions are very close
3057b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        //  ... so we can do a linear interpolation
3058b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        scale0 = 1.0 - t;
3059b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        scale1 = t;
3060b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
3061b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // calculate final values
3062b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = scale0 * ax + scale1 * bx;
3063b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = scale0 * ay + scale1 * by;
3064b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = scale0 * az + scale1 * bz;
3065b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = scale0 * aw + scale1 * bw;
3066b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3067b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3068b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3069b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3070b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3071b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Performs a spherical linear interpolation with two control points
3072b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3073b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
3074b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a the first operand
3075b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} b the second operand
3076b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} c the third operand
3077b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} d the fourth operand
3078b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} t interpolation amount
3079b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
3080b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3081b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.sqlerp = (function () {
3082b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  var temp1 = quat.create();
3083b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  var temp2 = quat.create();
3084b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3085b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  return function (out, a, b, c, d, t) {
3086b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    quat.slerp(temp1, a, d, t);
3087b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    quat.slerp(temp2, b, c, t);
3088b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    quat.slerp(out, temp1, temp2, 2 * t * (1 - t));
3089b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3090b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3091b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  };
3092b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	}());
3093b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3094b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3095b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the inverse of a quat
3096b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3097b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
3098b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a quat to calculate inverse of
3099b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
3100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.invert = function(out, a) {
3102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3],
3103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        dot = a0*a0 + a1*a1 + a2*a2 + a3*a3,
3104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        invDot = dot ? 1.0/dot : 0;
3105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0
3107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = -a0*invDot;
3109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = -a1*invDot;
3110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = -a2*invDot;
3111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a3*invDot;
3112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the conjugate of a quat
3117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.
3118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
3120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a quat to calculate conjugate of
3121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
3122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.conjugate = function (out, a) {
3124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = -a[0];
3125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = -a[1];
3126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = -a[2];
3127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
3128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the length of a quat
3133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a vector to calculate length of
3135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} length of a
3136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.length = vec4.length;
3139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link quat.length}
3142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.len = quat.length;
3145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the squared length of a quat
3148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a vector to calculate squared length of
3150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} squared length of a
3151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3152b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3153b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.squaredLength = vec4.squaredLength;
3154b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3155b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3156b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link quat.squaredLength}
3157b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3158b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3159b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.sqrLen = quat.squaredLength;
3160b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3161b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3162b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Normalize a quat
3163b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3164b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
3165b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} a quaternion to normalize
3166b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
3167b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3168b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3169b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.normalize = vec4.normalize;
3170b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3171b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3172b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a quaternion from the given 3x3 rotation matrix.
3173b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3174b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * NOTE: The resultant quaternion is not normalized, so you should be sure
3175b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * to renormalize the quaternion yourself where necessary.
3176b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3177b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} out the receiving quaternion
3178b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} m rotation matrix
3179b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {quat} out
3180b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3181b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3182b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.fromMat3 = function(out, m) {
3183b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
3184b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // article "Quaternion Calculus and Fast Animation".
3185b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var fTrace = m[0] + m[4] + m[8];
3186b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var fRoot;
3187b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3188b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if ( fTrace > 0.0 ) {
3189b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        // |w| > 1/2, may as well choose w > 1/2
3190b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        fRoot = Math.sqrt(fTrace + 1.0);  // 2w
3191b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[3] = 0.5 * fRoot;
3192b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        fRoot = 0.5/fRoot;  // 1/(4w)
3193b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[0] = (m[5]-m[7])*fRoot;
3194b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[1] = (m[6]-m[2])*fRoot;
3195b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[2] = (m[1]-m[3])*fRoot;
3196b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    } else {
3197b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        // |w| <= 1/2
3198b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        var i = 0;
3199b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if ( m[4] > m[0] )
3200b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	          i = 1;
3201b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if ( m[8] > m[i*3+i] )
3202b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	          i = 2;
3203b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        var j = (i+1)%3;
3204b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        var k = (i+2)%3;
3205b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3206b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        fRoot = Math.sqrt(m[i*3+i]-m[j*3+j]-m[k*3+k] + 1.0);
3207b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[i] = 0.5 * fRoot;
3208b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        fRoot = 0.5 / fRoot;
3209b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[3] = (m[j*3+k] - m[k*3+j]) * fRoot;
3210b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[j] = (m[j*3+i] + m[i*3+j]) * fRoot;
3211b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[k] = (m[k*3+i] + m[i*3+k]) * fRoot;
3212b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
3213b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3214b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3215b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3216b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3217b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3218b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns a string representation of a quatenion
3219b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3220b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} vec vector to represent as a string
3221b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {String} string representation of the vector
3222b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3223b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	quat.str = function (a) {
3224b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
3225b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3226b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3227b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	module.exports = quat;
3228b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3229b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3230b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ },
3231b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/* 7 */
3232b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ function(module, exports, __webpack_require__) {
3233b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3234b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
3235b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3236b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	Permission is hereby granted, free of charge, to any person obtaining a copy
3237b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	of this software and associated documentation files (the "Software"), to deal
3238b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	in the Software without restriction, including without limitation the rights
3239b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3240b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	copies of the Software, and to permit persons to whom the Software is
3241b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	furnished to do so, subject to the following conditions:
3242b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3243b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	The above copyright notice and this permission notice shall be included in
3244b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	all copies or substantial portions of the Software.
3245b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3246b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3247b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3248b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3249b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3250b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3251b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3252b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE. */
3253b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3254b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var glMatrix = __webpack_require__(1);
3255b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3256b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3257b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @class 3 Dimensional Vector
3258b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @name vec3
3259b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3260b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var vec3 = {};
3261b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3262b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3263b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new, empty vec3
3264b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3265b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} a new 3D vector
3266b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3267b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.create = function() {
3268b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(3);
3269b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 0;
3270b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
3271b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
3272b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3273b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3274b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3275b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3276b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new vec3 initialized with values from an existing vector
3277b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3278b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a vector to clone
3279b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} a new 3D vector
3280b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3281b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.clone = function(a) {
3282b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(3);
3283b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
3284b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
3285b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
3286b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3287b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3288b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3289b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3290b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new vec3 initialized with the given values
3291b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3292b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} x X component
3293b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} y Y component
3294b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} z Z component
3295b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} a new 3D vector
3296b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3297b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.fromValues = function(x, y, z) {
3298b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(3);
3299b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = x;
3300b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = y;
3301b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = z;
3302b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3303b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3304b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3305b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3306b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Copy the values from one vec3 to another
3307b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3308b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3309b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the source vector
3310b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3311b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3312b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.copy = function(out, a) {
3313b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
3314b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
3315b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
3316b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3317b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3318b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3319b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3320b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Set the components of a vec3 to the given values
3321b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3322b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3323b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} x X component
3324b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} y Y component
3325b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} z Z component
3326b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3327b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3328b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.set = function(out, x, y, z) {
3329b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = x;
3330b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = y;
3331b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = z;
3332b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3333b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3334b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3335b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3336b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Adds two vec3's
3337b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3338b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3339b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3340b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3341b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3342b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3343b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.add = function(out, a, b) {
3344b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] + b[0];
3345b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] + b[1];
3346b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] + b[2];
3347b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3348b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3349b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3350b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3351b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Subtracts vector b from vector a
3352b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3353b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3354b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3355b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3356b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3357b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3358b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.subtract = function(out, a, b) {
3359b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] - b[0];
3360b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] - b[1];
3361b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] - b[2];
3362b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3363b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3364b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3365b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3366b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec3.subtract}
3367b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3368b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3369b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.sub = vec3.subtract;
3370b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3371b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3372b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Multiplies two vec3's
3373b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3374b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3375b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3376b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3377b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3378b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3379b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.multiply = function(out, a, b) {
3380b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] * b[0];
3381b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] * b[1];
3382b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] * b[2];
3383b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3384b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3385b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3386b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3387b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec3.multiply}
3388b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3389b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3390b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.mul = vec3.multiply;
3391b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3392b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3393b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Divides two vec3's
3394b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3395b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3396b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3397b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3398b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3399b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3400b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.divide = function(out, a, b) {
3401b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] / b[0];
3402b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] / b[1];
3403b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] / b[2];
3404b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3405b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3406b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3407b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3408b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec3.divide}
3409b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3410b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3411b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.div = vec3.divide;
3412b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3413b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3414b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns the minimum of two vec3's
3415b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3416b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3417b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3418b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3419b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3420b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3421b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.min = function(out, a, b) {
3422b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = Math.min(a[0], b[0]);
3423b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = Math.min(a[1], b[1]);
3424b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = Math.min(a[2], b[2]);
3425b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3426b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3427b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3428b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3429b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns the maximum of two vec3's
3430b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3431b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3432b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3433b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3434b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3435b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3436b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.max = function(out, a, b) {
3437b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = Math.max(a[0], b[0]);
3438b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = Math.max(a[1], b[1]);
3439b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = Math.max(a[2], b[2]);
3440b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3441b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3442b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3443b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3444b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Scales a vec3 by a scalar number
3445b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3446b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3447b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the vector to scale
3448b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} b amount to scale the vector by
3449b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3450b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3451b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.scale = function(out, a, b) {
3452b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] * b;
3453b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] * b;
3454b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] * b;
3455b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3456b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3457b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3458b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3459b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Adds two vec3's after scaling the second operand by a scalar value
3460b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3461b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3462b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3463b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3464b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} scale the amount to scale b by before adding
3465b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3466b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3467b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.scaleAndAdd = function(out, a, b, scale) {
3468b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] + (b[0] * scale);
3469b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] + (b[1] * scale);
3470b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] + (b[2] * scale);
3471b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3472b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3473b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3474b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3475b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the euclidian distance between two vec3's
3476b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3477b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3478b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3479b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} distance between a and b
3480b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3481b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.distance = function(a, b) {
3482b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = b[0] - a[0],
3483b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = b[1] - a[1],
3484b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z = b[2] - a[2];
3485b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return Math.sqrt(x*x + y*y + z*z);
3486b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3487b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3488b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3489b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec3.distance}
3490b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3491b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3492b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.dist = vec3.distance;
3493b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3494b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3495b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the squared euclidian distance between two vec3's
3496b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3497b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3498b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3499b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} squared distance between a and b
3500b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3501b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.squaredDistance = function(a, b) {
3502b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = b[0] - a[0],
3503b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = b[1] - a[1],
3504b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z = b[2] - a[2];
3505b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return x*x + y*y + z*z;
3506b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3507b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3508b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3509b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec3.squaredDistance}
3510b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3511b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3512b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.sqrDist = vec3.squaredDistance;
3513b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3514b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3515b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the length of a vec3
3516b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3517b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a vector to calculate length of
3518b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} length of a
3519b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3520b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.length = function (a) {
3521b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
3522b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1],
3523b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z = a[2];
3524b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return Math.sqrt(x*x + y*y + z*z);
3525b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3526b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3527b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3528b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec3.length}
3529b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3530b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3531b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.len = vec3.length;
3532b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3533b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3534b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the squared length of a vec3
3535b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3536b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a vector to calculate squared length of
3537b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} squared length of a
3538b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3539b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.squaredLength = function (a) {
3540b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
3541b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1],
3542b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z = a[2];
3543b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return x*x + y*y + z*z;
3544b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3545b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3546b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3547b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec3.squaredLength}
3548b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3549b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3550b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.sqrLen = vec3.squaredLength;
3551b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3552b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3553b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Negates the components of a vec3
3554b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3555b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3556b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a vector to negate
3557b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3558b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3559b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.negate = function(out, a) {
3560b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = -a[0];
3561b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = -a[1];
3562b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = -a[2];
3563b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3564b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3565b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3566b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3567b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns the inverse of the components of a vec3
3568b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3569b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3570b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a vector to invert
3571b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3572b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3573b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.inverse = function(out, a) {
3574b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[0] = 1.0 / a[0];
3575b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[1] = 1.0 / a[1];
3576b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[2] = 1.0 / a[2];
3577b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  return out;
3578b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3579b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3580b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3581b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Normalize a vec3
3582b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3583b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3584b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a vector to normalize
3585b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3586b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3587b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.normalize = function(out, a) {
3588b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
3589b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1],
3590b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z = a[2];
3591b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var len = x*x + y*y + z*z;
3592b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (len > 0) {
3593b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        //TODO: evaluate use of glm_invsqrt here?
3594b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        len = 1 / Math.sqrt(len);
3595b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[0] = a[0] * len;
3596b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[1] = a[1] * len;
3597b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[2] = a[2] * len;
3598b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
3599b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3600b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3601b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3602b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3603b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the dot product of two vec3's
3604b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3605b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3606b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3607b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} dot product of a and b
3608b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3609b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.dot = function (a, b) {
3610b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
3611b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3612b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3613b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3614b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Computes the cross product of two vec3's
3615b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3616b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3617b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3618b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3619b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3620b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3621b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.cross = function(out, a, b) {
3622b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var ax = a[0], ay = a[1], az = a[2],
3623b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        bx = b[0], by = b[1], bz = b[2];
3624b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3625b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = ay * bz - az * by;
3626b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = az * bx - ax * bz;
3627b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = ax * by - ay * bx;
3628b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3629b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3630b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3631b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3632b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Performs a linear interpolation between two vec3's
3633b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3634b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3635b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3636b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3637b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} t interpolation amount between the two inputs
3638b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3639b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3640b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.lerp = function (out, a, b, t) {
3641b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var ax = a[0],
3642b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        ay = a[1],
3643b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        az = a[2];
3644b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = ax + t * (b[0] - ax);
3645b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = ay + t * (b[1] - ay);
3646b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = az + t * (b[2] - az);
3647b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3648b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3649b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3650b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3651b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Performs a hermite interpolation with two control points
3652b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3653b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3654b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3655b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3656b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} c the third operand
3657b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} d the fourth operand
3658b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} t interpolation amount between the two inputs
3659b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3660b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3661b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.hermite = function (out, a, b, c, d, t) {
3662b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  var factorTimes2 = t * t,
3663b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      factor1 = factorTimes2 * (2 * t - 3) + 1,
3664b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      factor2 = factorTimes2 * (t - 2) + t,
3665b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      factor3 = factorTimes2 * (t - 1),
3666b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      factor4 = factorTimes2 * (3 - 2 * t);
3667b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3668b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
3669b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
3670b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
3671b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3672b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  return out;
3673b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3674b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3675b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3676b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Performs a bezier interpolation with two control points
3677b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3678b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3679b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the first operand
3680b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b the second operand
3681b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} c the third operand
3682b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} d the fourth operand
3683b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} t interpolation amount between the two inputs
3684b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3685b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3686b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.bezier = function (out, a, b, c, d, t) {
3687b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  var inverseFactor = 1 - t,
3688b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      inverseFactorTimesTwo = inverseFactor * inverseFactor,
3689b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      factorTimes2 = t * t,
3690b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      factor1 = inverseFactorTimesTwo * inverseFactor,
3691b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      factor2 = 3 * t * inverseFactorTimesTwo,
3692b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      factor3 = 3 * factorTimes2 * inverseFactor,
3693b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	      factor4 = factorTimes2 * t;
3694b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3695b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
3696b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
3697b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
3698b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3699b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  return out;
3700b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3701b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3702b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3703b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Generates a random vector with the given scale
3704b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3705b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3706b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
3707b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3708b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3709b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.random = function (out, scale) {
3710b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    scale = scale || 1.0;
3711b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3712b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var r = glMatrix.RANDOM() * 2.0 * Math.PI;
3713b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var z = (glMatrix.RANDOM() * 2.0) - 1.0;
3714b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var zScale = Math.sqrt(1.0-z*z) * scale;
3715b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3716b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = Math.cos(r) * zScale;
3717b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = Math.sin(r) * zScale;
3718b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = z * scale;
3719b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3720b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3721b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3722b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3723b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transforms the vec3 with a mat4.
3724b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * 4th vector component is implicitly '1'
3725b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3726b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3727b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the vector to transform
3728b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} m matrix to transform with
3729b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3730b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3731b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.transformMat4 = function(out, a, m) {
3732b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0], y = a[1], z = a[2],
3733b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        w = m[3] * x + m[7] * y + m[11] * z + m[15];
3734b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    w = w || 1.0;
3735b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
3736b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
3737b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
3738b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3739b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3740b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3741b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3742b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transforms the vec3 with a mat3.
3743b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3744b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3745b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the vector to transform
3746b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} m the 3x3 matrix to transform with
3747b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3748b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3749b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.transformMat3 = function(out, a, m) {
3750b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0], y = a[1], z = a[2];
3751b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = x * m[0] + y * m[3] + z * m[6];
3752b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = x * m[1] + y * m[4] + z * m[7];
3753b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = x * m[2] + y * m[5] + z * m[8];
3754b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3755b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3756b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3757b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3758b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transforms the vec3 with a quat
3759b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3760b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
3761b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a the vector to transform
3762b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} q quaternion to transform with
3763b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3764b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3765b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.transformQuat = function(out, a, q) {
3766b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // benchmarks: http://jsperf.com/quaternion-transform-vec3-implementations
3767b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3768b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0], y = a[1], z = a[2],
3769b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        qx = q[0], qy = q[1], qz = q[2], qw = q[3],
3770b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3771b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        // calculate quat * vec
3772b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        ix = qw * x + qy * z - qz * y,
3773b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        iy = qw * y + qz * x - qx * z,
3774b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        iz = qw * z + qx * y - qy * x,
3775b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        iw = -qx * x - qy * y - qz * z;
3776b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3777b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // calculate result * inverse quat
3778b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
3779b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
3780b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
3781b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3782b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3783b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3784b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3785b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotate a 3D vector around the x-axis
3786b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out The receiving vec3
3787b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a The vec3 point to rotate
3788b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b The origin of the rotation
3789b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} c The angle of rotation
3790b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3791b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3792b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.rotateX = function(out, a, b, c){
3793b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	   var p = [], r=[];
3794b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		  //Translate point to the origin
3795b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		  p[0] = a[0] - b[0];
3796b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		  p[1] = a[1] - b[1];
3797b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	p[2] = a[2] - b[2];
3798b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3799b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		  //perform rotation
3800b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		  r[0] = p[0];
3801b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		  r[1] = p[1]*Math.cos(c) - p[2]*Math.sin(c);
3802b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		  r[2] = p[1]*Math.sin(c) + p[2]*Math.cos(c);
3803b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3804b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		  //translate to correct position
3805b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		  out[0] = r[0] + b[0];
3806b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		  out[1] = r[1] + b[1];
3807b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik		  out[2] = r[2] + b[2];
3808b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3809b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	return out;
3810b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3811b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3812b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3813b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotate a 3D vector around the y-axis
3814b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out The receiving vec3
3815b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a The vec3 point to rotate
3816b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b The origin of the rotation
3817b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} c The angle of rotation
3818b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3819b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3820b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.rotateY = function(out, a, b, c){
3821b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	var p = [], r=[];
3822b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	//Translate point to the origin
3823b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	p[0] = a[0] - b[0];
3824b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	p[1] = a[1] - b[1];
3825b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	p[2] = a[2] - b[2];
3826b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3827b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	//perform rotation
3828b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	r[0] = p[2]*Math.sin(c) + p[0]*Math.cos(c);
3829b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	r[1] = p[1];
3830b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	r[2] = p[2]*Math.cos(c) - p[0]*Math.sin(c);
3831b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3832b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	//translate to correct position
3833b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	out[0] = r[0] + b[0];
3834b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	out[1] = r[1] + b[1];
3835b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	out[2] = r[2] + b[2];
3836b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3837b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	return out;
3838b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3839b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3840b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3841b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Rotate a 3D vector around the z-axis
3842b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out The receiving vec3
3843b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a The vec3 point to rotate
3844b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b The origin of the rotation
3845b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} c The angle of rotation
3846b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
3847b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3848b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.rotateZ = function(out, a, b, c){
3849b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	var p = [], r=[];
3850b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	//Translate point to the origin
3851b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	p[0] = a[0] - b[0];
3852b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	p[1] = a[1] - b[1];
3853b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	p[2] = a[2] - b[2];
3854b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3855b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	//perform rotation
3856b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	r[0] = p[0]*Math.cos(c) - p[1]*Math.sin(c);
3857b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	r[1] = p[0]*Math.sin(c) + p[1]*Math.cos(c);
3858b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	r[2] = p[2];
3859b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3860b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	//translate to correct position
3861b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	out[0] = r[0] + b[0];
3862b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	out[1] = r[1] + b[1];
3863b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	out[2] = r[2] + b[2];
3864b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3865b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  	return out;
3866b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3867b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3868b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3869b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Perform some operation over an array of vec3s.
3870b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3871b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Array} a the array of vectors to iterate over
3872b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
3873b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} offset Number of elements to skip at the beginning of the array
3874b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
3875b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Function} fn Function to call for each vector in the array
3876b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Object} [arg] additional argument to pass to fn
3877b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Array} a
3878b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
3879b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3880b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.forEach = (function() {
3881b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var vec = vec3.create();
3882b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3883b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return function(a, stride, offset, count, fn, arg) {
3884b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        var i, l;
3885b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if(!stride) {
3886b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            stride = 3;
3887b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
3888b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3889b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if(!offset) {
3890b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            offset = 0;
3891b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
3892b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3893b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if(count) {
3894b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            l = Math.min((count * stride) + offset, a.length);
3895b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        } else {
3896b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            l = a.length;
3897b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
3898b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3899b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        for(i = offset; i < l; i += stride) {
3900b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2];
3901b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            fn(vec, vec, arg);
3902b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2];
3903b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
3904b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3905b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return a;
3906b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    };
3907b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	})();
3908b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3909b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3910b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Get the angle between two 3D vectors
3911b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} a The first operand
3912b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} b The second operand
3913b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} The angle in radians
3914b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3915b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.angle = function(a, b) {
3916b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3917b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var tempA = vec3.fromValues(a[0], a[1], a[2]);
3918b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var tempB = vec3.fromValues(b[0], b[1], b[2]);
3919b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3920b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    vec3.normalize(tempA, tempA);
3921b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    vec3.normalize(tempB, tempB);
3922b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3923b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var cosine = vec3.dot(tempA, tempB);
3924b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3925b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if(cosine > 1.0){
3926b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return 0;
3927b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    } else {
3928b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return Math.acos(cosine);
3929b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
3930b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3931b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3932b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3933b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns a string representation of a vector
3934b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3935b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} vec vector to represent as a string
3936b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {String} string representation of the vector
3937b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3938b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec3.str = function (a) {
3939b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')';
3940b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3941b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3942b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	module.exports = vec3;
3943b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3944b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3945b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ },
3946b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/* 8 */
3947b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ function(module, exports, __webpack_require__) {
3948b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3949b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
3950b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3951b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	Permission is hereby granted, free of charge, to any person obtaining a copy
3952b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	of this software and associated documentation files (the "Software"), to deal
3953b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	in the Software without restriction, including without limitation the rights
3954b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3955b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	copies of the Software, and to permit persons to whom the Software is
3956b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	furnished to do so, subject to the following conditions:
3957b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3958b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	The above copyright notice and this permission notice shall be included in
3959b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	all copies or substantial portions of the Software.
3960b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3961b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3962b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3963b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3964b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3965b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3966b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3967b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE. */
3968b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3969b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var glMatrix = __webpack_require__(1);
3970b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3971b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3972b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @class 4 Dimensional Vector
3973b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @name vec4
3974b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3975b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var vec4 = {};
3976b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3977b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3978b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new, empty vec4
3979b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3980b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} a new 4D vector
3981b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3982b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.create = function() {
3983b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(4);
3984b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 0;
3985b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
3986b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = 0;
3987b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = 0;
3988b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
3989b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
3990b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
3991b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
3992b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new vec4 initialized with values from an existing vector
3993b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
3994b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a vector to clone
3995b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} a new 4D vector
3996b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
3997b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.clone = function(a) {
3998b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(4);
3999b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
4000b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
4001b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
4002b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
4003b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4004b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4005b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4006b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4007b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new vec4 initialized with the given values
4008b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4009b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} x X component
4010b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} y Y component
4011b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} z Z component
4012b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} w W component
4013b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} a new 4D vector
4014b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4015b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.fromValues = function(x, y, z, w) {
4016b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(4);
4017b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = x;
4018b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = y;
4019b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = z;
4020b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = w;
4021b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4022b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4023b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4024b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4025b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Copy the values from one vec4 to another
4026b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4027b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4028b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the source vector
4029b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4030b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4031b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.copy = function(out, a) {
4032b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
4033b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
4034b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2];
4035b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
4036b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4037b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4038b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4039b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4040b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Set the components of a vec4 to the given values
4041b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4042b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4043b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} x X component
4044b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} y Y component
4045b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} z Z component
4046b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} w W component
4047b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4048b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4049b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.set = function(out, x, y, z, w) {
4050b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = x;
4051b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = y;
4052b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = z;
4053b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = w;
4054b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4055b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4056b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4057b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4058b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Adds two vec4's
4059b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4060b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4061b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the first operand
4062b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} b the second operand
4063b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4064b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4065b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.add = function(out, a, b) {
4066b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] + b[0];
4067b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] + b[1];
4068b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] + b[2];
4069b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3] + b[3];
4070b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4071b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4072b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4073b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4074b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Subtracts vector b from vector a
4075b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4076b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4077b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the first operand
4078b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} b the second operand
4079b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4080b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4081b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.subtract = function(out, a, b) {
4082b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] - b[0];
4083b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] - b[1];
4084b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] - b[2];
4085b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3] - b[3];
4086b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4087b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4088b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4089b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4090b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec4.subtract}
4091b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4092b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4093b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.sub = vec4.subtract;
4094b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4095b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4096b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Multiplies two vec4's
4097b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4098b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4099b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the first operand
4100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} b the second operand
4101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.multiply = function(out, a, b) {
4104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] * b[0];
4105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] * b[1];
4106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] * b[2];
4107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3] * b[3];
4108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec4.multiply}
4113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.mul = vec4.multiply;
4116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Divides two vec4's
4119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the first operand
4122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} b the second operand
4123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.divide = function(out, a, b) {
4126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] / b[0];
4127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] / b[1];
4128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] / b[2];
4129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3] / b[3];
4130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec4.divide}
4135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.div = vec4.divide;
4138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns the minimum of two vec4's
4141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the first operand
4144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} b the second operand
4145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.min = function(out, a, b) {
4148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = Math.min(a[0], b[0]);
4149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = Math.min(a[1], b[1]);
4150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = Math.min(a[2], b[2]);
4151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = Math.min(a[3], b[3]);
4152b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4153b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4154b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4155b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4156b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns the maximum of two vec4's
4157b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4158b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4159b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the first operand
4160b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} b the second operand
4161b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4162b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4163b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.max = function(out, a, b) {
4164b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = Math.max(a[0], b[0]);
4165b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = Math.max(a[1], b[1]);
4166b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = Math.max(a[2], b[2]);
4167b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = Math.max(a[3], b[3]);
4168b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4169b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4170b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4171b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4172b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Scales a vec4 by a scalar number
4173b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4174b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4175b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the vector to scale
4176b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} b amount to scale the vector by
4177b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4178b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4179b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.scale = function(out, a, b) {
4180b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] * b;
4181b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] * b;
4182b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] * b;
4183b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3] * b;
4184b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4185b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4186b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4187b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4188b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Adds two vec4's after scaling the second operand by a scalar value
4189b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4190b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4191b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the first operand
4192b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} b the second operand
4193b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} scale the amount to scale b by before adding
4194b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4195b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4196b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.scaleAndAdd = function(out, a, b, scale) {
4197b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] + (b[0] * scale);
4198b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] + (b[1] * scale);
4199b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = a[2] + (b[2] * scale);
4200b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3] + (b[3] * scale);
4201b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4202b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4203b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4204b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4205b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the euclidian distance between two vec4's
4206b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4207b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the first operand
4208b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} b the second operand
4209b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} distance between a and b
4210b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4211b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.distance = function(a, b) {
4212b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = b[0] - a[0],
4213b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = b[1] - a[1],
4214b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z = b[2] - a[2],
4215b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        w = b[3] - a[3];
4216b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return Math.sqrt(x*x + y*y + z*z + w*w);
4217b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4218b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4219b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4220b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec4.distance}
4221b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4222b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4223b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.dist = vec4.distance;
4224b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4225b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4226b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the squared euclidian distance between two vec4's
4227b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4228b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the first operand
4229b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} b the second operand
4230b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} squared distance between a and b
4231b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4232b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.squaredDistance = function(a, b) {
4233b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = b[0] - a[0],
4234b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = b[1] - a[1],
4235b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z = b[2] - a[2],
4236b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        w = b[3] - a[3];
4237b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return x*x + y*y + z*z + w*w;
4238b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4239b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4240b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4241b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec4.squaredDistance}
4242b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4243b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4244b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.sqrDist = vec4.squaredDistance;
4245b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4246b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4247b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the length of a vec4
4248b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4249b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a vector to calculate length of
4250b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} length of a
4251b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4252b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.length = function (a) {
4253b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
4254b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1],
4255b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z = a[2],
4256b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        w = a[3];
4257b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return Math.sqrt(x*x + y*y + z*z + w*w);
4258b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4259b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4260b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4261b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec4.length}
4262b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4263b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4264b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.len = vec4.length;
4265b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4266b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4267b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the squared length of a vec4
4268b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4269b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a vector to calculate squared length of
4270b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} squared length of a
4271b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4272b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.squaredLength = function (a) {
4273b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
4274b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1],
4275b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z = a[2],
4276b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        w = a[3];
4277b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return x*x + y*y + z*z + w*w;
4278b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4279b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4280b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4281b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec4.squaredLength}
4282b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4283b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4284b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.sqrLen = vec4.squaredLength;
4285b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4286b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4287b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Negates the components of a vec4
4288b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4289b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4290b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a vector to negate
4291b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4292b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4293b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.negate = function(out, a) {
4294b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = -a[0];
4295b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = -a[1];
4296b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = -a[2];
4297b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = -a[3];
4298b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4299b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4300b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4301b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4302b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns the inverse of the components of a vec4
4303b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4304b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4305b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a vector to invert
4306b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4307b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4308b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.inverse = function(out, a) {
4309b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[0] = 1.0 / a[0];
4310b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[1] = 1.0 / a[1];
4311b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[2] = 1.0 / a[2];
4312b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[3] = 1.0 / a[3];
4313b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  return out;
4314b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4315b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4316b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4317b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Normalize a vec4
4318b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4319b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4320b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a vector to normalize
4321b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4322b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4323b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.normalize = function(out, a) {
4324b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
4325b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1],
4326b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        z = a[2],
4327b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        w = a[3];
4328b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var len = x*x + y*y + z*z + w*w;
4329b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (len > 0) {
4330b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        len = 1 / Math.sqrt(len);
4331b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[0] = x * len;
4332b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[1] = y * len;
4333b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[2] = z * len;
4334b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[3] = w * len;
4335b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
4336b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4337b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4338b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4339b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4340b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the dot product of two vec4's
4341b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4342b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the first operand
4343b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} b the second operand
4344b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} dot product of a and b
4345b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4346b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.dot = function (a, b) {
4347b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
4348b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4349b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4350b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4351b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Performs a linear interpolation between two vec4's
4352b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4353b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4354b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the first operand
4355b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} b the second operand
4356b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} t interpolation amount between the two inputs
4357b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4358b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4359b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.lerp = function (out, a, b, t) {
4360b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var ax = a[0],
4361b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        ay = a[1],
4362b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        az = a[2],
4363b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        aw = a[3];
4364b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = ax + t * (b[0] - ax);
4365b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = ay + t * (b[1] - ay);
4366b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = az + t * (b[2] - az);
4367b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = aw + t * (b[3] - aw);
4368b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4369b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4370b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4371b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4372b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Generates a random vector with the given scale
4373b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4374b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4375b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
4376b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4377b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4378b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.random = function (out, scale) {
4379b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    scale = scale || 1.0;
4380b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4381b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    //TODO: This is a pretty awful way of doing this. Find something better.
4382b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = glMatrix.RANDOM();
4383b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = glMatrix.RANDOM();
4384b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = glMatrix.RANDOM();
4385b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = glMatrix.RANDOM();
4386b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    vec4.normalize(out, out);
4387b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    vec4.scale(out, out, scale);
4388b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4389b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4390b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4391b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4392b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transforms the vec4 with a mat4.
4393b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4394b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4395b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the vector to transform
4396b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} m matrix to transform with
4397b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4398b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4399b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.transformMat4 = function(out, a, m) {
4400b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0], y = a[1], z = a[2], w = a[3];
4401b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
4402b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
4403b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
4404b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
4405b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4406b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4407b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4408b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4409b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transforms the vec4 with a quat
4410b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4411b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} out the receiving vector
4412b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} a the vector to transform
4413b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {quat} q quaternion to transform with
4414b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec4} out
4415b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4416b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.transformQuat = function(out, a, q) {
4417b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0], y = a[1], z = a[2],
4418b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        qx = q[0], qy = q[1], qz = q[2], qw = q[3],
4419b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4420b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        // calculate quat * vec
4421b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        ix = qw * x + qy * z - qz * y,
4422b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        iy = qw * y + qz * x - qx * z,
4423b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        iz = qw * z + qx * y - qy * x,
4424b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        iw = -qx * x - qy * y - qz * z;
4425b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4426b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    // calculate result * inverse quat
4427b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
4428b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
4429b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
4430b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[3] = a[3];
4431b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4432b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4433b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4434b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4435b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Perform some operation over an array of vec4s.
4436b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4437b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Array} a the array of vectors to iterate over
4438b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed
4439b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} offset Number of elements to skip at the beginning of the array
4440b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array
4441b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Function} fn Function to call for each vector in the array
4442b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Object} [arg] additional argument to pass to fn
4443b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Array} a
4444b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4445b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4446b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.forEach = (function() {
4447b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var vec = vec4.create();
4448b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4449b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return function(a, stride, offset, count, fn, arg) {
4450b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        var i, l;
4451b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if(!stride) {
4452b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            stride = 4;
4453b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
4454b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4455b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if(!offset) {
4456b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            offset = 0;
4457b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
4458b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4459b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if(count) {
4460b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            l = Math.min((count * stride) + offset, a.length);
4461b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        } else {
4462b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            l = a.length;
4463b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
4464b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4465b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        for(i = offset; i < l; i += stride) {
4466b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            vec[0] = a[i]; vec[1] = a[i+1]; vec[2] = a[i+2]; vec[3] = a[i+3];
4467b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            fn(vec, vec, arg);
4468b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            a[i] = vec[0]; a[i+1] = vec[1]; a[i+2] = vec[2]; a[i+3] = vec[3];
4469b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
4470b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4471b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return a;
4472b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    };
4473b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	})();
4474b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4475b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4476b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns a string representation of a vector
4477b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4478b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec4} vec vector to represent as a string
4479b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {String} string representation of the vector
4480b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4481b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec4.str = function (a) {
4482b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
4483b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4484b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4485b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	module.exports = vec4;
4486b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4487b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4488b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ },
4489b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/* 9 */
4490b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ function(module, exports, __webpack_require__) {
4491b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4492b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV.
4493b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4494b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	Permission is hereby granted, free of charge, to any person obtaining a copy
4495b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	of this software and associated documentation files (the "Software"), to deal
4496b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	in the Software without restriction, including without limitation the rights
4497b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4498b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	copies of the Software, and to permit persons to whom the Software is
4499b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	furnished to do so, subject to the following conditions:
4500b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4501b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	The above copyright notice and this permission notice shall be included in
4502b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	all copies or substantial portions of the Software.
4503b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4504b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4505b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4506b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4507b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4508b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4509b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4510b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	THE SOFTWARE. */
4511b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4512b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var glMatrix = __webpack_require__(1);
4513b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4514b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4515b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @class 2 Dimensional Vector
4516b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @name vec2
4517b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4518b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	var vec2 = {};
4519b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4520b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4521b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new, empty vec2
4522b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4523b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} a new 2D vector
4524b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4525b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.create = function() {
4526b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(2);
4527b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = 0;
4528b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = 0;
4529b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4530b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4531b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4532b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4533b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new vec2 initialized with values from an existing vector
4534b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4535b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a vector to clone
4536b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} a new 2D vector
4537b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4538b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.clone = function(a) {
4539b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(2);
4540b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
4541b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
4542b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4543b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4544b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4545b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4546b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Creates a new vec2 initialized with the given values
4547b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4548b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} x X component
4549b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} y Y component
4550b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} a new 2D vector
4551b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4552b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.fromValues = function(x, y) {
4553b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var out = new glMatrix.ARRAY_TYPE(2);
4554b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = x;
4555b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = y;
4556b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4557b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4558b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4559b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4560b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Copy the values from one vec2 to another
4561b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4562b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4563b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the source vector
4564b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4565b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4566b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.copy = function(out, a) {
4567b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0];
4568b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1];
4569b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4570b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4571b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4572b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4573b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Set the components of a vec2 to the given values
4574b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4575b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4576b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} x X component
4577b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} y Y component
4578b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4579b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4580b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.set = function(out, x, y) {
4581b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = x;
4582b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = y;
4583b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4584b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4585b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4586b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4587b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Adds two vec2's
4588b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4589b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4590b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4591b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4592b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4593b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4594b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.add = function(out, a, b) {
4595b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] + b[0];
4596b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] + b[1];
4597b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4598b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4599b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4600b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4601b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Subtracts vector b from vector a
4602b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4603b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4604b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4605b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4606b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4607b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4608b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.subtract = function(out, a, b) {
4609b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] - b[0];
4610b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] - b[1];
4611b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4612b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4613b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4614b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4615b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec2.subtract}
4616b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4617b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4618b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.sub = vec2.subtract;
4619b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4620b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4621b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Multiplies two vec2's
4622b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4623b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4624b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4625b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4626b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4627b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4628b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.multiply = function(out, a, b) {
4629b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] * b[0];
4630b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] * b[1];
4631b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4632b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4633b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4634b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4635b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec2.multiply}
4636b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4637b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4638b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.mul = vec2.multiply;
4639b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4640b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4641b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Divides two vec2's
4642b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4643b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4644b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4645b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4646b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4647b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4648b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.divide = function(out, a, b) {
4649b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] / b[0];
4650b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] / b[1];
4651b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4652b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4653b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4654b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4655b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec2.divide}
4656b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4657b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4658b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.div = vec2.divide;
4659b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4660b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4661b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns the minimum of two vec2's
4662b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4663b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4664b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4665b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4666b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4667b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4668b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.min = function(out, a, b) {
4669b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = Math.min(a[0], b[0]);
4670b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = Math.min(a[1], b[1]);
4671b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4672b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4673b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4674b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4675b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns the maximum of two vec2's
4676b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4677b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4678b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4679b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4680b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4681b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4682b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.max = function(out, a, b) {
4683b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = Math.max(a[0], b[0]);
4684b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = Math.max(a[1], b[1]);
4685b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4686b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4687b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4688b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4689b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Scales a vec2 by a scalar number
4690b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4691b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4692b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the vector to scale
4693b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} b amount to scale the vector by
4694b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4695b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4696b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.scale = function(out, a, b) {
4697b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] * b;
4698b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] * b;
4699b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4700b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4701b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4702b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4703b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Adds two vec2's after scaling the second operand by a scalar value
4704b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4705b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4706b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4707b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4708b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} scale the amount to scale b by before adding
4709b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4710b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4711b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.scaleAndAdd = function(out, a, b, scale) {
4712b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = a[0] + (b[0] * scale);
4713b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = a[1] + (b[1] * scale);
4714b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4715b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4716b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4717b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4718b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the euclidian distance between two vec2's
4719b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4720b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4721b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4722b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} distance between a and b
4723b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4724b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.distance = function(a, b) {
4725b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = b[0] - a[0],
4726b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = b[1] - a[1];
4727b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return Math.sqrt(x*x + y*y);
4728b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4729b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4730b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4731b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec2.distance}
4732b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4733b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4734b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.dist = vec2.distance;
4735b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4736b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4737b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the squared euclidian distance between two vec2's
4738b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4739b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4740b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4741b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} squared distance between a and b
4742b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4743b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.squaredDistance = function(a, b) {
4744b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = b[0] - a[0],
4745b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = b[1] - a[1];
4746b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return x*x + y*y;
4747b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4748b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4749b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4750b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec2.squaredDistance}
4751b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4752b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4753b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.sqrDist = vec2.squaredDistance;
4754b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4755b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4756b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the length of a vec2
4757b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4758b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a vector to calculate length of
4759b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} length of a
4760b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4761b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.length = function (a) {
4762b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
4763b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1];
4764b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return Math.sqrt(x*x + y*y);
4765b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4766b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4767b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4768b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec2.length}
4769b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4770b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4771b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.len = vec2.length;
4772b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4773b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4774b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the squared length of a vec2
4775b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4776b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a vector to calculate squared length of
4777b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} squared length of a
4778b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4779b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.squaredLength = function (a) {
4780b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
4781b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1];
4782b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return x*x + y*y;
4783b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4784b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4785b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4786b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Alias for {@link vec2.squaredLength}
4787b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4788b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4789b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.sqrLen = vec2.squaredLength;
4790b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4791b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4792b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Negates the components of a vec2
4793b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4794b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4795b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a vector to negate
4796b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4797b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4798b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.negate = function(out, a) {
4799b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = -a[0];
4800b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = -a[1];
4801b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4802b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4803b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4804b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4805b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns the inverse of the components of a vec2
4806b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4807b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4808b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a vector to invert
4809b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4810b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4811b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.inverse = function(out, a) {
4812b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[0] = 1.0 / a[0];
4813b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  out[1] = 1.0 / a[1];
4814b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	  return out;
4815b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4816b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4817b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4818b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Normalize a vec2
4819b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4820b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4821b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a vector to normalize
4822b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4823b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4824b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.normalize = function(out, a) {
4825b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
4826b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1];
4827b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var len = x*x + y*y;
4828b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    if (len > 0) {
4829b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        //TODO: evaluate use of glm_invsqrt here?
4830b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        len = 1 / Math.sqrt(len);
4831b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[0] = a[0] * len;
4832b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        out[1] = a[1] * len;
4833b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    }
4834b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4835b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4836b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4837b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4838b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Calculates the dot product of two vec2's
4839b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4840b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4841b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4842b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Number} dot product of a and b
4843b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4844b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.dot = function (a, b) {
4845b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return a[0] * b[0] + a[1] * b[1];
4846b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4847b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4848b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4849b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Computes the cross product of two vec2's
4850b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Note that the cross product must by definition produce a 3D vector
4851b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4852b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec3} out the receiving vector
4853b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4854b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4855b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec3} out
4856b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4857b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.cross = function(out, a, b) {
4858b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var z = a[0] * b[1] - a[1] * b[0];
4859b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = out[1] = 0;
4860b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[2] = z;
4861b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4862b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4863b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4864b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4865b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Performs a linear interpolation between two vec2's
4866b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4867b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4868b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the first operand
4869b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} b the second operand
4870b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} t interpolation amount between the two inputs
4871b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4872b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4873b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.lerp = function (out, a, b, t) {
4874b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var ax = a[0],
4875b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        ay = a[1];
4876b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = ax + t * (b[0] - ax);
4877b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = ay + t * (b[1] - ay);
4878b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4879b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4880b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4881b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4882b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Generates a random vector with the given scale
4883b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4884b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4885b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
4886b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4887b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4888b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.random = function (out, scale) {
4889b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    scale = scale || 1.0;
4890b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var r = glMatrix.RANDOM() * 2.0 * Math.PI;
4891b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = Math.cos(r) * scale;
4892b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = Math.sin(r) * scale;
4893b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4894b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4895b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4896b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4897b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transforms the vec2 with a mat2
4898b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4899b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4900b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the vector to transform
4901b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2} m matrix to transform with
4902b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4903b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4904b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.transformMat2 = function(out, a, m) {
4905b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
4906b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1];
4907b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = m[0] * x + m[2] * y;
4908b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = m[1] * x + m[3] * y;
4909b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4910b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4911b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4912b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4913b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transforms the vec2 with a mat2d
4914b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4915b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4916b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the vector to transform
4917b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat2d} m matrix to transform with
4918b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4919b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4920b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.transformMat2d = function(out, a, m) {
4921b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
4922b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1];
4923b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = m[0] * x + m[2] * y + m[4];
4924b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = m[1] * x + m[3] * y + m[5];
4925b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4926b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4927b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4928b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4929b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transforms the vec2 with a mat3
4930b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * 3rd vector component is implicitly '1'
4931b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4932b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4933b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the vector to transform
4934b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat3} m matrix to transform with
4935b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4936b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4937b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.transformMat3 = function(out, a, m) {
4938b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
4939b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1];
4940b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = m[0] * x + m[3] * y + m[6];
4941b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = m[1] * x + m[4] * y + m[7];
4942b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4943b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4944b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4945b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4946b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Transforms the vec2 with a mat4
4947b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * 3rd vector component is implicitly '0'
4948b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * 4th vector component is implicitly '1'
4949b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4950b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} out the receiving vector
4951b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} a the vector to transform
4952b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {mat4} m matrix to transform with
4953b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {vec2} out
4954b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4955b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.transformMat4 = function(out, a, m) {
4956b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var x = a[0],
4957b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        y = a[1];
4958b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[0] = m[0] * x + m[4] * y + m[12];
4959b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    out[1] = m[1] * x + m[5] * y + m[13];
4960b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return out;
4961b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
4962b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4963b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
4964b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Perform some operation over an array of vec2s.
4965b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
4966b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Array} a the array of vectors to iterate over
4967b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed
4968b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} offset Number of elements to skip at the beginning of the array
4969b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
4970b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Function} fn Function to call for each vector in the array
4971b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {Object} [arg] additional argument to pass to fn
4972b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {Array} a
4973b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @function
4974b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
4975b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.forEach = (function() {
4976b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    var vec = vec2.create();
4977b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4978b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return function(a, stride, offset, count, fn, arg) {
4979b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        var i, l;
4980b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if(!stride) {
4981b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            stride = 2;
4982b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
4983b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4984b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if(!offset) {
4985b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            offset = 0;
4986b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
4987b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4988b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        if(count) {
4989b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            l = Math.min((count * stride) + offset, a.length);
4990b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        } else {
4991b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            l = a.length;
4992b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
4993b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
4994b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        for(i = offset; i < l; i += stride) {
4995b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            vec[0] = a[i]; vec[1] = a[i+1];
4996b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            fn(vec, vec, arg);
4997b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	            a[i] = vec[0]; a[i+1] = vec[1];
4998b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        }
4999b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
5000b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	        return a;
5001b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    };
5002b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	})();
5003b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
5004b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	/**
5005b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * Returns a string representation of a vector
5006b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 *
5007b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @param {vec2} vec vector to represent as a string
5008b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 * @returns {String} string representation of the vector
5009b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	 */
5010b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	vec2.str = function (a) {
5011b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	    return 'vec2(' + a[0] + ', ' + a[1] + ')';
5012b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	};
5013b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
5014b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik	module.exports = vec2;
5015b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
5016b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik
5017b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/***/ }
5018b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik/******/ ])
5019b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik});
5020b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik;