(() => {12/**3* @fileoverview gl-matrix - High performance matrix and vector operations for WebGL4* @author Brandon Jones5* @version 1.2.46*/78// Modified for emscripten:9// - Global scoping etc.10// - Disabled some non-closure-compatible javadoc comments.1112/*13* Copyright (c) 2011 Brandon Jones14*15* This software is provided 'as-is', without any express or implied16* warranty. In no event will the authors be held liable for any damages17* arising from the use of this software.18*19* Permission is granted to anyone to use this software for any purpose,20* including commercial applications, and to alter it and redistribute it21* freely, subject to the following restrictions:22*23* 1. The origin of this software must not be misrepresented; you must not24* claim that you wrote the original software. If you use this software25* in a product, an acknowledgment in the product documentation would be26* appreciated but is not required.27*28* 2. Altered source versions must be plainly marked as such, and must not29* be misrepresented as being the original software.30*31* 3. This notice may not be removed or altered from any source32* distribution.33*/343536/**37* @class 3 Dimensional Vector38* @name vec339*/40var vec3 = {};4142/**43* @class 3x3 Matrix44* @name mat345*/46var mat3 = {};4748/**49* @class 4x4 Matrix50* @name mat451*/52var mat4 = {};5354/**55* @class Quaternion56* @name quat457*/58var quat4 = {};5960var MatrixArray = Float32Array;6162/*63* vec364*/6566/**67* Creates a new instance of a vec3 using the default array type68* Any javascript array-like objects containing at least 3 numeric elements can serve as a vec369*70* _param {vec3} [vec] vec3 containing values to initialize with71*72* _returns {vec3} New vec373*/74vec3.create = function (vec) {75var dest = new MatrixArray(3);7677if (vec) {78dest[0] = vec[0];79dest[1] = vec[1];80dest[2] = vec[2];81} else {82dest[0] = dest[1] = dest[2] = 0;83}8485return dest;86};8788/**89* Copies the values of one vec3 to another90*91* _param {vec3} vec vec3 containing values to copy92* _param {vec3} dest vec3 receiving copied values93*94* _returns {vec3} dest95*/96vec3.set = function (vec, dest) {97dest[0] = vec[0];98dest[1] = vec[1];99dest[2] = vec[2];100101return dest;102};103104/**105* Performs a vector addition106*107* _param {vec3} vec First operand108* _param {vec3} vec2 Second operand109* _param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec110*111* _returns {vec3} dest if specified, vec otherwise112*/113vec3.add = function (vec, vec2, dest) {114if (!dest || vec === dest) {115vec[0] += vec2[0];116vec[1] += vec2[1];117vec[2] += vec2[2];118return vec;119}120121dest[0] = vec[0] + vec2[0];122dest[1] = vec[1] + vec2[1];123dest[2] = vec[2] + vec2[2];124return dest;125};126127/**128* Performs a vector subtraction129*130* _param {vec3} vec First operand131* _param {vec3} vec2 Second operand132* _param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec133*134* _returns {vec3} dest if specified, vec otherwise135*/136vec3.subtract = function (vec, vec2, dest) {137if (!dest || vec === dest) {138vec[0] -= vec2[0];139vec[1] -= vec2[1];140vec[2] -= vec2[2];141return vec;142}143144dest[0] = vec[0] - vec2[0];145dest[1] = vec[1] - vec2[1];146dest[2] = vec[2] - vec2[2];147return dest;148};149150/**151* Performs a vector multiplication152*153* _param {vec3} vec First operand154* _param {vec3} vec2 Second operand155* _param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec156*157* _returns {vec3} dest if specified, vec otherwise158*/159vec3.multiply = function (vec, vec2, dest) {160if (!dest || vec === dest) {161vec[0] *= vec2[0];162vec[1] *= vec2[1];163vec[2] *= vec2[2];164return vec;165}166167dest[0] = vec[0] * vec2[0];168dest[1] = vec[1] * vec2[1];169dest[2] = vec[2] * vec2[2];170return dest;171};172173/**174* Negates the components of a vec3175*176* _param {vec3} vec vec3 to negate177* _param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec178*179* _returns {vec3} dest if specified, vec otherwise180*/181vec3.negate = function (vec, dest) {182if (!dest) { dest = vec; }183184dest[0] = -vec[0];185dest[1] = -vec[1];186dest[2] = -vec[2];187return dest;188};189190/**191* Multiplies the components of a vec3 by a scalar value192*193* _param {vec3} vec vec3 to scale194* _param {number} val Value to scale by195* _param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec196*197* _returns {vec3} dest if specified, vec otherwise198*/199vec3.scale = function (vec, val, dest) {200if (!dest || vec === dest) {201vec[0] *= val;202vec[1] *= val;203vec[2] *= val;204return vec;205}206207dest[0] = vec[0] * val;208dest[1] = vec[1] * val;209dest[2] = vec[2] * val;210return dest;211};212213/**214* Generates a unit vector of the same direction as the provided vec3215* If vector length is 0, returns [0, 0, 0]216*217* _param {vec3} vec vec3 to normalize218* _param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec219*220* _returns {vec3} dest if specified, vec otherwise221*/222vec3.normalize = function (vec, dest) {223if (!dest) { dest = vec; }224225var x = vec[0], y = vec[1], z = vec[2],226len = Math.sqrt(x * x + y * y + z * z);227228if (!len) {229dest[0] = 0;230dest[1] = 0;231dest[2] = 0;232return dest;233} else if (len === 1) {234dest[0] = x;235dest[1] = y;236dest[2] = z;237return dest;238}239240len = 1 / len;241dest[0] = x * len;242dest[1] = y * len;243dest[2] = z * len;244return dest;245};246247/**248* Generates the cross product of two vec3s249*250* _param {vec3} vec First operand251* _param {vec3} vec2 Second operand252* _param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec253*254* _returns {vec3} dest if specified, vec otherwise255*/256vec3.cross = function (vec, vec2, dest) {257if (!dest) { dest = vec; }258259var x = vec[0], y = vec[1], z = vec[2],260x2 = vec2[0], y2 = vec2[1], z2 = vec2[2];261262dest[0] = y * z2 - z * y2;263dest[1] = z * x2 - x * z2;264dest[2] = x * y2 - y * x2;265return dest;266};267268/**269* Calculates the length of a vec3270*271* _param {vec3} vec vec3 to calculate length of272*273* _returns {number} Length of vec274*/275vec3.length = function (vec) {276var x = vec[0], y = vec[1], z = vec[2];277return Math.sqrt(x * x + y * y + z * z);278};279280/**281* Calculates the dot product of two vec3s282*283* _param {vec3} vec First operand284* _param {vec3} vec2 Second operand285*286* _returns {number} Dot product of vec and vec2287*/288vec3.dot = function (vec, vec2) {289return vec[0] * vec2[0] + vec[1] * vec2[1] + vec[2] * vec2[2];290};291292/**293* Generates a unit vector pointing from one vector to another294*295* _param {vec3} vec Origin vec3296* _param {vec3} vec2 vec3 to point to297* _param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec298*299* _returns {vec3} dest if specified, vec otherwise300*/301vec3.direction = function (vec, vec2, dest) {302if (!dest) { dest = vec; }303304var x = vec[0] - vec2[0],305y = vec[1] - vec2[1],306z = vec[2] - vec2[2],307len = Math.sqrt(x * x + y * y + z * z);308309if (!len) {310dest[0] = 0;311dest[1] = 0;312dest[2] = 0;313return dest;314}315316len = 1 / len;317dest[0] = x * len;318dest[1] = y * len;319dest[2] = z * len;320return dest;321};322323/**324* Performs a linear interpolation between two vec3325*326* _param {vec3} vec First vector327* _param {vec3} vec2 Second vector328* _param {number} lerp Interpolation amount between the two inputs329* _param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec330*331* _returns {vec3} dest if specified, vec otherwise332*/333vec3.lerp = function (vec, vec2, lerp, dest) {334if (!dest) { dest = vec; }335336dest[0] = vec[0] + lerp * (vec2[0] - vec[0]);337dest[1] = vec[1] + lerp * (vec2[1] - vec[1]);338dest[2] = vec[2] + lerp * (vec2[2] - vec[2]);339340return dest;341};342343/**344* Calculates the euclidean distance between two vec3345*346* Params:347* _param {vec3} vec First vector348* _param {vec3} vec2 Second vector349*350* _returns {number} Distance between vec and vec2351*/352vec3.dist = function (vec, vec2) {353var x = vec2[0] - vec[0],354y = vec2[1] - vec[1],355z = vec2[2] - vec[2];356357return Math.sqrt(x*x + y*y + z*z);358};359360/**361* Projects the specified vec3 from screen space into object space362* Based on the <a href="http://webcvs.freedesktop.org/mesa/Mesa/src/glu/mesa/project.c?revision=1.4&view=markup">Mesa gluUnProject implementation</a>363*364* _param {vec3} vec Screen-space vector to project365* _param {mat4} view View matrix366* _param {mat4} proj Projection matrix367* _param {vec4} viewport Viewport as given to gl.viewport [x, y, width, height]368* _param {vec3} [dest] vec3 receiving unprojected result. If not specified result is written to vec369*370* _returns {vec3} dest if specified, vec otherwise371*/372vec3.unproject = function (vec, view, proj, viewport, dest) {373if (!dest) { dest = vec; }374375var m = mat4.create();376var v = new MatrixArray(4);377378v[0] = (vec[0] - viewport[0]) * 2.0 / viewport[2] - 1.0;379v[1] = (vec[1] - viewport[1]) * 2.0 / viewport[3] - 1.0;380v[2] = 2.0 * vec[2] - 1.0;381v[3] = 1.0;382383mat4.multiply(proj, view, m);384if(!mat4.inverse(m)) { return null; }385386mat4.multiplyVec4(m, v);387if(v[3] === 0.0) { return null; }388389dest[0] = v[0] / v[3];390dest[1] = v[1] / v[3];391dest[2] = v[2] / v[3];392393return dest;394};395396/**397* Returns a string representation of a vector398*399* _param {vec3} vec Vector to represent as a string400*401* _returns {string} String representation of vec402*/403vec3.str = function (vec) {404return '[' + vec[0] + ', ' + vec[1] + ', ' + vec[2] + ']';405};406407/*408* mat3409*/410411/**412* Creates a new instance of a mat3 using the default array type413* Any javascript array-like object containing at least 9 numeric elements can serve as a mat3414*415* _param {mat3} [mat] mat3 containing values to initialize with416*417* _returns {mat3} New mat3418*419* @param {Object=} mat420*/421mat3.create = function (mat) {422var dest = new MatrixArray(9);423424if (mat) {425dest[0] = mat[0];426dest[1] = mat[1];427dest[2] = mat[2];428dest[3] = mat[3];429dest[4] = mat[4];430dest[5] = mat[5];431dest[6] = mat[6];432dest[7] = mat[7];433dest[8] = mat[8];434}435436return dest;437};438439/**440* Copies the values of one mat3 to another441*442* _param {mat3} mat mat3 containing values to copy443* _param {mat3} dest mat3 receiving copied values444*445* _returns {mat3} dest446*/447mat3.set = function (mat, dest) {448dest[0] = mat[0];449dest[1] = mat[1];450dest[2] = mat[2];451dest[3] = mat[3];452dest[4] = mat[4];453dest[5] = mat[5];454dest[6] = mat[6];455dest[7] = mat[7];456dest[8] = mat[8];457return dest;458};459460/**461* Sets a mat3 to an identity matrix462*463* _param {mat3} dest mat3 to set464*465* _returns dest if specified, otherwise a new mat3466*/467mat3.identity = function (dest) {468if (!dest) { dest = mat3.create(); }469dest[0] = 1;470dest[1] = 0;471dest[2] = 0;472dest[3] = 0;473dest[4] = 1;474dest[5] = 0;475dest[6] = 0;476dest[7] = 0;477dest[8] = 1;478return dest;479};480481/**482* Transposes a mat3 (flips the values over the diagonal)483*484* Params:485* _param {mat3} mat mat3 to transpose486* _param {mat3} [dest] mat3 receiving transposed values. If not specified result is written to mat487*/488mat3.transpose = function (mat, dest) {489// If we are transposing ourselves we can skip a few steps but have to cache some values490if (!dest || mat === dest) {491var a01 = mat[1], a02 = mat[2],492a12 = mat[5];493494mat[1] = mat[3];495mat[2] = mat[6];496mat[3] = a01;497mat[5] = mat[7];498mat[6] = a02;499mat[7] = a12;500return mat;501}502503dest[0] = mat[0];504dest[1] = mat[3];505dest[2] = mat[6];506dest[3] = mat[1];507dest[4] = mat[4];508dest[5] = mat[7];509dest[6] = mat[2];510dest[7] = mat[5];511dest[8] = mat[8];512return dest;513};514515/**516* Copies the elements of a mat3 into the upper 3x3 elements of a mat4517*518* _param {mat3} mat mat3 containing values to copy519* _param {mat4} [dest] mat4 receiving copied values520*521* _returns {mat4} dest if specified, a new mat4 otherwise522*/523mat3.toMat4 = function (mat, dest) {524if (!dest) { dest = mat4.create(); }525526dest[15] = 1;527dest[14] = 0;528dest[13] = 0;529dest[12] = 0;530531dest[11] = 0;532dest[10] = mat[8];533dest[9] = mat[7];534dest[8] = mat[6];535536dest[7] = 0;537dest[6] = mat[5];538dest[5] = mat[4];539dest[4] = mat[3];540541dest[3] = 0;542dest[2] = mat[2];543dest[1] = mat[1];544dest[0] = mat[0];545546return dest;547};548549/**550* Returns a string representation of a mat3551*552* _param {mat3} mat mat3 to represent as a string553*554* _param {string} String representation of mat555*/556mat3.str = function (mat) {557return '[' + mat[0] + ', ' + mat[1] + ', ' + mat[2] +558', ' + mat[3] + ', ' + mat[4] + ', ' + mat[5] +559', ' + mat[6] + ', ' + mat[7] + ', ' + mat[8] + ']';560};561562/*563* mat4564*/565566/**567* Creates a new instance of a mat4 using the default array type568* Any javascript array-like object containing at least 16 numeric elements can serve as a mat4569*570* _param {mat4} [mat] mat4 containing values to initialize with571*572* _returns {mat4} New mat4573*574* @param {Object=} mat575*/576mat4.create = function (mat) {577var dest = new MatrixArray(16);578579if (mat) {580dest[0] = mat[0];581dest[1] = mat[1];582dest[2] = mat[2];583dest[3] = mat[3];584dest[4] = mat[4];585dest[5] = mat[5];586dest[6] = mat[6];587dest[7] = mat[7];588dest[8] = mat[8];589dest[9] = mat[9];590dest[10] = mat[10];591dest[11] = mat[11];592dest[12] = mat[12];593dest[13] = mat[13];594dest[14] = mat[14];595dest[15] = mat[15];596}597598return dest;599};600601/**602* Copies the values of one mat4 to another603*604* _param {mat4} mat mat4 containing values to copy605* _param {mat4} dest mat4 receiving copied values606*607* _returns {mat4} dest608*/609mat4.set = function (mat, dest) {610dest[0] = mat[0];611dest[1] = mat[1];612dest[2] = mat[2];613dest[3] = mat[3];614dest[4] = mat[4];615dest[5] = mat[5];616dest[6] = mat[6];617dest[7] = mat[7];618dest[8] = mat[8];619dest[9] = mat[9];620dest[10] = mat[10];621dest[11] = mat[11];622dest[12] = mat[12];623dest[13] = mat[13];624dest[14] = mat[14];625dest[15] = mat[15];626return dest;627};628629/**630* Sets a mat4 to an identity matrix631*632* _param {mat4} dest mat4 to set633*634* _returns {mat4} dest635*/636mat4.identity = function (dest) {637if (!dest) { dest = mat4.create(); }638dest[0] = 1;639dest[1] = 0;640dest[2] = 0;641dest[3] = 0;642dest[4] = 0;643dest[5] = 1;644dest[6] = 0;645dest[7] = 0;646dest[8] = 0;647dest[9] = 0;648dest[10] = 1;649dest[11] = 0;650dest[12] = 0;651dest[13] = 0;652dest[14] = 0;653dest[15] = 1;654return dest;655};656657/**658* Transposes a mat4 (flips the values over the diagonal)659*660* _param {mat4} mat mat4 to transpose661* _param {mat4} [dest] mat4 receiving transposed values. If not specified result is written to mat662*/663mat4.transpose = function (mat, dest) {664// If we are transposing ourselves we can skip a few steps but have to cache some values665if (!dest || mat === dest) {666var a01 = mat[1], a02 = mat[2], a03 = mat[3],667a12 = mat[6], a13 = mat[7],668a23 = mat[11];669670mat[1] = mat[4];671mat[2] = mat[8];672mat[3] = mat[12];673mat[4] = a01;674mat[6] = mat[9];675mat[7] = mat[13];676mat[8] = a02;677mat[9] = a12;678mat[11] = mat[14];679mat[12] = a03;680mat[13] = a13;681mat[14] = a23;682return mat;683}684685dest[0] = mat[0];686dest[1] = mat[4];687dest[2] = mat[8];688dest[3] = mat[12];689dest[4] = mat[1];690dest[5] = mat[5];691dest[6] = mat[9];692dest[7] = mat[13];693dest[8] = mat[2];694dest[9] = mat[6];695dest[10] = mat[10];696dest[11] = mat[14];697dest[12] = mat[3];698dest[13] = mat[7];699dest[14] = mat[11];700dest[15] = mat[15];701return dest;702};703704/**705* Calculates the determinant of a mat4706*707* _param {mat4} mat mat4 to calculate determinant of708*709* _returns {number} determinant of mat710*/711mat4.determinant = function (mat) {712// Cache the matrix values (makes for huge speed increases!)713var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3],714a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7],715a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11],716a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];717718return (a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 +719a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 +720a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 +721a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 +722a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 +723a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33);724};725726/**727* Calculates the inverse matrix of a mat4728*729* _param {mat4} mat mat4 to calculate inverse of730* _param {mat4} [dest] mat4 receiving inverse matrix. If not specified result is written to mat, null if matrix cannot be inverted731*732* @param {Object=} dest733*/734mat4.inverse = function (mat, dest) {735if (!dest) { dest = mat; }736737// Cache the matrix values (makes for huge speed increases!)738var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3],739a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7],740a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11],741a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15],742743b00 = a00 * a11 - a01 * a10,744b01 = a00 * a12 - a02 * a10,745b02 = a00 * a13 - a03 * a10,746b03 = a01 * a12 - a02 * a11,747b04 = a01 * a13 - a03 * a11,748b05 = a02 * a13 - a03 * a12,749b06 = a20 * a31 - a21 * a30,750b07 = a20 * a32 - a22 * a30,751b08 = a20 * a33 - a23 * a30,752b09 = a21 * a32 - a22 * a31,753b10 = a21 * a33 - a23 * a31,754b11 = a22 * a33 - a23 * a32,755756d = (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06),757invDet;758759// Calculate the determinant760if (!d) { return null; }761invDet = 1 / d;762763dest[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;764dest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;765dest[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;766dest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;767dest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;768dest[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;769dest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;770dest[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;771dest[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;772dest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;773dest[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;774dest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;775dest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;776dest[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;777dest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;778dest[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;779780return dest;781};782783/**784* Copies the upper 3x3 elements of a mat4 into another mat4785*786* _param {mat4} mat mat4 containing values to copy787* _param {mat4} [dest] mat4 receiving copied values788*789* _returns {mat4} dest is specified, a new mat4 otherwise790*/791mat4.toRotationMat = function (mat, dest) {792if (!dest) { dest = mat4.create(); }793794dest[0] = mat[0];795dest[1] = mat[1];796dest[2] = mat[2];797dest[3] = mat[3];798dest[4] = mat[4];799dest[5] = mat[5];800dest[6] = mat[6];801dest[7] = mat[7];802dest[8] = mat[8];803dest[9] = mat[9];804dest[10] = mat[10];805dest[11] = mat[11];806dest[12] = 0;807dest[13] = 0;808dest[14] = 0;809dest[15] = 1;810811return dest;812};813814/**815* Copies the upper 3x3 elements of a mat4 into a mat3816*817* _param {mat4} mat mat4 containing values to copy818* _param {mat3} [dest] mat3 receiving copied values819*820* _returns {mat3} dest is specified, a new mat3 otherwise821*/822mat4.toMat3 = function (mat, dest) {823if (!dest) { dest = mat3.create(); }824825dest[0] = mat[0];826dest[1] = mat[1];827dest[2] = mat[2];828dest[3] = mat[4];829dest[4] = mat[5];830dest[5] = mat[6];831dest[6] = mat[8];832dest[7] = mat[9];833dest[8] = mat[10];834835return dest;836};837838/**839* Calculates the inverse of the upper 3x3 elements of a mat4 and copies the result into a mat3840* The resulting matrix is useful for calculating transformed normals841*842* Params:843* _param {mat4} mat mat4 containing values to invert and copy844* _param {mat3} [dest] mat3 receiving values845*846* _returns {mat3} dest is specified, a new mat3 otherwise, null if the matrix cannot be inverted847*/848mat4.toInverseMat3 = function (mat, dest) {849// Cache the matrix values (makes for huge speed increases!)850var a00 = mat[0], a01 = mat[1], a02 = mat[2],851a10 = mat[4], a11 = mat[5], a12 = mat[6],852a20 = mat[8], a21 = mat[9], a22 = mat[10],853854b01 = a22 * a11 - a12 * a21,855b11 = -a22 * a10 + a12 * a20,856b21 = a21 * a10 - a11 * a20,857858d = a00 * b01 + a01 * b11 + a02 * b21,859id;860861if (!d) { return null; }862id = 1 / d;863864if (!dest) { dest = mat3.create(); }865866dest[0] = b01 * id;867dest[1] = (-a22 * a01 + a02 * a21) * id;868dest[2] = (a12 * a01 - a02 * a11) * id;869dest[3] = b11 * id;870dest[4] = (a22 * a00 - a02 * a20) * id;871dest[5] = (-a12 * a00 + a02 * a10) * id;872dest[6] = b21 * id;873dest[7] = (-a21 * a00 + a01 * a20) * id;874dest[8] = (a11 * a00 - a01 * a10) * id;875876return dest;877};878879/**880* Performs a matrix multiplication881*882* _param {mat4} mat First operand883* _param {mat4} mat2 Second operand884* _param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat885*/886mat4.multiply = function (mat, mat2, dest) {887if (!dest) { dest = mat; }888889// Cache the matrix values (makes for huge speed increases!)890var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3],891a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7],892a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11],893a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15],894895b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3],896b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7],897b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11],898b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15];899900dest[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;901dest[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;902dest[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;903dest[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;904dest[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;905dest[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;906dest[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;907dest[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;908dest[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;909dest[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;910dest[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;911dest[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;912dest[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;913dest[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;914dest[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;915dest[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;916917return dest;918};919920/**921* Transforms a vec3 with the given matrix922* 4th vector component is implicitly '1'923*924* _param {mat4} mat mat4 to transform the vector with925* _param {vec3} vec vec3 to transform926* _param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec927*928* _returns {vec3} dest if specified, vec otherwise929*/930mat4.multiplyVec3 = function (mat, vec, dest) {931if (!dest) { dest = vec; }932933var x = vec[0], y = vec[1], z = vec[2];934935dest[0] = mat[0] * x + mat[4] * y + mat[8] * z + mat[12];936dest[1] = mat[1] * x + mat[5] * y + mat[9] * z + mat[13];937dest[2] = mat[2] * x + mat[6] * y + mat[10] * z + mat[14];938939return dest;940};941942/**943* Transforms a vec4 with the given matrix944*945* _param {mat4} mat mat4 to transform the vector with946* _param {vec4} vec vec4 to transform947* _param {vec4} [dest] vec4 receiving operation result. If not specified result is written to vec948*949* _returns {vec4} dest if specified, vec otherwise950*951* @param {Object=} dest952*/953mat4.multiplyVec4 = function (mat, vec, dest) {954if (!dest) { dest = vec; }955956var x = vec[0], y = vec[1], z = vec[2], w = vec[3];957958dest[0] = mat[0] * x + mat[4] * y + mat[8] * z + mat[12] * w;959dest[1] = mat[1] * x + mat[5] * y + mat[9] * z + mat[13] * w;960dest[2] = mat[2] * x + mat[6] * y + mat[10] * z + mat[14] * w;961dest[3] = mat[3] * x + mat[7] * y + mat[11] * z + mat[15] * w;962963return dest;964};965966/**967* Translates a matrix by the given vector968*969* _param {mat4} mat mat4 to translate970* _param {vec3} vec vec3 specifying the translation971* _param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat972*/973mat4.translate = function (mat, vec, dest) {974var x = vec[0], y = vec[1], z = vec[2],975a00, a01, a02, a03,976a10, a11, a12, a13,977a20, a21, a22, a23;978979if (!dest || mat === dest) {980mat[12] = mat[0] * x + mat[4] * y + mat[8] * z + mat[12];981mat[13] = mat[1] * x + mat[5] * y + mat[9] * z + mat[13];982mat[14] = mat[2] * x + mat[6] * y + mat[10] * z + mat[14];983mat[15] = mat[3] * x + mat[7] * y + mat[11] * z + mat[15];984return mat;985}986987a00 = mat[0]; a01 = mat[1]; a02 = mat[2]; a03 = mat[3];988a10 = mat[4]; a11 = mat[5]; a12 = mat[6]; a13 = mat[7];989a20 = mat[8]; a21 = mat[9]; a22 = mat[10]; a23 = mat[11];990991dest[0] = a00; dest[1] = a01; dest[2] = a02; dest[3] = a03;992dest[4] = a10; dest[5] = a11; dest[6] = a12; dest[7] = a13;993dest[8] = a20; dest[9] = a21; dest[10] = a22; dest[11] = a23;994995dest[12] = a00 * x + a10 * y + a20 * z + mat[12];996dest[13] = a01 * x + a11 * y + a21 * z + mat[13];997dest[14] = a02 * x + a12 * y + a22 * z + mat[14];998dest[15] = a03 * x + a13 * y + a23 * z + mat[15];999return dest;1000};10011002/**1003* Scales a matrix by the given vector1004*1005* _param {mat4} mat mat4 to scale1006* _param {vec3} vec vec3 specifying the scale for each axis1007* _param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat1008*/1009mat4.scale = function (mat, vec, dest) {1010var x = vec[0], y = vec[1], z = vec[2];10111012if (!dest || mat === dest) {1013mat[0] *= x;1014mat[1] *= x;1015mat[2] *= x;1016mat[3] *= x;1017mat[4] *= y;1018mat[5] *= y;1019mat[6] *= y;1020mat[7] *= y;1021mat[8] *= z;1022mat[9] *= z;1023mat[10] *= z;1024mat[11] *= z;1025return mat;1026}10271028dest[0] = mat[0] * x;1029dest[1] = mat[1] * x;1030dest[2] = mat[2] * x;1031dest[3] = mat[3] * x;1032dest[4] = mat[4] * y;1033dest[5] = mat[5] * y;1034dest[6] = mat[6] * y;1035dest[7] = mat[7] * y;1036dest[8] = mat[8] * z;1037dest[9] = mat[9] * z;1038dest[10] = mat[10] * z;1039dest[11] = mat[11] * z;1040dest[12] = mat[12];1041dest[13] = mat[13];1042dest[14] = mat[14];1043dest[15] = mat[15];1044return dest;1045};10461047/**1048* Rotates a matrix by the given angle around the specified axis1049* If rotating around a primary axis (X,Y,Z) one of the specialized rotation functions should be used instead for performance1050*1051* _param {mat4} mat mat4 to rotate1052* _param {number} angle Angle (in radians) to rotate1053* _param {vec3} axis vec3 representing the axis to rotate around1054* _param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat1055*/1056mat4.rotate = function (mat, angle, axis, dest) {1057var x = axis[0], y = axis[1], z = axis[2],1058len = Math.sqrt(x * x + y * y + z * z),1059s, c, t,1060a00, a01, a02, a03,1061a10, a11, a12, a13,1062a20, a21, a22, a23,1063b00, b01, b02,1064b10, b11, b12,1065b20, b21, b22;10661067if (!len) { return null; }1068if (len !== 1) {1069len = 1 / len;1070x *= len;1071y *= len;1072z *= len;1073}10741075s = Math.sin(angle);1076c = Math.cos(angle);1077t = 1 - c;10781079a00 = mat[0]; a01 = mat[1]; a02 = mat[2]; a03 = mat[3];1080a10 = mat[4]; a11 = mat[5]; a12 = mat[6]; a13 = mat[7];1081a20 = mat[8]; a21 = mat[9]; a22 = mat[10]; a23 = mat[11];10821083// Construct the elements of the rotation matrix1084b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;1085b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;1086b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;10871088if (!dest) {1089dest = mat;1090} else if (mat !== dest) { // If the source and destination differ, copy the unchanged last row1091dest[12] = mat[12];1092dest[13] = mat[13];1093dest[14] = mat[14];1094dest[15] = mat[15];1095}10961097// Perform rotation-specific matrix multiplication1098dest[0] = a00 * b00 + a10 * b01 + a20 * b02;1099dest[1] = a01 * b00 + a11 * b01 + a21 * b02;1100dest[2] = a02 * b00 + a12 * b01 + a22 * b02;1101dest[3] = a03 * b00 + a13 * b01 + a23 * b02;11021103dest[4] = a00 * b10 + a10 * b11 + a20 * b12;1104dest[5] = a01 * b10 + a11 * b11 + a21 * b12;1105dest[6] = a02 * b10 + a12 * b11 + a22 * b12;1106dest[7] = a03 * b10 + a13 * b11 + a23 * b12;11071108dest[8] = a00 * b20 + a10 * b21 + a20 * b22;1109dest[9] = a01 * b20 + a11 * b21 + a21 * b22;1110dest[10] = a02 * b20 + a12 * b21 + a22 * b22;1111dest[11] = a03 * b20 + a13 * b21 + a23 * b22;1112return dest;1113};11141115/**1116* Rotates a matrix by the given angle around the X axis1117*1118* _param {mat4} mat mat4 to rotate1119* _param {number} angle Angle (in radians) to rotate1120* _param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat1121*/1122mat4.rotateX = function (mat, angle, dest) {1123var s = Math.sin(angle),1124c = Math.cos(angle),1125a10 = mat[4],1126a11 = mat[5],1127a12 = mat[6],1128a13 = mat[7],1129a20 = mat[8],1130a21 = mat[9],1131a22 = mat[10],1132a23 = mat[11];11331134if (!dest) {1135dest = mat;1136} else if (mat !== dest) { // If the source and destination differ, copy the unchanged rows1137dest[0] = mat[0];1138dest[1] = mat[1];1139dest[2] = mat[2];1140dest[3] = mat[3];11411142dest[12] = mat[12];1143dest[13] = mat[13];1144dest[14] = mat[14];1145dest[15] = mat[15];1146}11471148// Perform axis-specific matrix multiplication1149dest[4] = a10 * c + a20 * s;1150dest[5] = a11 * c + a21 * s;1151dest[6] = a12 * c + a22 * s;1152dest[7] = a13 * c + a23 * s;11531154dest[8] = a10 * -s + a20 * c;1155dest[9] = a11 * -s + a21 * c;1156dest[10] = a12 * -s + a22 * c;1157dest[11] = a13 * -s + a23 * c;1158return dest;1159};11601161/**1162* Rotates a matrix by the given angle around the Y axis1163*1164* _param {mat4} mat mat4 to rotate1165* _param {number} angle Angle (in radians) to rotate1166* _param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat1167*/1168mat4.rotateY = function (mat, angle, dest) {1169var s = Math.sin(angle),1170c = Math.cos(angle),1171a00 = mat[0],1172a01 = mat[1],1173a02 = mat[2],1174a03 = mat[3],1175a20 = mat[8],1176a21 = mat[9],1177a22 = mat[10],1178a23 = mat[11];11791180if (!dest) {1181dest = mat;1182} else if (mat !== dest) { // If the source and destination differ, copy the unchanged rows1183dest[4] = mat[4];1184dest[5] = mat[5];1185dest[6] = mat[6];1186dest[7] = mat[7];11871188dest[12] = mat[12];1189dest[13] = mat[13];1190dest[14] = mat[14];1191dest[15] = mat[15];1192}11931194// Perform axis-specific matrix multiplication1195dest[0] = a00 * c + a20 * -s;1196dest[1] = a01 * c + a21 * -s;1197dest[2] = a02 * c + a22 * -s;1198dest[3] = a03 * c + a23 * -s;11991200dest[8] = a00 * s + a20 * c;1201dest[9] = a01 * s + a21 * c;1202dest[10] = a02 * s + a22 * c;1203dest[11] = a03 * s + a23 * c;1204return dest;1205};12061207/**1208* Rotates a matrix by the given angle around the Z axis1209*1210* _param {mat4} mat mat4 to rotate1211* _param {number} angle Angle (in radians) to rotate1212* _param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat1213*/1214mat4.rotateZ = function (mat, angle, dest) {1215var s = Math.sin(angle),1216c = Math.cos(angle),1217a00 = mat[0],1218a01 = mat[1],1219a02 = mat[2],1220a03 = mat[3],1221a10 = mat[4],1222a11 = mat[5],1223a12 = mat[6],1224a13 = mat[7];12251226if (!dest) {1227dest = mat;1228} else if (mat !== dest) { // If the source and destination differ, copy the unchanged last row1229dest[8] = mat[8];1230dest[9] = mat[9];1231dest[10] = mat[10];1232dest[11] = mat[11];12331234dest[12] = mat[12];1235dest[13] = mat[13];1236dest[14] = mat[14];1237dest[15] = mat[15];1238}12391240// Perform axis-specific matrix multiplication1241dest[0] = a00 * c + a10 * s;1242dest[1] = a01 * c + a11 * s;1243dest[2] = a02 * c + a12 * s;1244dest[3] = a03 * c + a13 * s;12451246dest[4] = a00 * -s + a10 * c;1247dest[5] = a01 * -s + a11 * c;1248dest[6] = a02 * -s + a12 * c;1249dest[7] = a03 * -s + a13 * c;12501251return dest;1252};12531254/**1255* Generates a frustum matrix with the given bounds1256*1257* _param {number} left Left bound of the frustum1258* _param {number} right Right bound of the frustum1259* _param {number} bottom Bottom bound of the frustum1260* _param {number} top Top bound of the frustum1261* _param {number} near Near bound of the frustum1262* _param {number} far Far bound of the frustum1263* _param {mat4} [dest] mat4 frustum matrix will be written into1264*1265* _returns {mat4} dest if specified, a new mat4 otherwise1266*/1267mat4.frustum = function (left, right, bottom, top, near, far, dest) {1268if (!dest) { dest = mat4.create(); }1269var rl = (right - left),1270tb = (top - bottom),1271fn = (far - near);1272dest[0] = (near * 2) / rl;1273dest[1] = 0;1274dest[2] = 0;1275dest[3] = 0;1276dest[4] = 0;1277dest[5] = (near * 2) / tb;1278dest[6] = 0;1279dest[7] = 0;1280dest[8] = (right + left) / rl;1281dest[9] = (top + bottom) / tb;1282dest[10] = -(far + near) / fn;1283dest[11] = -1;1284dest[12] = 0;1285dest[13] = 0;1286dest[14] = -(far * near * 2) / fn;1287dest[15] = 0;1288return dest;1289};12901291/**1292* Generates a perspective projection matrix with the given bounds1293*1294* _param {number} fovy Vertical field of view1295* _param {number} aspect Aspect ratio. typically viewport width/height1296* _param {number} near Near bound of the frustum1297* _param {number} far Far bound of the frustum1298* _param {mat4} [dest] mat4 frustum matrix will be written into1299*1300* _returns {mat4} dest if specified, a new mat4 otherwise1301*/1302mat4.perspective = function (fovy, aspect, near, far, dest) {1303var top = near * Math.tan(fovy * Math.PI / 360.0),1304right = top * aspect;1305return mat4.frustum(-right, right, -top, top, near, far, dest);1306};13071308/**1309* Generates a orthogonal projection matrix with the given bounds1310*1311* _param {number} left Left bound of the frustum1312* _param {number} right Right bound of the frustum1313* _param {number} bottom Bottom bound of the frustum1314* _param {number} top Top bound of the frustum1315* _param {number} near Near bound of the frustum1316* _param {number} far Far bound of the frustum1317* _param {mat4} [dest] mat4 frustum matrix will be written into1318*1319* _returns {mat4} dest if specified, a new mat4 otherwise1320*/1321mat4.ortho = function (left, right, bottom, top, near, far, dest) {1322if (!dest) { dest = mat4.create(); }1323var rl = (right - left),1324tb = (top - bottom),1325fn = (far - near);1326dest[0] = 2 / rl;1327dest[1] = 0;1328dest[2] = 0;1329dest[3] = 0;1330dest[4] = 0;1331dest[5] = 2 / tb;1332dest[6] = 0;1333dest[7] = 0;1334dest[8] = 0;1335dest[9] = 0;1336dest[10] = -2 / fn;1337dest[11] = 0;1338dest[12] = -(left + right) / rl;1339dest[13] = -(top + bottom) / tb;1340dest[14] = -(far + near) / fn;1341dest[15] = 1;1342return dest;1343};13441345/**1346* Generates a look-at matrix with the given eye position, focal point, and up axis1347*1348* _param {vec3} eye Position of the viewer1349* _param {vec3} center Point the viewer is looking at1350* _param {vec3} up vec3 pointing "up"1351* _param {mat4} [dest] mat4 frustum matrix will be written into1352*1353* _returns {mat4} dest if specified, a new mat4 otherwise1354*/1355mat4.lookAt = function (eye, center, up, dest) {1356if (!dest) { dest = mat4.create(); }13571358var x0, x1, x2, y0, y1, y2, z0, z1, z2, len,1359eyex = eye[0],1360eyey = eye[1],1361eyez = eye[2],1362upx = up[0],1363upy = up[1],1364upz = up[2],1365centerx = center[0],1366centery = center[1],1367centerz = center[2];13681369if (eyex === centerx && eyey === centery && eyez === centerz) {1370return mat4.identity(dest);1371}13721373//vec3.direction(eye, center, z);1374z0 = eyex - centerx;1375z1 = eyey - centery;1376z2 = eyez - centerz;13771378// normalize (no check needed for 0 because of early return)1379len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);1380z0 *= len;1381z1 *= len;1382z2 *= len;13831384//vec3.normalize(vec3.cross(up, z, x));1385x0 = upy * z2 - upz * z1;1386x1 = upz * z0 - upx * z2;1387x2 = upx * z1 - upy * z0;1388len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);1389if (!len) {1390x0 = 0;1391x1 = 0;1392x2 = 0;1393} else {1394len = 1 / len;1395x0 *= len;1396x1 *= len;1397x2 *= len;1398}13991400//vec3.normalize(vec3.cross(z, x, y));1401y0 = z1 * x2 - z2 * x1;1402y1 = z2 * x0 - z0 * x2;1403y2 = z0 * x1 - z1 * x0;14041405len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);1406if (!len) {1407y0 = 0;1408y1 = 0;1409y2 = 0;1410} else {1411len = 1 / len;1412y0 *= len;1413y1 *= len;1414y2 *= len;1415}14161417dest[0] = x0;1418dest[1] = y0;1419dest[2] = z0;1420dest[3] = 0;1421dest[4] = x1;1422dest[5] = y1;1423dest[6] = z1;1424dest[7] = 0;1425dest[8] = x2;1426dest[9] = y2;1427dest[10] = z2;1428dest[11] = 0;1429dest[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);1430dest[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);1431dest[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);1432dest[15] = 1;14331434return dest;1435};14361437/**1438* Creates a matrix from a quaternion rotation and vector translation1439* This is equivalent to (but much faster than):1440*1441* mat4.identity(dest);1442* mat4.translate(dest, vec);1443* var quatMat = mat4.create();1444* quat4.toMat4(quat, quatMat);1445* mat4.multiply(dest, quatMat);1446*1447* _param {quat4} quat Rotation quaternion1448* _param {vec3} vec Translation vector1449* _param {mat4} [dest] mat4 receiving operation result. If not specified result is written to a new mat41450*1451* _returns {mat4} dest if specified, a new mat4 otherwise1452*/1453mat4.fromRotationTranslation = function (quat, vec, dest) {1454if (!dest) { dest = mat4.create(); }14551456// Quaternion math1457var x = quat[0], y = quat[1], z = quat[2], w = quat[3],1458x2 = x + x,1459y2 = y + y,1460z2 = z + z,14611462xx = x * x2,1463xy = x * y2,1464xz = x * z2,1465yy = y * y2,1466yz = y * z2,1467zz = z * z2,1468wx = w * x2,1469wy = w * y2,1470wz = w * z2;14711472dest[0] = 1 - (yy + zz);1473dest[1] = xy + wz;1474dest[2] = xz - wy;1475dest[3] = 0;1476dest[4] = xy - wz;1477dest[5] = 1 - (xx + zz);1478dest[6] = yz + wx;1479dest[7] = 0;1480dest[8] = xz + wy;1481dest[9] = yz - wx;1482dest[10] = 1 - (xx + yy);1483dest[11] = 0;1484dest[12] = vec[0];1485dest[13] = vec[1];1486dest[14] = vec[2];1487dest[15] = 1;14881489return dest;1490};14911492/**1493* Returns a string representation of a mat41494*1495* _param {mat4} mat mat4 to represent as a string1496*1497* _returns {string} String representation of mat1498*/1499mat4.str = function (mat) {1500return '[' + mat[0] + ', ' + mat[1] + ', ' + mat[2] + ', ' + mat[3] +1501', ' + mat[4] + ', ' + mat[5] + ', ' + mat[6] + ', ' + mat[7] +1502', ' + mat[8] + ', ' + mat[9] + ', ' + mat[10] + ', ' + mat[11] +1503', ' + mat[12] + ', ' + mat[13] + ', ' + mat[14] + ', ' + mat[15] + ']';1504};15051506/*1507* quat41508*/15091510/**1511* Creates a new instance of a quat4 using the default array type1512* Any javascript array containing at least 4 numeric elements can serve as a quat41513*1514* _param {quat4} [quat] quat4 containing values to initialize with1515*1516* _returns {quat4} New quat41517*/1518quat4.create = function (quat) {1519var dest = new MatrixArray(4);15201521if (quat) {1522dest[0] = quat[0];1523dest[1] = quat[1];1524dest[2] = quat[2];1525dest[3] = quat[3];1526}15271528return dest;1529};15301531/**1532* Copies the values of one quat4 to another1533*1534* _param {quat4} quat quat4 containing values to copy1535* _param {quat4} dest quat4 receiving copied values1536*1537* _returns {quat4} dest1538*/1539quat4.set = function (quat, dest) {1540dest[0] = quat[0];1541dest[1] = quat[1];1542dest[2] = quat[2];1543dest[3] = quat[3];15441545return dest;1546};15471548/**1549* Calculates the W component of a quat4 from the X, Y, and Z components.1550* Assumes that quaternion is 1 unit in length.1551* Any existing W component will be ignored.1552*1553* _param {quat4} quat quat4 to calculate W component of1554* _param {quat4} [dest] quat4 receiving calculated values. If not specified result is written to quat1555*1556* _returns {quat4} dest if specified, quat otherwise1557*/1558quat4.calculateW = function (quat, dest) {1559var x = quat[0], y = quat[1], z = quat[2];15601561if (!dest || quat === dest) {1562quat[3] = -Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));1563return quat;1564}1565dest[0] = x;1566dest[1] = y;1567dest[2] = z;1568dest[3] = -Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));1569return dest;1570};15711572/**1573* Calculates the dot product of two quaternions1574*1575* _param {quat4} quat First operand1576* _param {quat4} quat2 Second operand1577*1578* @return {number} Dot product of quat and quat21579*/1580quat4.dot = function(quat, quat2){1581return quat[0]*quat2[0] + quat[1]*quat2[1] + quat[2]*quat2[2] + quat[3]*quat2[3];1582};15831584/**1585* Calculates the inverse of a quat41586*1587* _param {quat4} quat quat4 to calculate inverse of1588* _param {quat4} [dest] quat4 receiving inverse values. If not specified result is written to quat1589*1590* _returns {quat4} dest if specified, quat otherwise1591*/1592quat4.inverse = function(quat, dest) {1593var q0 = quat[0], q1 = quat[1], q2 = quat[2], q3 = quat[3],1594dot = q0*q0 + q1*q1 + q2*q2 + q3*q3,1595invDot = dot ? 1.0/dot : 0;15961597// TODO: Would be faster to return [0,0,0,0] immediately if dot == 015981599if(!dest || quat === dest) {1600quat[0] *= -invDot;1601quat[1] *= -invDot;1602quat[2] *= -invDot;1603quat[3] *= invDot;1604return quat;1605}1606dest[0] = -quat[0]*invDot;1607dest[1] = -quat[1]*invDot;1608dest[2] = -quat[2]*invDot;1609dest[3] = quat[3]*invDot;1610return dest;1611};161216131614/**1615* Calculates the conjugate of a quat41616* If the quaternion is normalized, this function is faster than quat4.inverse and produces the same result.1617*1618* _param {quat4} quat quat4 to calculate conjugate of1619* _param {quat4} [dest] quat4 receiving conjugate values. If not specified result is written to quat1620*1621* _returns {quat4} dest if specified, quat otherwise1622*/1623quat4.conjugate = function (quat, dest) {1624if (!dest || quat === dest) {1625quat[0] *= -1;1626quat[1] *= -1;1627quat[2] *= -1;1628return quat;1629}1630dest[0] = -quat[0];1631dest[1] = -quat[1];1632dest[2] = -quat[2];1633dest[3] = quat[3];1634return dest;1635};16361637/**1638* Calculates the length of a quat41639*1640* Params:1641* _param {quat4} quat quat4 to calculate length of1642*1643* _returns Length of quat1644*/1645quat4.length = function (quat) {1646var x = quat[0], y = quat[1], z = quat[2], w = quat[3];1647return Math.sqrt(x * x + y * y + z * z + w * w);1648};16491650/**1651* Generates a unit quaternion of the same direction as the provided quat41652* If quaternion length is 0, returns [0, 0, 0, 0]1653*1654* _param {quat4} quat quat4 to normalize1655* _param {quat4} [dest] quat4 receiving operation result. If not specified result is written to quat1656*1657* _returns {quat4} dest if specified, quat otherwise1658*/1659quat4.normalize = function (quat, dest) {1660if (!dest) { dest = quat; }16611662var x = quat[0], y = quat[1], z = quat[2], w = quat[3],1663len = Math.sqrt(x * x + y * y + z * z + w * w);1664if (len === 0) {1665dest[0] = 0;1666dest[1] = 0;1667dest[2] = 0;1668dest[3] = 0;1669return dest;1670}1671len = 1 / len;1672dest[0] = x * len;1673dest[1] = y * len;1674dest[2] = z * len;1675dest[3] = w * len;16761677return dest;1678};16791680/**1681* Performs quaternion addition1682*1683* _param {quat4} quat First operand1684* _param {quat4} quat2 Second operand1685* _param {quat4} [dest] quat4 receiving operation result. If not specified result is written to quat1686*1687* _returns {quat4} dest if specified, quat otherwise1688*/1689quat4.add = function (quat, quat2, dest) {1690if(!dest || quat === dest) {1691quat[0] += quat2[0];1692quat[1] += quat2[1];1693quat[2] += quat2[2];1694quat[3] += quat2[3];1695return quat;1696}1697dest[0] = quat[0]+quat2[0];1698dest[1] = quat[1]+quat2[1];1699dest[2] = quat[2]+quat2[2];1700dest[3] = quat[3]+quat2[3];1701return dest;1702};17031704/**1705* Performs a quaternion multiplication1706*1707* _param {quat4} quat First operand1708* _param {quat4} quat2 Second operand1709* _param {quat4} [dest] quat4 receiving operation result. If not specified result is written to quat1710*1711* _returns {quat4} dest if specified, quat otherwise1712*/1713quat4.multiply = function (quat, quat2, dest) {1714if (!dest) { dest = quat; }17151716var qax = quat[0], qay = quat[1], qaz = quat[2], qaw = quat[3],1717qbx = quat2[0], qby = quat2[1], qbz = quat2[2], qbw = quat2[3];17181719dest[0] = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;1720dest[1] = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;1721dest[2] = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;1722dest[3] = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;17231724return dest;1725};17261727/**1728* Transforms a vec3 with the given quaternion1729*1730* _param {quat4} quat quat4 to transform the vector with1731* _param {vec3} vec vec3 to transform1732* _param {vec3} [dest] vec3 receiving operation result. If not specified result is written to vec1733*1734* _returns dest if specified, vec otherwise1735*/1736quat4.multiplyVec3 = function (quat, vec, dest) {1737if (!dest) { dest = vec; }17381739var x = vec[0], y = vec[1], z = vec[2],1740qx = quat[0], qy = quat[1], qz = quat[2], qw = quat[3],17411742// calculate quat * vec1743ix = qw * x + qy * z - qz * y,1744iy = qw * y + qz * x - qx * z,1745iz = qw * z + qx * y - qy * x,1746iw = -qx * x - qy * y - qz * z;17471748// calculate result * inverse quat1749dest[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;1750dest[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;1751dest[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;17521753return dest;1754};17551756/**1757* Multiplies the components of a quaternion by a scalar value1758*1759* _param {quat4} quat to scale1760* _param {number} val Value to scale by1761* _param {quat4} [dest] quat4 receiving operation result. If not specified result is written to quat1762*1763* _returns {quat4} dest if specified, quat otherwise1764*/1765quat4.scale = function (quat, val, dest) {1766if(!dest || quat === dest) {1767quat[0] *= val;1768quat[1] *= val;1769quat[2] *= val;1770quat[3] *= val;1771return quat;1772}1773dest[0] = quat[0]*val;1774dest[1] = quat[1]*val;1775dest[2] = quat[2]*val;1776dest[3] = quat[3]*val;1777return dest;1778};17791780/**1781* Calculates a 3x3 matrix from the given quat41782*1783* _param {quat4} quat quat4 to create matrix from1784* _param {mat3} [dest] mat3 receiving operation result1785*1786* _returns {mat3} dest if specified, a new mat3 otherwise1787*/1788quat4.toMat3 = function (quat, dest) {1789if (!dest) { dest = mat3.create(); }17901791var x = quat[0], y = quat[1], z = quat[2], w = quat[3],1792x2 = x + x,1793y2 = y + y,1794z2 = z + z,17951796xx = x * x2,1797xy = x * y2,1798xz = x * z2,1799yy = y * y2,1800yz = y * z2,1801zz = z * z2,1802wx = w * x2,1803wy = w * y2,1804wz = w * z2;18051806dest[0] = 1 - (yy + zz);1807dest[1] = xy + wz;1808dest[2] = xz - wy;18091810dest[3] = xy - wz;1811dest[4] = 1 - (xx + zz);1812dest[5] = yz + wx;18131814dest[6] = xz + wy;1815dest[7] = yz - wx;1816dest[8] = 1 - (xx + yy);18171818return dest;1819};18201821/**1822* Calculates a 4x4 matrix from the given quat41823*1824* _param {quat4} quat quat4 to create matrix from1825* _param {mat4} [dest] mat4 receiving operation result1826*1827* _returns {mat4} dest if specified, a new mat4 otherwise1828*/1829quat4.toMat4 = function (quat, dest) {1830if (!dest) { dest = mat4.create(); }18311832var x = quat[0], y = quat[1], z = quat[2], w = quat[3],1833x2 = x + x,1834y2 = y + y,1835z2 = z + z,18361837xx = x * x2,1838xy = x * y2,1839xz = x * z2,1840yy = y * y2,1841yz = y * z2,1842zz = z * z2,1843wx = w * x2,1844wy = w * y2,1845wz = w * z2;18461847dest[0] = 1 - (yy + zz);1848dest[1] = xy + wz;1849dest[2] = xz - wy;1850dest[3] = 0;18511852dest[4] = xy - wz;1853dest[5] = 1 - (xx + zz);1854dest[6] = yz + wx;1855dest[7] = 0;18561857dest[8] = xz + wy;1858dest[9] = yz - wx;1859dest[10] = 1 - (xx + yy);1860dest[11] = 0;18611862dest[12] = 0;1863dest[13] = 0;1864dest[14] = 0;1865dest[15] = 1;18661867return dest;1868};18691870/**1871* Performs a spherical linear interpolation between two quat41872*1873* _param {quat4} quat First quaternion1874* _param {quat4} quat2 Second quaternion1875* _param {number} slerp Interpolation amount between the two inputs1876* _param {quat4} [dest] quat4 receiving operation result. If not specified result is written to quat1877*1878* _returns {quat4} dest if specified, quat otherwise1879*/1880quat4.slerp = function (quat, quat2, slerp, dest) {1881if (!dest) { dest = quat; }18821883var cosHalfTheta = quat[0] * quat2[0] + quat[1] * quat2[1] + quat[2] * quat2[2] + quat[3] * quat2[3],1884halfTheta,1885sinHalfTheta,1886ratioA,1887ratioB;18881889if (Math.abs(cosHalfTheta) >= 1.0) {1890if (dest !== quat) {1891dest[0] = quat[0];1892dest[1] = quat[1];1893dest[2] = quat[2];1894dest[3] = quat[3];1895}1896return dest;1897}18981899halfTheta = Math.acos(cosHalfTheta);1900sinHalfTheta = Math.sqrt(1.0 - cosHalfTheta * cosHalfTheta);19011902if (Math.abs(sinHalfTheta) < 0.001) {1903dest[0] = (quat[0] * 0.5 + quat2[0] * 0.5);1904dest[1] = (quat[1] * 0.5 + quat2[1] * 0.5);1905dest[2] = (quat[2] * 0.5 + quat2[2] * 0.5);1906dest[3] = (quat[3] * 0.5 + quat2[3] * 0.5);1907return dest;1908}19091910ratioA = Math.sin((1 - slerp) * halfTheta) / sinHalfTheta;1911ratioB = Math.sin(slerp * halfTheta) / sinHalfTheta;19121913dest[0] = (quat[0] * ratioA + quat2[0] * ratioB);1914dest[1] = (quat[1] * ratioA + quat2[1] * ratioB);1915dest[2] = (quat[2] * ratioA + quat2[2] * ratioB);1916dest[3] = (quat[3] * ratioA + quat2[3] * ratioB);19171918return dest;1919};19201921/**1922* Returns a string representation of a quaternion1923*1924* _param {quat4} quat quat4 to represent as a string1925*1926* _returns {string} String representation of quat1927*/1928quat4.str = function (quat) {1929return '[' + quat[0] + ', ' + quat[1] + ', ' + quat[2] + ', ' + quat[3] + ']';1930};193119321933return {1934vec3: vec3,1935mat3: mat3,1936mat4: mat4,1937quat4: quat41938};19391940})();1941194219431944