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