From d915e9e92c12456d39c9ca0337cb6a0599bb853f Mon Sep 17 00:00:00 2001 From: Brulijam Date: Fri, 24 Nov 2023 21:30:05 +0100 Subject: [PATCH] added pdfs, task 1, task 2 --- index.html | 5 +- Übung_23112023/ToDo_Liste_Woche_6.pdf | Bin 0 -> 136648 bytes Übung_23112023/aufgabe1/common/Object3D.js | 408 + Übung_23112023/aufgabe1/common/gl-matrix.js | 7861 +++++++++++++++++ Übung_23112023/aufgabe1/common/initShaders.js | 48 + Übung_23112023/aufgabe1/index.html | 56 + Übung_23112023/aufgabe1/main.js | 62 + Übung_23112023/aufgabe2/common/Object3D.js | 408 + Übung_23112023/aufgabe2/common/gl-matrix.js | 7861 +++++++++++++++++ Übung_23112023/aufgabe2/common/initShaders.js | 48 + Übung_23112023/aufgabe2/index.html | 56 + Übung_23112023/aufgabe2/main.js | 71 + Übung_23112023/uebung-woche6.pdf | Bin 0 -> 573919 bytes 13 files changed, 16881 insertions(+), 3 deletions(-) create mode 100644 Übung_23112023/ToDo_Liste_Woche_6.pdf create mode 100644 Übung_23112023/aufgabe1/common/Object3D.js create mode 100644 Übung_23112023/aufgabe1/common/gl-matrix.js create mode 100644 Übung_23112023/aufgabe1/common/initShaders.js create mode 100644 Übung_23112023/aufgabe1/index.html create mode 100644 Übung_23112023/aufgabe1/main.js create mode 100644 Übung_23112023/aufgabe2/common/Object3D.js create mode 100644 Übung_23112023/aufgabe2/common/gl-matrix.js create mode 100644 Übung_23112023/aufgabe2/common/initShaders.js create mode 100644 Übung_23112023/aufgabe2/index.html create mode 100644 Übung_23112023/aufgabe2/main.js create mode 100644 Übung_23112023/uebung-woche6.pdf diff --git a/index.html b/index.html index dcb28af..d8d5fbc 100644 --- a/index.html +++ b/index.html @@ -5,8 +5,7 @@ -

This is a Heading

-

This is a paragraph.

+Übung_23112023/
- \ No newline at end of file + diff --git a/Übung_23112023/ToDo_Liste_Woche_6.pdf b/Übung_23112023/ToDo_Liste_Woche_6.pdf new file mode 100644 index 0000000000000000000000000000000000000000..230609b2cb5dd2a407a1168f8e251ce0abe0adf4 GIT binary patch literal 136648 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 additional for waterfall + 4.0, -6.0, 0.0 // index 18 -> additional for waterfall + ]; + + this.indices = [ + 0, 1, 2, + 1, 2, 3, + 2, 3, 4, + 3, 4, 5, + 4, 5, 6, + 5, 6, 7, + 6, 7, 8, + 7, 8, 9, + 8, 9, 10, + 9, 10, 11, + 10, 11, 12, + 11, 12, 13, + 12, 13, 14, + 13, 14, 15, + 14, 15, 16, + 15, 16, 17, // additional for waterfall + 16, 17, 18 // additional for waterfall + ]; + + this.colors = []; + for(let i = 0; i < this.positions.length; i += 3) { + this.colors.push(0.2, 0.2, 0.8, 1); + } + + this.InitBuffers(); + } +} diff --git a/Übung_23112023/aufgabe1/common/gl-matrix.js b/Übung_23112023/aufgabe1/common/gl-matrix.js new file mode 100644 index 0000000..0799c59 --- /dev/null +++ b/Übung_23112023/aufgabe1/common/gl-matrix.js @@ -0,0 +1,7861 @@ + +/*! +@fileoverview gl-matrix - High performance matrix and vector operations +@author Brandon Jones +@author Colin MacKenzie IV +@version 3.4.0 + +Copyright (c) 2015-2021, Brandon Jones, Colin MacKenzie IV. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.glMatrix = {})); + })(this, (function (exports) { 'use strict'; + + /** + * Common utilities + * @module glMatrix + */ + // Configuration Constants + var EPSILON = 0.000001; + var ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array; + var RANDOM = Math.random; + var ANGLE_ORDER = "zyx"; + /** + * Sets the type of array used when creating new vectors and matrices + * + * @param {Float32ArrayConstructor | ArrayConstructor} type Array type, such as Float32Array or Array + */ + + function setMatrixArrayType(type) { + ARRAY_TYPE = type; + } + var degree = Math.PI / 180; + /** + * Convert Degree To Radian + * + * @param {Number} a Angle in Degrees + */ + + function toRadian(a) { + return a * degree; + } + /** + * Tests whether or not the arguments have approximately the same value, within an absolute + * or relative tolerance of glMatrix.EPSILON (an absolute tolerance is used for values less + * than or equal to 1.0, and a relative tolerance is used for larger values) + * + * @param {Number} a The first number to test. + * @param {Number} b The second number to test. + * @returns {Boolean} True if the numbers are approximately equal, false otherwise. + */ + + function equals$9(a, b) { + return Math.abs(a - b) <= EPSILON * Math.max(1.0, Math.abs(a), Math.abs(b)); + } + if (!Math.hypot) Math.hypot = function () { + var y = 0, + i = arguments.length; + + while (i--) { + y += arguments[i] * arguments[i]; + } + + return Math.sqrt(y); + }; + + var common = /*#__PURE__*/Object.freeze({ + __proto__: null, + EPSILON: EPSILON, + get ARRAY_TYPE () { return ARRAY_TYPE; }, + RANDOM: RANDOM, + ANGLE_ORDER: ANGLE_ORDER, + setMatrixArrayType: setMatrixArrayType, + toRadian: toRadian, + equals: equals$9 + }); + + /** + * 2x2 Matrix + * @module mat2 + */ + + /** + * Creates a new identity mat2 + * + * @returns {mat2} a new 2x2 matrix + */ + + function create$8() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + } + + out[0] = 1; + out[3] = 1; + return out; + } + /** + * Creates a new mat2 initialized with values from an existing matrix + * + * @param {ReadonlyMat2} a matrix to clone + * @returns {mat2} a new 2x2 matrix + */ + + function clone$8(a) { + var out = new ARRAY_TYPE(4); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Copy the values from one mat2 to another + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the source matrix + * @returns {mat2} out + */ + + function copy$8(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Set a mat2 to the identity matrix + * + * @param {mat2} out the receiving matrix + * @returns {mat2} out + */ + + function identity$5(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } + /** + * Create a new mat2 with the given values + * + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m10 Component in column 1, row 0 position (index 2) + * @param {Number} m11 Component in column 1, row 1 position (index 3) + * @returns {mat2} out A new 2x2 matrix + */ + + function fromValues$8(m00, m01, m10, m11) { + var out = new ARRAY_TYPE(4); + out[0] = m00; + out[1] = m01; + out[2] = m10; + out[3] = m11; + return out; + } + /** + * Set the components of a mat2 to the given values + * + * @param {mat2} out the receiving matrix + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m10 Component in column 1, row 0 position (index 2) + * @param {Number} m11 Component in column 1, row 1 position (index 3) + * @returns {mat2} out + */ + + function set$8(out, m00, m01, m10, m11) { + out[0] = m00; + out[1] = m01; + out[2] = m10; + out[3] = m11; + return out; + } + /** + * Transpose the values of a mat2 + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the source matrix + * @returns {mat2} out + */ + + function transpose$2(out, a) { + // If we are transposing ourselves we can skip a few steps but have to cache + // some values + if (out === a) { + var a1 = a[1]; + out[1] = a[2]; + out[2] = a1; + } else { + out[0] = a[0]; + out[1] = a[2]; + out[2] = a[1]; + out[3] = a[3]; + } + + return out; + } + /** + * Inverts a mat2 + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the source matrix + * @returns {mat2} out + */ + + function invert$5(out, a) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; // Calculate the determinant + + var det = a0 * a3 - a2 * a1; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = a3 * det; + out[1] = -a1 * det; + out[2] = -a2 * det; + out[3] = a0 * det; + return out; + } + /** + * Calculates the adjugate of a mat2 + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the source matrix + * @returns {mat2} out + */ + + function adjoint$2(out, a) { + // Caching this value is necessary if out == a + var a0 = a[0]; + out[0] = a[3]; + out[1] = -a[1]; + out[2] = -a[2]; + out[3] = a0; + return out; + } + /** + * Calculates the determinant of a mat2 + * + * @param {ReadonlyMat2} a the source matrix + * @returns {Number} determinant of a + */ + + function determinant$3(a) { + return a[0] * a[3] - a[2] * a[1]; + } + /** + * Multiplies two mat2's + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand + * @returns {mat2} out + */ + + function multiply$8(out, a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + out[0] = a0 * b0 + a2 * b1; + out[1] = a1 * b0 + a3 * b1; + out[2] = a0 * b2 + a2 * b3; + out[3] = a1 * b2 + a3 * b3; + return out; + } + /** + * Rotates a mat2 by the given angle + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2} out + */ + + function rotate$4(out, a, rad) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var s = Math.sin(rad); + var c = Math.cos(rad); + out[0] = a0 * c + a2 * s; + out[1] = a1 * c + a3 * s; + out[2] = a0 * -s + a2 * c; + out[3] = a1 * -s + a3 * c; + return out; + } + /** + * Scales the mat2 by the dimensions in the given vec2 + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the matrix to rotate + * @param {ReadonlyVec2} v the vec2 to scale the matrix by + * @returns {mat2} out + **/ + + function scale$8(out, a, v) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var v0 = v[0], + v1 = v[1]; + out[0] = a0 * v0; + out[1] = a1 * v0; + out[2] = a2 * v1; + out[3] = a3 * v1; + return out; + } + /** + * Creates a matrix from a given angle + * This is equivalent to (but much faster than): + * + * mat2.identity(dest); + * mat2.rotate(dest, dest, rad); + * + * @param {mat2} out mat2 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2} out + */ + + function fromRotation$4(out, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + out[0] = c; + out[1] = s; + out[2] = -s; + out[3] = c; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat2.identity(dest); + * mat2.scale(dest, dest, vec); + * + * @param {mat2} out mat2 receiving operation result + * @param {ReadonlyVec2} v Scaling vector + * @returns {mat2} out + */ + + function fromScaling$3(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = v[1]; + return out; + } + /** + * Returns a string representation of a mat2 + * + * @param {ReadonlyMat2} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ + + function str$8(a) { + return "mat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; + } + /** + * Returns Frobenius norm of a mat2 + * + * @param {ReadonlyMat2} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ + + function frob$3(a) { + return Math.hypot(a[0], a[1], a[2], a[3]); + } + /** + * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix + * @param {ReadonlyMat2} L the lower triangular matrix + * @param {ReadonlyMat2} D the diagonal matrix + * @param {ReadonlyMat2} U the upper triangular matrix + * @param {ReadonlyMat2} a the input matrix to factorize + */ + + function LDU(L, D, U, a) { + L[2] = a[2] / a[0]; + U[0] = a[0]; + U[1] = a[1]; + U[3] = a[3] - L[2] * U[1]; + return [L, D, U]; + } + /** + * Adds two mat2's + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand + * @returns {mat2} out + */ + + function add$8(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand + * @returns {mat2} out + */ + + function subtract$6(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyMat2} a The first matrix. + * @param {ReadonlyMat2} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function exactEquals$8(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {ReadonlyMat2} a The first matrix. + * @param {ReadonlyMat2} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function equals$8(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)); + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat2} out + */ + + function multiplyScalar$3(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + return out; + } + /** + * Adds two mat2's after multiplying each element of the second operand by a scalar value. + * + * @param {mat2} out the receiving vector + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat2} out + */ + + function multiplyScalarAndAdd$3(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + return out; + } + /** + * Alias for {@link mat2.multiply} + * @function + */ + + var mul$8 = multiply$8; + /** + * Alias for {@link mat2.subtract} + * @function + */ + + var sub$6 = subtract$6; + + var mat2 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$8, + clone: clone$8, + copy: copy$8, + identity: identity$5, + fromValues: fromValues$8, + set: set$8, + transpose: transpose$2, + invert: invert$5, + adjoint: adjoint$2, + determinant: determinant$3, + multiply: multiply$8, + rotate: rotate$4, + scale: scale$8, + fromRotation: fromRotation$4, + fromScaling: fromScaling$3, + str: str$8, + frob: frob$3, + LDU: LDU, + add: add$8, + subtract: subtract$6, + exactEquals: exactEquals$8, + equals: equals$8, + multiplyScalar: multiplyScalar$3, + multiplyScalarAndAdd: multiplyScalarAndAdd$3, + mul: mul$8, + sub: sub$6 + }); + + /** + * 2x3 Matrix + * @module mat2d + * @description + * A mat2d contains six elements defined as: + *
+     * [a, b,
+     *  c, d,
+     *  tx, ty]
+     * 
+ * This is a short form for the 3x3 matrix: + *
+     * [a, b, 0,
+     *  c, d, 0,
+     *  tx, ty, 1]
+     * 
+ * The last column is ignored so the array is shorter and operations are faster. + */ + + /** + * Creates a new identity mat2d + * + * @returns {mat2d} a new 2x3 matrix + */ + + function create$7() { + var out = new ARRAY_TYPE(6); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[4] = 0; + out[5] = 0; + } + + out[0] = 1; + out[3] = 1; + return out; + } + /** + * Creates a new mat2d initialized with values from an existing matrix + * + * @param {ReadonlyMat2d} a matrix to clone + * @returns {mat2d} a new 2x3 matrix + */ + + function clone$7(a) { + var out = new ARRAY_TYPE(6); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + return out; + } + /** + * Copy the values from one mat2d to another + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the source matrix + * @returns {mat2d} out + */ + + function copy$7(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + return out; + } + /** + * Set a mat2d to the identity matrix + * + * @param {mat2d} out the receiving matrix + * @returns {mat2d} out + */ + + function identity$4(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = 0; + out[5] = 0; + return out; + } + /** + * Create a new mat2d with the given values + * + * @param {Number} a Component A (index 0) + * @param {Number} b Component B (index 1) + * @param {Number} c Component C (index 2) + * @param {Number} d Component D (index 3) + * @param {Number} tx Component TX (index 4) + * @param {Number} ty Component TY (index 5) + * @returns {mat2d} A new mat2d + */ + + function fromValues$7(a, b, c, d, tx, ty) { + var out = new ARRAY_TYPE(6); + out[0] = a; + out[1] = b; + out[2] = c; + out[3] = d; + out[4] = tx; + out[5] = ty; + return out; + } + /** + * Set the components of a mat2d to the given values + * + * @param {mat2d} out the receiving matrix + * @param {Number} a Component A (index 0) + * @param {Number} b Component B (index 1) + * @param {Number} c Component C (index 2) + * @param {Number} d Component D (index 3) + * @param {Number} tx Component TX (index 4) + * @param {Number} ty Component TY (index 5) + * @returns {mat2d} out + */ + + function set$7(out, a, b, c, d, tx, ty) { + out[0] = a; + out[1] = b; + out[2] = c; + out[3] = d; + out[4] = tx; + out[5] = ty; + return out; + } + /** + * Inverts a mat2d + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the source matrix + * @returns {mat2d} out + */ + + function invert$4(out, a) { + var aa = a[0], + ab = a[1], + ac = a[2], + ad = a[3]; + var atx = a[4], + aty = a[5]; + var det = aa * ad - ab * ac; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = ad * det; + out[1] = -ab * det; + out[2] = -ac * det; + out[3] = aa * det; + out[4] = (ac * aty - ad * atx) * det; + out[5] = (ab * atx - aa * aty) * det; + return out; + } + /** + * Calculates the determinant of a mat2d + * + * @param {ReadonlyMat2d} a the source matrix + * @returns {Number} determinant of a + */ + + function determinant$2(a) { + return a[0] * a[3] - a[1] * a[2]; + } + /** + * Multiplies two mat2d's + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the first operand + * @param {ReadonlyMat2d} b the second operand + * @returns {mat2d} out + */ + + function multiply$7(out, a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5]; + out[0] = a0 * b0 + a2 * b1; + out[1] = a1 * b0 + a3 * b1; + out[2] = a0 * b2 + a2 * b3; + out[3] = a1 * b2 + a3 * b3; + out[4] = a0 * b4 + a2 * b5 + a4; + out[5] = a1 * b4 + a3 * b5 + a5; + return out; + } + /** + * Rotates a mat2d by the given angle + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2d} out + */ + + function rotate$3(out, a, rad) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var s = Math.sin(rad); + var c = Math.cos(rad); + out[0] = a0 * c + a2 * s; + out[1] = a1 * c + a3 * s; + out[2] = a0 * -s + a2 * c; + out[3] = a1 * -s + a3 * c; + out[4] = a4; + out[5] = a5; + return out; + } + /** + * Scales the mat2d by the dimensions in the given vec2 + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the matrix to translate + * @param {ReadonlyVec2} v the vec2 to scale the matrix by + * @returns {mat2d} out + **/ + + function scale$7(out, a, v) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var v0 = v[0], + v1 = v[1]; + out[0] = a0 * v0; + out[1] = a1 * v0; + out[2] = a2 * v1; + out[3] = a3 * v1; + out[4] = a4; + out[5] = a5; + return out; + } + /** + * Translates the mat2d by the dimensions in the given vec2 + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the matrix to translate + * @param {ReadonlyVec2} v the vec2 to translate the matrix by + * @returns {mat2d} out + **/ + + function translate$3(out, a, v) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var v0 = v[0], + v1 = v[1]; + out[0] = a0; + out[1] = a1; + out[2] = a2; + out[3] = a3; + out[4] = a0 * v0 + a2 * v1 + a4; + out[5] = a1 * v0 + a3 * v1 + a5; + return out; + } + /** + * Creates a matrix from a given angle + * This is equivalent to (but much faster than): + * + * mat2d.identity(dest); + * mat2d.rotate(dest, dest, rad); + * + * @param {mat2d} out mat2d receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2d} out + */ + + function fromRotation$3(out, rad) { + var s = Math.sin(rad), + c = Math.cos(rad); + out[0] = c; + out[1] = s; + out[2] = -s; + out[3] = c; + out[4] = 0; + out[5] = 0; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat2d.identity(dest); + * mat2d.scale(dest, dest, vec); + * + * @param {mat2d} out mat2d receiving operation result + * @param {ReadonlyVec2} v Scaling vector + * @returns {mat2d} out + */ + + function fromScaling$2(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = v[1]; + out[4] = 0; + out[5] = 0; + return out; + } + /** + * Creates a matrix from a vector translation + * This is equivalent to (but much faster than): + * + * mat2d.identity(dest); + * mat2d.translate(dest, dest, vec); + * + * @param {mat2d} out mat2d receiving operation result + * @param {ReadonlyVec2} v Translation vector + * @returns {mat2d} out + */ + + function fromTranslation$3(out, v) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = v[0]; + out[5] = v[1]; + return out; + } + /** + * Returns a string representation of a mat2d + * + * @param {ReadonlyMat2d} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ + + function str$7(a) { + return "mat2d(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ")"; + } + /** + * Returns Frobenius norm of a mat2d + * + * @param {ReadonlyMat2d} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ + + function frob$2(a) { + return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], 1); + } + /** + * Adds two mat2d's + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the first operand + * @param {ReadonlyMat2d} b the second operand + * @returns {mat2d} out + */ + + function add$7(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the first operand + * @param {ReadonlyMat2d} b the second operand + * @returns {mat2d} out + */ + + function subtract$5(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + out[4] = a[4] - b[4]; + out[5] = a[5] - b[5]; + return out; + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat2d} out + */ + + function multiplyScalar$2(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + out[4] = a[4] * b; + out[5] = a[5] * b; + return out; + } + /** + * Adds two mat2d's after multiplying each element of the second operand by a scalar value. + * + * @param {mat2d} out the receiving vector + * @param {ReadonlyMat2d} a the first operand + * @param {ReadonlyMat2d} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat2d} out + */ + + function multiplyScalarAndAdd$2(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + out[4] = a[4] + b[4] * scale; + out[5] = a[5] + b[5] * scale; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyMat2d} a The first matrix. + * @param {ReadonlyMat2d} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function exactEquals$7(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {ReadonlyMat2d} a The first matrix. + * @param {ReadonlyMat2d} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function equals$7(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)); + } + /** + * Alias for {@link mat2d.multiply} + * @function + */ + + var mul$7 = multiply$7; + /** + * Alias for {@link mat2d.subtract} + * @function + */ + + var sub$5 = subtract$5; + + var mat2d = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$7, + clone: clone$7, + copy: copy$7, + identity: identity$4, + fromValues: fromValues$7, + set: set$7, + invert: invert$4, + determinant: determinant$2, + multiply: multiply$7, + rotate: rotate$3, + scale: scale$7, + translate: translate$3, + fromRotation: fromRotation$3, + fromScaling: fromScaling$2, + fromTranslation: fromTranslation$3, + str: str$7, + frob: frob$2, + add: add$7, + subtract: subtract$5, + multiplyScalar: multiplyScalar$2, + multiplyScalarAndAdd: multiplyScalarAndAdd$2, + exactEquals: exactEquals$7, + equals: equals$7, + mul: mul$7, + sub: sub$5 + }); + + /** + * 3x3 Matrix + * @module mat3 + */ + + /** + * Creates a new identity mat3 + * + * @returns {mat3} a new 3x3 matrix + */ + + function create$6() { + var out = new ARRAY_TYPE(9); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + } + + out[0] = 1; + out[4] = 1; + out[8] = 1; + return out; + } + /** + * Copies the upper-left 3x3 values into the given mat3. + * + * @param {mat3} out the receiving 3x3 matrix + * @param {ReadonlyMat4} a the source 4x4 matrix + * @returns {mat3} out + */ + + function fromMat4$1(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[4]; + out[4] = a[5]; + out[5] = a[6]; + out[6] = a[8]; + out[7] = a[9]; + out[8] = a[10]; + return out; + } + /** + * Creates a new mat3 initialized with values from an existing matrix + * + * @param {ReadonlyMat3} a matrix to clone + * @returns {mat3} a new 3x3 matrix + */ + + function clone$6(a) { + var out = new ARRAY_TYPE(9); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + return out; + } + /** + * Copy the values from one mat3 to another + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + + function copy$6(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + return out; + } + /** + * Create a new mat3 with the given values + * + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m10 Component in column 1, row 0 position (index 3) + * @param {Number} m11 Component in column 1, row 1 position (index 4) + * @param {Number} m12 Component in column 1, row 2 position (index 5) + * @param {Number} m20 Component in column 2, row 0 position (index 6) + * @param {Number} m21 Component in column 2, row 1 position (index 7) + * @param {Number} m22 Component in column 2, row 2 position (index 8) + * @returns {mat3} A new mat3 + */ + + function fromValues$6(m00, m01, m02, m10, m11, m12, m20, m21, m22) { + var out = new ARRAY_TYPE(9); + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m10; + out[4] = m11; + out[5] = m12; + out[6] = m20; + out[7] = m21; + out[8] = m22; + return out; + } + /** + * Set the components of a mat3 to the given values + * + * @param {mat3} out the receiving matrix + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m10 Component in column 1, row 0 position (index 3) + * @param {Number} m11 Component in column 1, row 1 position (index 4) + * @param {Number} m12 Component in column 1, row 2 position (index 5) + * @param {Number} m20 Component in column 2, row 0 position (index 6) + * @param {Number} m21 Component in column 2, row 1 position (index 7) + * @param {Number} m22 Component in column 2, row 2 position (index 8) + * @returns {mat3} out + */ + + function set$6(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) { + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m10; + out[4] = m11; + out[5] = m12; + out[6] = m20; + out[7] = m21; + out[8] = m22; + return out; + } + /** + * Set a mat3 to the identity matrix + * + * @param {mat3} out the receiving matrix + * @returns {mat3} out + */ + + function identity$3(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 1; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 1; + return out; + } + /** + * Transpose the values of a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + + function transpose$1(out, a) { + // If we are transposing ourselves we can skip a few steps but have to cache some values + if (out === a) { + var a01 = a[1], + a02 = a[2], + a12 = a[5]; + out[1] = a[3]; + out[2] = a[6]; + out[3] = a01; + out[5] = a[7]; + out[6] = a02; + out[7] = a12; + } else { + out[0] = a[0]; + out[1] = a[3]; + out[2] = a[6]; + out[3] = a[1]; + out[4] = a[4]; + out[5] = a[7]; + out[6] = a[2]; + out[7] = a[5]; + out[8] = a[8]; + } + + return out; + } + /** + * Inverts a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + + function invert$3(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + var b01 = a22 * a11 - a12 * a21; + var b11 = -a22 * a10 + a12 * a20; + var b21 = a21 * a10 - a11 * a20; // Calculate the determinant + + var det = a00 * b01 + a01 * b11 + a02 * b21; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = b01 * det; + out[1] = (-a22 * a01 + a02 * a21) * det; + out[2] = (a12 * a01 - a02 * a11) * det; + out[3] = b11 * det; + out[4] = (a22 * a00 - a02 * a20) * det; + out[5] = (-a12 * a00 + a02 * a10) * det; + out[6] = b21 * det; + out[7] = (-a21 * a00 + a01 * a20) * det; + out[8] = (a11 * a00 - a01 * a10) * det; + return out; + } + /** + * Calculates the adjugate of a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + + function adjoint$1(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + out[0] = a11 * a22 - a12 * a21; + out[1] = a02 * a21 - a01 * a22; + out[2] = a01 * a12 - a02 * a11; + out[3] = a12 * a20 - a10 * a22; + out[4] = a00 * a22 - a02 * a20; + out[5] = a02 * a10 - a00 * a12; + out[6] = a10 * a21 - a11 * a20; + out[7] = a01 * a20 - a00 * a21; + out[8] = a00 * a11 - a01 * a10; + return out; + } + /** + * Calculates the determinant of a mat3 + * + * @param {ReadonlyMat3} a the source matrix + * @returns {Number} determinant of a + */ + + function determinant$1(a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); + } + /** + * Multiplies two mat3's + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the first operand + * @param {ReadonlyMat3} b the second operand + * @returns {mat3} out + */ + + function multiply$6(out, a, b) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + var b00 = b[0], + b01 = b[1], + b02 = b[2]; + var b10 = b[3], + b11 = b[4], + b12 = b[5]; + var b20 = b[6], + b21 = b[7], + b22 = b[8]; + out[0] = b00 * a00 + b01 * a10 + b02 * a20; + out[1] = b00 * a01 + b01 * a11 + b02 * a21; + out[2] = b00 * a02 + b01 * a12 + b02 * a22; + out[3] = b10 * a00 + b11 * a10 + b12 * a20; + out[4] = b10 * a01 + b11 * a11 + b12 * a21; + out[5] = b10 * a02 + b11 * a12 + b12 * a22; + out[6] = b20 * a00 + b21 * a10 + b22 * a20; + out[7] = b20 * a01 + b21 * a11 + b22 * a21; + out[8] = b20 * a02 + b21 * a12 + b22 * a22; + return out; + } + /** + * Translate a mat3 by the given vector + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the matrix to translate + * @param {ReadonlyVec2} v vector to translate by + * @returns {mat3} out + */ + + function translate$2(out, a, v) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a10 = a[3], + a11 = a[4], + a12 = a[5], + a20 = a[6], + a21 = a[7], + a22 = a[8], + x = v[0], + y = v[1]; + out[0] = a00; + out[1] = a01; + out[2] = a02; + out[3] = a10; + out[4] = a11; + out[5] = a12; + out[6] = x * a00 + y * a10 + a20; + out[7] = x * a01 + y * a11 + a21; + out[8] = x * a02 + y * a12 + a22; + return out; + } + /** + * Rotates a mat3 by the given angle + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat3} out + */ + + function rotate$2(out, a, rad) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a10 = a[3], + a11 = a[4], + a12 = a[5], + a20 = a[6], + a21 = a[7], + a22 = a[8], + s = Math.sin(rad), + c = Math.cos(rad); + out[0] = c * a00 + s * a10; + out[1] = c * a01 + s * a11; + out[2] = c * a02 + s * a12; + out[3] = c * a10 - s * a00; + out[4] = c * a11 - s * a01; + out[5] = c * a12 - s * a02; + out[6] = a20; + out[7] = a21; + out[8] = a22; + return out; + } + /** + * Scales the mat3 by the dimensions in the given vec2 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the matrix to rotate + * @param {ReadonlyVec2} v the vec2 to scale the matrix by + * @returns {mat3} out + **/ + + function scale$6(out, a, v) { + var x = v[0], + y = v[1]; + out[0] = x * a[0]; + out[1] = x * a[1]; + out[2] = x * a[2]; + out[3] = y * a[3]; + out[4] = y * a[4]; + out[5] = y * a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + return out; + } + /** + * Creates a matrix from a vector translation + * This is equivalent to (but much faster than): + * + * mat3.identity(dest); + * mat3.translate(dest, dest, vec); + * + * @param {mat3} out mat3 receiving operation result + * @param {ReadonlyVec2} v Translation vector + * @returns {mat3} out + */ + + function fromTranslation$2(out, v) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 1; + out[5] = 0; + out[6] = v[0]; + out[7] = v[1]; + out[8] = 1; + return out; + } + /** + * Creates a matrix from a given angle + * This is equivalent to (but much faster than): + * + * mat3.identity(dest); + * mat3.rotate(dest, dest, rad); + * + * @param {mat3} out mat3 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat3} out + */ + + function fromRotation$2(out, rad) { + var s = Math.sin(rad), + c = Math.cos(rad); + out[0] = c; + out[1] = s; + out[2] = 0; + out[3] = -s; + out[4] = c; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 1; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat3.identity(dest); + * mat3.scale(dest, dest, vec); + * + * @param {mat3} out mat3 receiving operation result + * @param {ReadonlyVec2} v Scaling vector + * @returns {mat3} out + */ + + function fromScaling$1(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = v[1]; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 1; + return out; + } + /** + * Copies the values from a mat2d into a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat2d} a the matrix to copy + * @returns {mat3} out + **/ + + function fromMat2d(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = 0; + out[3] = a[2]; + out[4] = a[3]; + out[5] = 0; + out[6] = a[4]; + out[7] = a[5]; + out[8] = 1; + return out; + } + /** + * Calculates a 3x3 matrix from the given quaternion + * + * @param {mat3} out mat3 receiving operation result + * @param {ReadonlyQuat} q Quaternion to create matrix from + * + * @returns {mat3} out + */ + + function fromQuat$1(out, q) { + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var yx = y * x2; + var yy = y * y2; + var zx = z * x2; + var zy = z * y2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - yy - zz; + out[3] = yx - wz; + out[6] = zx + wy; + out[1] = yx + wz; + out[4] = 1 - xx - zz; + out[7] = zy - wx; + out[2] = zx - wy; + out[5] = zy + wx; + out[8] = 1 - xx - yy; + return out; + } + /** + * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix + * + * @param {mat3} out mat3 receiving operation result + * @param {ReadonlyMat4} a Mat4 to derive the normal matrix from + * + * @returns {mat3} out + */ + + function normalFromMat4(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + return out; + } + /** + * Generates a 2D projection matrix with the given bounds + * + * @param {mat3} out mat3 frustum matrix will be written into + * @param {number} width Width of your gl context + * @param {number} height Height of gl context + * @returns {mat3} out + */ + + function projection(out, width, height) { + out[0] = 2 / width; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = -2 / height; + out[5] = 0; + out[6] = -1; + out[7] = 1; + out[8] = 1; + return out; + } + /** + * Returns a string representation of a mat3 + * + * @param {ReadonlyMat3} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ + + function str$6(a) { + return "mat3(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ")"; + } + /** + * Returns Frobenius norm of a mat3 + * + * @param {ReadonlyMat3} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ + + function frob$1(a) { + return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); + } + /** + * Adds two mat3's + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the first operand + * @param {ReadonlyMat3} b the second operand + * @returns {mat3} out + */ + + function add$6(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; + out[7] = a[7] + b[7]; + out[8] = a[8] + b[8]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the first operand + * @param {ReadonlyMat3} b the second operand + * @returns {mat3} out + */ + + function subtract$4(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + out[4] = a[4] - b[4]; + out[5] = a[5] - b[5]; + out[6] = a[6] - b[6]; + out[7] = a[7] - b[7]; + out[8] = a[8] - b[8]; + return out; + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat3} out + */ + + function multiplyScalar$1(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + out[4] = a[4] * b; + out[5] = a[5] * b; + out[6] = a[6] * b; + out[7] = a[7] * b; + out[8] = a[8] * b; + return out; + } + /** + * Adds two mat3's after multiplying each element of the second operand by a scalar value. + * + * @param {mat3} out the receiving vector + * @param {ReadonlyMat3} a the first operand + * @param {ReadonlyMat3} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat3} out + */ + + function multiplyScalarAndAdd$1(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + out[4] = a[4] + b[4] * scale; + out[5] = a[5] + b[5] * scale; + out[6] = a[6] + b[6] * scale; + out[7] = a[7] + b[7] * scale; + out[8] = a[8] + b[8] * scale; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyMat3} a The first matrix. + * @param {ReadonlyMat3} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function exactEquals$6(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {ReadonlyMat3} a The first matrix. + * @param {ReadonlyMat3} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function equals$6(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5], + a6 = a[6], + a7 = a[7], + a8 = a[8]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7], + b8 = b[8]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)); + } + /** + * Alias for {@link mat3.multiply} + * @function + */ + + var mul$6 = multiply$6; + /** + * Alias for {@link mat3.subtract} + * @function + */ + + var sub$4 = subtract$4; + + var mat3 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$6, + fromMat4: fromMat4$1, + clone: clone$6, + copy: copy$6, + fromValues: fromValues$6, + set: set$6, + identity: identity$3, + transpose: transpose$1, + invert: invert$3, + adjoint: adjoint$1, + determinant: determinant$1, + multiply: multiply$6, + translate: translate$2, + rotate: rotate$2, + scale: scale$6, + fromTranslation: fromTranslation$2, + fromRotation: fromRotation$2, + fromScaling: fromScaling$1, + fromMat2d: fromMat2d, + fromQuat: fromQuat$1, + normalFromMat4: normalFromMat4, + projection: projection, + str: str$6, + frob: frob$1, + add: add$6, + subtract: subtract$4, + multiplyScalar: multiplyScalar$1, + multiplyScalarAndAdd: multiplyScalarAndAdd$1, + exactEquals: exactEquals$6, + equals: equals$6, + mul: mul$6, + sub: sub$4 + }); + + /** + * 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied. + * @module mat4 + */ + + /** + * Creates a new identity mat4 + * + * @returns {mat4} a new 4x4 matrix + */ + + function create$5() { + var out = new ARRAY_TYPE(16); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + } + + out[0] = 1; + out[5] = 1; + out[10] = 1; + out[15] = 1; + return out; + } + /** + * Creates a new mat4 initialized with values from an existing matrix + * + * @param {ReadonlyMat4} a matrix to clone + * @returns {mat4} a new 4x4 matrix + */ + + function clone$5(a) { + var out = new ARRAY_TYPE(16); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + out[9] = a[9]; + out[10] = a[10]; + out[11] = a[11]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + return out; + } + /** + * Copy the values from one mat4 to another + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the source matrix + * @returns {mat4} out + */ + + function copy$5(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + out[9] = a[9]; + out[10] = a[10]; + out[11] = a[11]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + return out; + } + /** + * Create a new mat4 with the given values + * + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m03 Component in column 0, row 3 position (index 3) + * @param {Number} m10 Component in column 1, row 0 position (index 4) + * @param {Number} m11 Component in column 1, row 1 position (index 5) + * @param {Number} m12 Component in column 1, row 2 position (index 6) + * @param {Number} m13 Component in column 1, row 3 position (index 7) + * @param {Number} m20 Component in column 2, row 0 position (index 8) + * @param {Number} m21 Component in column 2, row 1 position (index 9) + * @param {Number} m22 Component in column 2, row 2 position (index 10) + * @param {Number} m23 Component in column 2, row 3 position (index 11) + * @param {Number} m30 Component in column 3, row 0 position (index 12) + * @param {Number} m31 Component in column 3, row 1 position (index 13) + * @param {Number} m32 Component in column 3, row 2 position (index 14) + * @param {Number} m33 Component in column 3, row 3 position (index 15) + * @returns {mat4} A new mat4 + */ + + function fromValues$5(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { + var out = new ARRAY_TYPE(16); + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m03; + out[4] = m10; + out[5] = m11; + out[6] = m12; + out[7] = m13; + out[8] = m20; + out[9] = m21; + out[10] = m22; + out[11] = m23; + out[12] = m30; + out[13] = m31; + out[14] = m32; + out[15] = m33; + return out; + } + /** + * Set the components of a mat4 to the given values + * + * @param {mat4} out the receiving matrix + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m03 Component in column 0, row 3 position (index 3) + * @param {Number} m10 Component in column 1, row 0 position (index 4) + * @param {Number} m11 Component in column 1, row 1 position (index 5) + * @param {Number} m12 Component in column 1, row 2 position (index 6) + * @param {Number} m13 Component in column 1, row 3 position (index 7) + * @param {Number} m20 Component in column 2, row 0 position (index 8) + * @param {Number} m21 Component in column 2, row 1 position (index 9) + * @param {Number} m22 Component in column 2, row 2 position (index 10) + * @param {Number} m23 Component in column 2, row 3 position (index 11) + * @param {Number} m30 Component in column 3, row 0 position (index 12) + * @param {Number} m31 Component in column 3, row 1 position (index 13) + * @param {Number} m32 Component in column 3, row 2 position (index 14) + * @param {Number} m33 Component in column 3, row 3 position (index 15) + * @returns {mat4} out + */ + + function set$5(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m03; + out[4] = m10; + out[5] = m11; + out[6] = m12; + out[7] = m13; + out[8] = m20; + out[9] = m21; + out[10] = m22; + out[11] = m23; + out[12] = m30; + out[13] = m31; + out[14] = m32; + out[15] = m33; + return out; + } + /** + * Set a mat4 to the identity matrix + * + * @param {mat4} out the receiving matrix + * @returns {mat4} out + */ + + function identity$2(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Transpose the values of a mat4 + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the source matrix + * @returns {mat4} out + */ + + function transpose(out, a) { + // If we are transposing ourselves we can skip a few steps but have to cache some values + if (out === a) { + var a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a12 = a[6], + a13 = a[7]; + var a23 = a[11]; + out[1] = a[4]; + out[2] = a[8]; + out[3] = a[12]; + out[4] = a01; + out[6] = a[9]; + out[7] = a[13]; + out[8] = a02; + out[9] = a12; + out[11] = a[14]; + out[12] = a03; + out[13] = a13; + out[14] = a23; + } else { + out[0] = a[0]; + out[1] = a[4]; + out[2] = a[8]; + out[3] = a[12]; + out[4] = a[1]; + out[5] = a[5]; + out[6] = a[9]; + out[7] = a[13]; + out[8] = a[2]; + out[9] = a[6]; + out[10] = a[10]; + out[11] = a[14]; + out[12] = a[3]; + out[13] = a[7]; + out[14] = a[11]; + out[15] = a[15]; + } + + return out; + } + /** + * Inverts a mat4 + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the source matrix + * @returns {mat4} out + */ + + function invert$2(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; + out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; + out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; + out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; + out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; + out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; + out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; + return out; + } + /** + * Calculates the adjugate of a mat4 + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the source matrix + * @returns {mat4} out + */ + + function adjoint(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; + out[0] = a11 * b11 - a12 * b10 + a13 * b09; + out[1] = a02 * b10 - a01 * b11 - a03 * b09; + out[2] = a31 * b05 - a32 * b04 + a33 * b03; + out[3] = a22 * b04 - a21 * b05 - a23 * b03; + out[4] = a12 * b08 - a10 * b11 - a13 * b07; + out[5] = a00 * b11 - a02 * b08 + a03 * b07; + out[6] = a32 * b02 - a30 * b05 - a33 * b01; + out[7] = a20 * b05 - a22 * b02 + a23 * b01; + out[8] = a10 * b10 - a11 * b08 + a13 * b06; + out[9] = a01 * b08 - a00 * b10 - a03 * b06; + out[10] = a30 * b04 - a31 * b02 + a33 * b00; + out[11] = a21 * b02 - a20 * b04 - a23 * b00; + out[12] = a11 * b07 - a10 * b09 - a12 * b06; + out[13] = a00 * b09 - a01 * b07 + a02 * b06; + out[14] = a31 * b01 - a30 * b03 - a32 * b00; + out[15] = a20 * b03 - a21 * b01 + a22 * b00; + return out; + } + /** + * Calculates the determinant of a mat4 + * + * @param {ReadonlyMat4} a the source matrix + * @returns {Number} determinant of a + */ + + function determinant(a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + var b0 = a00 * a11 - a01 * a10; + var b1 = a00 * a12 - a02 * a10; + var b2 = a01 * a12 - a02 * a11; + var b3 = a20 * a31 - a21 * a30; + var b4 = a20 * a32 - a22 * a30; + var b5 = a21 * a32 - a22 * a31; + var b6 = a00 * b5 - a01 * b4 + a02 * b3; + var b7 = a10 * b5 - a11 * b4 + a12 * b3; + var b8 = a20 * b2 - a21 * b1 + a22 * b0; + var b9 = a30 * b2 - a31 * b1 + a32 * b0; // Calculate the determinant + + return a13 * b6 - a03 * b7 + a33 * b8 - a23 * b9; + } + /** + * Multiplies two mat4s + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand + * @returns {mat4} out + */ + + function multiply$5(out, a, b) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; // Cache only the current line of the second matrix + + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[4]; + b1 = b[5]; + b2 = b[6]; + b3 = b[7]; + out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[8]; + b1 = b[9]; + b2 = b[10]; + b3 = b[11]; + out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[12]; + b1 = b[13]; + b2 = b[14]; + b3 = b[15]; + out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + return out; + } + /** + * Translate a mat4 by the given vector + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to translate + * @param {ReadonlyVec3} v vector to translate by + * @returns {mat4} out + */ + + function translate$1(out, a, v) { + var x = v[0], + y = v[1], + z = v[2]; + var a00, a01, a02, a03; + var a10, a11, a12, a13; + var a20, a21, a22, a23; + + if (a === out) { + out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; + out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; + out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; + out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; + } else { + a00 = a[0]; + a01 = a[1]; + a02 = a[2]; + a03 = a[3]; + a10 = a[4]; + a11 = a[5]; + a12 = a[6]; + a13 = a[7]; + a20 = a[8]; + a21 = a[9]; + a22 = a[10]; + a23 = a[11]; + out[0] = a00; + out[1] = a01; + out[2] = a02; + out[3] = a03; + out[4] = a10; + out[5] = a11; + out[6] = a12; + out[7] = a13; + out[8] = a20; + out[9] = a21; + out[10] = a22; + out[11] = a23; + out[12] = a00 * x + a10 * y + a20 * z + a[12]; + out[13] = a01 * x + a11 * y + a21 * z + a[13]; + out[14] = a02 * x + a12 * y + a22 * z + a[14]; + out[15] = a03 * x + a13 * y + a23 * z + a[15]; + } + + return out; + } + /** + * Scales the mat4 by the dimensions in the given vec3 not using vectorization + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to scale + * @param {ReadonlyVec3} v the vec3 to scale the matrix by + * @returns {mat4} out + **/ + + function scale$5(out, a, v) { + var x = v[0], + y = v[1], + z = v[2]; + out[0] = a[0] * x; + out[1] = a[1] * x; + out[2] = a[2] * x; + out[3] = a[3] * x; + out[4] = a[4] * y; + out[5] = a[5] * y; + out[6] = a[6] * y; + out[7] = a[7] * y; + out[8] = a[8] * z; + out[9] = a[9] * z; + out[10] = a[10] * z; + out[11] = a[11] * z; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + return out; + } + /** + * Rotates a mat4 by the given angle around the given axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @param {ReadonlyVec3} axis the axis to rotate around + * @returns {mat4} out + */ + + function rotate$1(out, a, rad, axis) { + var x = axis[0], + y = axis[1], + z = axis[2]; + var len = Math.hypot(x, y, z); + var s, c, t; + var a00, a01, a02, a03; + var a10, a11, a12, a13; + var a20, a21, a22, a23; + var b00, b01, b02; + var b10, b11, b12; + var b20, b21, b22; + + if (len < EPSILON) { + return null; + } + + len = 1 / len; + x *= len; + y *= len; + z *= len; + s = Math.sin(rad); + c = Math.cos(rad); + t = 1 - c; + a00 = a[0]; + a01 = a[1]; + a02 = a[2]; + a03 = a[3]; + a10 = a[4]; + a11 = a[5]; + a12 = a[6]; + a13 = a[7]; + a20 = a[8]; + a21 = a[9]; + a22 = a[10]; + a23 = a[11]; // Construct the elements of the rotation matrix + + b00 = x * x * t + c; + b01 = y * x * t + z * s; + b02 = z * x * t - y * s; + b10 = x * y * t - z * s; + b11 = y * y * t + c; + b12 = z * y * t + x * s; + b20 = x * z * t + y * s; + b21 = y * z * t - x * s; + b22 = z * z * t + c; // Perform rotation-specific matrix multiplication + + out[0] = a00 * b00 + a10 * b01 + a20 * b02; + out[1] = a01 * b00 + a11 * b01 + a21 * b02; + out[2] = a02 * b00 + a12 * b01 + a22 * b02; + out[3] = a03 * b00 + a13 * b01 + a23 * b02; + out[4] = a00 * b10 + a10 * b11 + a20 * b12; + out[5] = a01 * b10 + a11 * b11 + a21 * b12; + out[6] = a02 * b10 + a12 * b11 + a22 * b12; + out[7] = a03 * b10 + a13 * b11 + a23 * b12; + out[8] = a00 * b20 + a10 * b21 + a20 * b22; + out[9] = a01 * b20 + a11 * b21 + a21 * b22; + out[10] = a02 * b20 + a12 * b21 + a22 * b22; + out[11] = a03 * b20 + a13 * b21 + a23 * b22; + + if (a !== out) { + // If the source and destination differ, copy the unchanged last row + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } + + return out; + } + /** + * Rotates a matrix by the given angle around the X axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function rotateX$3(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + + if (a !== out) { + // If the source and destination differ, copy the unchanged rows + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[4] = a10 * c + a20 * s; + out[5] = a11 * c + a21 * s; + out[6] = a12 * c + a22 * s; + out[7] = a13 * c + a23 * s; + out[8] = a20 * c - a10 * s; + out[9] = a21 * c - a11 * s; + out[10] = a22 * c - a12 * s; + out[11] = a23 * c - a13 * s; + return out; + } + /** + * Rotates a matrix by the given angle around the Y axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function rotateY$3(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + + if (a !== out) { + // If the source and destination differ, copy the unchanged rows + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[0] = a00 * c - a20 * s; + out[1] = a01 * c - a21 * s; + out[2] = a02 * c - a22 * s; + out[3] = a03 * c - a23 * s; + out[8] = a00 * s + a20 * c; + out[9] = a01 * s + a21 * c; + out[10] = a02 * s + a22 * c; + out[11] = a03 * s + a23 * c; + return out; + } + /** + * Rotates a matrix by the given angle around the Z axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function rotateZ$3(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + + if (a !== out) { + // If the source and destination differ, copy the unchanged last row + out[8] = a[8]; + out[9] = a[9]; + out[10] = a[10]; + out[11] = a[11]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[0] = a00 * c + a10 * s; + out[1] = a01 * c + a11 * s; + out[2] = a02 * c + a12 * s; + out[3] = a03 * c + a13 * s; + out[4] = a10 * c - a00 * s; + out[5] = a11 * c - a01 * s; + out[6] = a12 * c - a02 * s; + out[7] = a13 * c - a03 * s; + return out; + } + /** + * Creates a matrix from a vector translation + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, dest, vec); + * + * @param {mat4} out mat4 receiving operation result + * @param {ReadonlyVec3} v Translation vector + * @returns {mat4} out + */ + + function fromTranslation$1(out, v) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.scale(dest, dest, vec); + * + * @param {mat4} out mat4 receiving operation result + * @param {ReadonlyVec3} v Scaling vector + * @returns {mat4} out + */ + + function fromScaling(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = v[1]; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = v[2]; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from a given angle around a given axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotate(dest, dest, rad, axis); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @param {ReadonlyVec3} axis the axis to rotate around + * @returns {mat4} out + */ + + function fromRotation$1(out, rad, axis) { + var x = axis[0], + y = axis[1], + z = axis[2]; + var len = Math.hypot(x, y, z); + var s, c, t; + + if (len < EPSILON) { + return null; + } + + len = 1 / len; + x *= len; + y *= len; + z *= len; + s = Math.sin(rad); + c = Math.cos(rad); + t = 1 - c; // Perform rotation-specific matrix multiplication + + out[0] = x * x * t + c; + out[1] = y * x * t + z * s; + out[2] = z * x * t - y * s; + out[3] = 0; + out[4] = x * y * t - z * s; + out[5] = y * y * t + c; + out[6] = z * y * t + x * s; + out[7] = 0; + out[8] = x * z * t + y * s; + out[9] = y * z * t - x * s; + out[10] = z * z * t + c; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from the given angle around the X axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotateX(dest, dest, rad); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function fromXRotation(out, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); // Perform axis-specific matrix multiplication + + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = c; + out[6] = s; + out[7] = 0; + out[8] = 0; + out[9] = -s; + out[10] = c; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from the given angle around the Y axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotateY(dest, dest, rad); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function fromYRotation(out, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); // Perform axis-specific matrix multiplication + + out[0] = c; + out[1] = 0; + out[2] = -s; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = s; + out[9] = 0; + out[10] = c; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from the given angle around the Z axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotateZ(dest, dest, rad); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function fromZRotation(out, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); // Perform axis-specific matrix multiplication + + out[0] = c; + out[1] = s; + out[2] = 0; + out[3] = 0; + out[4] = -s; + out[5] = c; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from a quaternion rotation and vector translation + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, vec); + * let quatMat = mat4.create(); + * quat4.toMat4(quat, quatMat); + * mat4.multiply(dest, quatMat); + * + * @param {mat4} out mat4 receiving operation result + * @param {quat4} q Rotation quaternion + * @param {ReadonlyVec3} v Translation vector + * @returns {mat4} out + */ + + function fromRotationTranslation$1(out, q, v) { + // Quaternion math + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - (yy + zz); + out[1] = xy + wz; + out[2] = xz - wy; + out[3] = 0; + out[4] = xy - wz; + out[5] = 1 - (xx + zz); + out[6] = yz + wx; + out[7] = 0; + out[8] = xz + wy; + out[9] = yz - wx; + out[10] = 1 - (xx + yy); + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + /** + * Creates a new mat4 from a dual quat. + * + * @param {mat4} out Matrix + * @param {ReadonlyQuat2} a Dual Quaternion + * @returns {mat4} mat4 receiving operation result + */ + + function fromQuat2(out, a) { + var translation = new ARRAY_TYPE(3); + var bx = -a[0], + by = -a[1], + bz = -a[2], + bw = a[3], + ax = a[4], + ay = a[5], + az = a[6], + aw = a[7]; + var magnitude = bx * bx + by * by + bz * bz + bw * bw; //Only scale if it makes sense + + if (magnitude > 0) { + translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude; + translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude; + translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude; + } else { + translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2; + translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2; + translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2; + } + + fromRotationTranslation$1(out, a, translation); + return out; + } + /** + * Returns the translation vector component of a transformation + * matrix. If a matrix is built with fromRotationTranslation, + * the returned vector will be the same as the translation vector + * originally supplied. + * @param {vec3} out Vector to receive translation component + * @param {ReadonlyMat4} mat Matrix to be decomposed (input) + * @return {vec3} out + */ + + function getTranslation$1(out, mat) { + out[0] = mat[12]; + out[1] = mat[13]; + out[2] = mat[14]; + return out; + } + /** + * Returns the scaling factor component of a transformation + * matrix. If a matrix is built with fromRotationTranslationScale + * with a normalized Quaternion paramter, the returned vector will be + * the same as the scaling vector + * originally supplied. + * @param {vec3} out Vector to receive scaling factor component + * @param {ReadonlyMat4} mat Matrix to be decomposed (input) + * @return {vec3} out + */ + + function getScaling(out, mat) { + var m11 = mat[0]; + var m12 = mat[1]; + var m13 = mat[2]; + var m21 = mat[4]; + var m22 = mat[5]; + var m23 = mat[6]; + var m31 = mat[8]; + var m32 = mat[9]; + var m33 = mat[10]; + out[0] = Math.hypot(m11, m12, m13); + out[1] = Math.hypot(m21, m22, m23); + out[2] = Math.hypot(m31, m32, m33); + return out; + } + /** + * Returns a quaternion representing the rotational component + * of a transformation matrix. If a matrix is built with + * fromRotationTranslation, the returned quaternion will be the + * same as the quaternion originally supplied. + * @param {quat} out Quaternion to receive the rotation component + * @param {ReadonlyMat4} mat Matrix to be decomposed (input) + * @return {quat} out + */ + + function getRotation(out, mat) { + var scaling = new ARRAY_TYPE(3); + getScaling(scaling, mat); + var is1 = 1 / scaling[0]; + var is2 = 1 / scaling[1]; + var is3 = 1 / scaling[2]; + var sm11 = mat[0] * is1; + var sm12 = mat[1] * is2; + var sm13 = mat[2] * is3; + var sm21 = mat[4] * is1; + var sm22 = mat[5] * is2; + var sm23 = mat[6] * is3; + var sm31 = mat[8] * is1; + var sm32 = mat[9] * is2; + var sm33 = mat[10] * is3; + var trace = sm11 + sm22 + sm33; + var S = 0; + + if (trace > 0) { + S = Math.sqrt(trace + 1.0) * 2; + out[3] = 0.25 * S; + out[0] = (sm23 - sm32) / S; + out[1] = (sm31 - sm13) / S; + out[2] = (sm12 - sm21) / S; + } else if (sm11 > sm22 && sm11 > sm33) { + S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2; + out[3] = (sm23 - sm32) / S; + out[0] = 0.25 * S; + out[1] = (sm12 + sm21) / S; + out[2] = (sm31 + sm13) / S; + } else if (sm22 > sm33) { + S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2; + out[3] = (sm31 - sm13) / S; + out[0] = (sm12 + sm21) / S; + out[1] = 0.25 * S; + out[2] = (sm23 + sm32) / S; + } else { + S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2; + out[3] = (sm12 - sm21) / S; + out[0] = (sm31 + sm13) / S; + out[1] = (sm23 + sm32) / S; + out[2] = 0.25 * S; + } + + return out; + } + /** + * Decomposes a transformation matrix into its rotation, translation + * and scale components. Returns only the rotation component + * @param {quat} out_r Quaternion to receive the rotation component + * @param {vec3} out_t Vector to receive the translation vector + * @param {vec3} out_s Vector to receive the scaling factor + * @param {ReadonlyMat4} mat Matrix to be decomposed (input) + * @returns {quat} out_r + */ + + function decompose(out_r, out_t, out_s, mat) { + out_t[0] = mat[12]; + out_t[1] = mat[13]; + out_t[2] = mat[14]; + var m11 = mat[0]; + var m12 = mat[1]; + var m13 = mat[2]; + var m21 = mat[4]; + var m22 = mat[5]; + var m23 = mat[6]; + var m31 = mat[8]; + var m32 = mat[9]; + var m33 = mat[10]; + out_s[0] = Math.hypot(m11, m12, m13); + out_s[1] = Math.hypot(m21, m22, m23); + out_s[2] = Math.hypot(m31, m32, m33); + var is1 = 1 / out_s[0]; + var is2 = 1 / out_s[1]; + var is3 = 1 / out_s[2]; + var sm11 = m11 * is1; + var sm12 = m12 * is2; + var sm13 = m13 * is3; + var sm21 = m21 * is1; + var sm22 = m22 * is2; + var sm23 = m23 * is3; + var sm31 = m31 * is1; + var sm32 = m32 * is2; + var sm33 = m33 * is3; + var trace = sm11 + sm22 + sm33; + var S = 0; + + if (trace > 0) { + S = Math.sqrt(trace + 1.0) * 2; + out_r[3] = 0.25 * S; + out_r[0] = (sm23 - sm32) / S; + out_r[1] = (sm31 - sm13) / S; + out_r[2] = (sm12 - sm21) / S; + } else if (sm11 > sm22 && sm11 > sm33) { + S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2; + out_r[3] = (sm23 - sm32) / S; + out_r[0] = 0.25 * S; + out_r[1] = (sm12 + sm21) / S; + out_r[2] = (sm31 + sm13) / S; + } else if (sm22 > sm33) { + S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2; + out_r[3] = (sm31 - sm13) / S; + out_r[0] = (sm12 + sm21) / S; + out_r[1] = 0.25 * S; + out_r[2] = (sm23 + sm32) / S; + } else { + S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2; + out_r[3] = (sm12 - sm21) / S; + out_r[0] = (sm31 + sm13) / S; + out_r[1] = (sm23 + sm32) / S; + out_r[2] = 0.25 * S; + } + + return out_r; + } + /** + * Creates a matrix from a quaternion rotation, vector translation and vector scale + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, vec); + * let quatMat = mat4.create(); + * quat4.toMat4(quat, quatMat); + * mat4.multiply(dest, quatMat); + * mat4.scale(dest, scale) + * + * @param {mat4} out mat4 receiving operation result + * @param {quat4} q Rotation quaternion + * @param {ReadonlyVec3} v Translation vector + * @param {ReadonlyVec3} s Scaling vector + * @returns {mat4} out + */ + + function fromRotationTranslationScale(out, q, v, s) { + // Quaternion math + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + var sx = s[0]; + var sy = s[1]; + var sz = s[2]; + out[0] = (1 - (yy + zz)) * sx; + out[1] = (xy + wz) * sx; + out[2] = (xz - wy) * sx; + out[3] = 0; + out[4] = (xy - wz) * sy; + out[5] = (1 - (xx + zz)) * sy; + out[6] = (yz + wx) * sy; + out[7] = 0; + out[8] = (xz + wy) * sz; + out[9] = (yz - wx) * sz; + out[10] = (1 - (xx + yy)) * sz; + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + /** + * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, vec); + * mat4.translate(dest, origin); + * let quatMat = mat4.create(); + * quat4.toMat4(quat, quatMat); + * mat4.multiply(dest, quatMat); + * mat4.scale(dest, scale) + * mat4.translate(dest, negativeOrigin); + * + * @param {mat4} out mat4 receiving operation result + * @param {quat4} q Rotation quaternion + * @param {ReadonlyVec3} v Translation vector + * @param {ReadonlyVec3} s Scaling vector + * @param {ReadonlyVec3} o The origin vector around which to scale and rotate + * @returns {mat4} out + */ + + function fromRotationTranslationScaleOrigin(out, q, v, s, o) { + // Quaternion math + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + var sx = s[0]; + var sy = s[1]; + var sz = s[2]; + var ox = o[0]; + var oy = o[1]; + var oz = o[2]; + var out0 = (1 - (yy + zz)) * sx; + var out1 = (xy + wz) * sx; + var out2 = (xz - wy) * sx; + var out4 = (xy - wz) * sy; + var out5 = (1 - (xx + zz)) * sy; + var out6 = (yz + wx) * sy; + var out8 = (xz + wy) * sz; + var out9 = (yz - wx) * sz; + var out10 = (1 - (xx + yy)) * sz; + out[0] = out0; + out[1] = out1; + out[2] = out2; + out[3] = 0; + out[4] = out4; + out[5] = out5; + out[6] = out6; + out[7] = 0; + out[8] = out8; + out[9] = out9; + out[10] = out10; + out[11] = 0; + out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz); + out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz); + out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz); + out[15] = 1; + return out; + } + /** + * Calculates a 4x4 matrix from the given quaternion + * + * @param {mat4} out mat4 receiving operation result + * @param {ReadonlyQuat} q Quaternion to create matrix from + * + * @returns {mat4} out + */ + + function fromQuat(out, q) { + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var yx = y * x2; + var yy = y * y2; + var zx = z * x2; + var zy = z * y2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - yy - zz; + out[1] = yx + wz; + out[2] = zx - wy; + out[3] = 0; + out[4] = yx - wz; + out[5] = 1 - xx - zz; + out[6] = zy + wx; + out[7] = 0; + out[8] = zx + wy; + out[9] = zy - wx; + out[10] = 1 - xx - yy; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Generates a frustum matrix with the given bounds + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {Number} left Left bound of the frustum + * @param {Number} right Right bound of the frustum + * @param {Number} bottom Bottom bound of the frustum + * @param {Number} top Top bound of the frustum + * @param {Number} near Near bound of the frustum + * @param {Number} far Far bound of the frustum + * @returns {mat4} out + */ + + function frustum(out, left, right, bottom, top, near, far) { + var rl = 1 / (right - left); + var tb = 1 / (top - bottom); + var nf = 1 / (near - far); + out[0] = near * 2 * rl; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = near * 2 * tb; + out[6] = 0; + out[7] = 0; + out[8] = (right + left) * rl; + out[9] = (top + bottom) * tb; + out[10] = (far + near) * nf; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[14] = far * near * 2 * nf; + out[15] = 0; + return out; + } + /** + * Generates a perspective projection matrix with the given bounds. + * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1], + * which matches WebGL/OpenGL's clip volume. + * Passing null/undefined/no value for far will generate infinite projection matrix. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} fovy Vertical field of view in radians + * @param {number} aspect Aspect ratio. typically viewport width/height + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum, can be null or Infinity + * @returns {mat4} out + */ + + function perspectiveNO(out, fovy, aspect, near, far) { + var f = 1.0 / Math.tan(fovy / 2); + out[0] = f / aspect; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = f; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[15] = 0; + + if (far != null && far !== Infinity) { + var nf = 1 / (near - far); + out[10] = (far + near) * nf; + out[14] = 2 * far * near * nf; + } else { + out[10] = -1; + out[14] = -2 * near; + } + + return out; + } + /** + * Alias for {@link mat4.perspectiveNO} + * @function + */ + + var perspective = perspectiveNO; + /** + * Generates a perspective projection matrix suitable for WebGPU with the given bounds. + * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1], + * which matches WebGPU/Vulkan/DirectX/Metal's clip volume. + * Passing null/undefined/no value for far will generate infinite projection matrix. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} fovy Vertical field of view in radians + * @param {number} aspect Aspect ratio. typically viewport width/height + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum, can be null or Infinity + * @returns {mat4} out + */ + + function perspectiveZO(out, fovy, aspect, near, far) { + var f = 1.0 / Math.tan(fovy / 2); + out[0] = f / aspect; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = f; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[15] = 0; + + if (far != null && far !== Infinity) { + var nf = 1 / (near - far); + out[10] = far * nf; + out[14] = far * near * nf; + } else { + out[10] = -1; + out[14] = -near; + } + + return out; + } + /** + * Generates a perspective projection matrix with the given field of view. + * This is primarily useful for generating projection matrices to be used + * with the still experiemental WebVR API. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum + * @returns {mat4} out + */ + + function perspectiveFromFieldOfView(out, fov, near, far) { + var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0); + var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0); + var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0); + var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0); + var xScale = 2.0 / (leftTan + rightTan); + var yScale = 2.0 / (upTan + downTan); + out[0] = xScale; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + out[4] = 0.0; + out[5] = yScale; + out[6] = 0.0; + out[7] = 0.0; + out[8] = -((leftTan - rightTan) * xScale * 0.5); + out[9] = (upTan - downTan) * yScale * 0.5; + out[10] = far / (near - far); + out[11] = -1.0; + out[12] = 0.0; + out[13] = 0.0; + out[14] = far * near / (near - far); + out[15] = 0.0; + return out; + } + /** + * Generates a orthogonal projection matrix with the given bounds. + * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1], + * which matches WebGL/OpenGL's clip volume. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} left Left bound of the frustum + * @param {number} right Right bound of the frustum + * @param {number} bottom Bottom bound of the frustum + * @param {number} top Top bound of the frustum + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum + * @returns {mat4} out + */ + + function orthoNO(out, left, right, bottom, top, near, far) { + var lr = 1 / (left - right); + var bt = 1 / (bottom - top); + var nf = 1 / (near - far); + out[0] = -2 * lr; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = -2 * bt; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 2 * nf; + out[11] = 0; + out[12] = (left + right) * lr; + out[13] = (top + bottom) * bt; + out[14] = (far + near) * nf; + out[15] = 1; + return out; + } + /** + * Alias for {@link mat4.orthoNO} + * @function + */ + + var ortho = orthoNO; + /** + * Generates a orthogonal projection matrix with the given bounds. + * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1], + * which matches WebGPU/Vulkan/DirectX/Metal's clip volume. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} left Left bound of the frustum + * @param {number} right Right bound of the frustum + * @param {number} bottom Bottom bound of the frustum + * @param {number} top Top bound of the frustum + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum + * @returns {mat4} out + */ + + function orthoZO(out, left, right, bottom, top, near, far) { + var lr = 1 / (left - right); + var bt = 1 / (bottom - top); + var nf = 1 / (near - far); + out[0] = -2 * lr; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = -2 * bt; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = nf; + out[11] = 0; + out[12] = (left + right) * lr; + out[13] = (top + bottom) * bt; + out[14] = near * nf; + out[15] = 1; + return out; + } + /** + * Generates a look-at matrix with the given eye position, focal point, and up axis. + * If you want a matrix that actually makes an object look at another object, you should use targetTo instead. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {ReadonlyVec3} eye Position of the viewer + * @param {ReadonlyVec3} center Point the viewer is looking at + * @param {ReadonlyVec3} up vec3 pointing up + * @returns {mat4} out + */ + + function lookAt(out, eye, center, up) { + var x0, x1, x2, y0, y1, y2, z0, z1, z2, len; + var eyex = eye[0]; + var eyey = eye[1]; + var eyez = eye[2]; + var upx = up[0]; + var upy = up[1]; + var upz = up[2]; + var centerx = center[0]; + var centery = center[1]; + var centerz = center[2]; + + if (Math.abs(eyex - centerx) < EPSILON && Math.abs(eyey - centery) < EPSILON && Math.abs(eyez - centerz) < EPSILON) { + return identity$2(out); + } + + z0 = eyex - centerx; + z1 = eyey - centery; + z2 = eyez - centerz; + len = 1 / Math.hypot(z0, z1, z2); + z0 *= len; + z1 *= len; + z2 *= len; + x0 = upy * z2 - upz * z1; + x1 = upz * z0 - upx * z2; + x2 = upx * z1 - upy * z0; + len = Math.hypot(x0, x1, x2); + + if (!len) { + x0 = 0; + x1 = 0; + x2 = 0; + } else { + len = 1 / len; + x0 *= len; + x1 *= len; + x2 *= len; + } + + y0 = z1 * x2 - z2 * x1; + y1 = z2 * x0 - z0 * x2; + y2 = z0 * x1 - z1 * x0; + len = Math.hypot(y0, y1, y2); + + if (!len) { + y0 = 0; + y1 = 0; + y2 = 0; + } else { + len = 1 / len; + y0 *= len; + y1 *= len; + y2 *= len; + } + + out[0] = x0; + out[1] = y0; + out[2] = z0; + out[3] = 0; + out[4] = x1; + out[5] = y1; + out[6] = z1; + out[7] = 0; + out[8] = x2; + out[9] = y2; + out[10] = z2; + out[11] = 0; + out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); + out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); + out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); + out[15] = 1; + return out; + } + /** + * Generates a matrix that makes something look at something else. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {ReadonlyVec3} eye Position of the viewer + * @param {ReadonlyVec3} center Point the viewer is looking at + * @param {ReadonlyVec3} up vec3 pointing up + * @returns {mat4} out + */ + + function targetTo(out, eye, target, up) { + var eyex = eye[0], + eyey = eye[1], + eyez = eye[2], + upx = up[0], + upy = up[1], + upz = up[2]; + var z0 = eyex - target[0], + z1 = eyey - target[1], + z2 = eyez - target[2]; + var len = z0 * z0 + z1 * z1 + z2 * z2; + + if (len > 0) { + len = 1 / Math.sqrt(len); + z0 *= len; + z1 *= len; + z2 *= len; + } + + var x0 = upy * z2 - upz * z1, + x1 = upz * z0 - upx * z2, + x2 = upx * z1 - upy * z0; + len = x0 * x0 + x1 * x1 + x2 * x2; + + if (len > 0) { + len = 1 / Math.sqrt(len); + x0 *= len; + x1 *= len; + x2 *= len; + } + + out[0] = x0; + out[1] = x1; + out[2] = x2; + out[3] = 0; + out[4] = z1 * x2 - z2 * x1; + out[5] = z2 * x0 - z0 * x2; + out[6] = z0 * x1 - z1 * x0; + out[7] = 0; + out[8] = z0; + out[9] = z1; + out[10] = z2; + out[11] = 0; + out[12] = eyex; + out[13] = eyey; + out[14] = eyez; + out[15] = 1; + return out; + } + /** + * Returns a string representation of a mat4 + * + * @param {ReadonlyMat4} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ + + function str$5(a) { + return "mat4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + ")"; + } + /** + * Returns Frobenius norm of a mat4 + * + * @param {ReadonlyMat4} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ + + function frob(a) { + return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); + } + /** + * Adds two mat4's + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand + * @returns {mat4} out + */ + + function add$5(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; + out[7] = a[7] + b[7]; + out[8] = a[8] + b[8]; + out[9] = a[9] + b[9]; + out[10] = a[10] + b[10]; + out[11] = a[11] + b[11]; + out[12] = a[12] + b[12]; + out[13] = a[13] + b[13]; + out[14] = a[14] + b[14]; + out[15] = a[15] + b[15]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand + * @returns {mat4} out + */ + + function subtract$3(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + out[4] = a[4] - b[4]; + out[5] = a[5] - b[5]; + out[6] = a[6] - b[6]; + out[7] = a[7] - b[7]; + out[8] = a[8] - b[8]; + out[9] = a[9] - b[9]; + out[10] = a[10] - b[10]; + out[11] = a[11] - b[11]; + out[12] = a[12] - b[12]; + out[13] = a[13] - b[13]; + out[14] = a[14] - b[14]; + out[15] = a[15] - b[15]; + return out; + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat4} out + */ + + function multiplyScalar(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + out[4] = a[4] * b; + out[5] = a[5] * b; + out[6] = a[6] * b; + out[7] = a[7] * b; + out[8] = a[8] * b; + out[9] = a[9] * b; + out[10] = a[10] * b; + out[11] = a[11] * b; + out[12] = a[12] * b; + out[13] = a[13] * b; + out[14] = a[14] * b; + out[15] = a[15] * b; + return out; + } + /** + * Adds two mat4's after multiplying each element of the second operand by a scalar value. + * + * @param {mat4} out the receiving vector + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat4} out + */ + + function multiplyScalarAndAdd(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + out[4] = a[4] + b[4] * scale; + out[5] = a[5] + b[5] * scale; + out[6] = a[6] + b[6] * scale; + out[7] = a[7] + b[7] * scale; + out[8] = a[8] + b[8] * scale; + out[9] = a[9] + b[9] * scale; + out[10] = a[10] + b[10] * scale; + out[11] = a[11] + b[11] * scale; + out[12] = a[12] + b[12] * scale; + out[13] = a[13] + b[13] * scale; + out[14] = a[14] + b[14] * scale; + out[15] = a[15] + b[15] * scale; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyMat4} a The first matrix. + * @param {ReadonlyMat4} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function exactEquals$5(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {ReadonlyMat4} a The first matrix. + * @param {ReadonlyMat4} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function equals$5(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var a4 = a[4], + a5 = a[5], + a6 = a[6], + a7 = a[7]; + var a8 = a[8], + a9 = a[9], + a10 = a[10], + a11 = a[11]; + var a12 = a[12], + a13 = a[13], + a14 = a[14], + a15 = a[15]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + var b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7]; + var b8 = b[8], + b9 = b[9], + b10 = b[10], + b11 = b[11]; + var b12 = b[12], + b13 = b[13], + b14 = b[14], + b15 = b[15]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15)); + } + /** + * Alias for {@link mat4.multiply} + * @function + */ + + var mul$5 = multiply$5; + /** + * Alias for {@link mat4.subtract} + * @function + */ + + var sub$3 = subtract$3; + + var mat4 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$5, + clone: clone$5, + copy: copy$5, + fromValues: fromValues$5, + set: set$5, + identity: identity$2, + transpose: transpose, + invert: invert$2, + adjoint: adjoint, + determinant: determinant, + multiply: multiply$5, + translate: translate$1, + scale: scale$5, + rotate: rotate$1, + rotateX: rotateX$3, + rotateY: rotateY$3, + rotateZ: rotateZ$3, + fromTranslation: fromTranslation$1, + fromScaling: fromScaling, + fromRotation: fromRotation$1, + fromXRotation: fromXRotation, + fromYRotation: fromYRotation, + fromZRotation: fromZRotation, + fromRotationTranslation: fromRotationTranslation$1, + fromQuat2: fromQuat2, + getTranslation: getTranslation$1, + getScaling: getScaling, + getRotation: getRotation, + decompose: decompose, + fromRotationTranslationScale: fromRotationTranslationScale, + fromRotationTranslationScaleOrigin: fromRotationTranslationScaleOrigin, + fromQuat: fromQuat, + frustum: frustum, + perspectiveNO: perspectiveNO, + perspective: perspective, + perspectiveZO: perspectiveZO, + perspectiveFromFieldOfView: perspectiveFromFieldOfView, + orthoNO: orthoNO, + ortho: ortho, + orthoZO: orthoZO, + lookAt: lookAt, + targetTo: targetTo, + str: str$5, + frob: frob, + add: add$5, + subtract: subtract$3, + multiplyScalar: multiplyScalar, + multiplyScalarAndAdd: multiplyScalarAndAdd, + exactEquals: exactEquals$5, + equals: equals$5, + mul: mul$5, + sub: sub$3 + }); + + /** + * 3 Dimensional Vector + * @module vec3 + */ + + /** + * Creates a new, empty vec3 + * + * @returns {vec3} a new 3D vector + */ + + function create$4() { + var out = new ARRAY_TYPE(3); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + return out; + } + /** + * Creates a new vec3 initialized with values from an existing vector + * + * @param {ReadonlyVec3} a vector to clone + * @returns {vec3} a new 3D vector + */ + + function clone$4(a) { + var out = new ARRAY_TYPE(3); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + return out; + } + /** + * Calculates the length of a vec3 + * + * @param {ReadonlyVec3} a vector to calculate length of + * @returns {Number} length of a + */ + + function length$4(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + return Math.hypot(x, y, z); + } + /** + * Creates a new vec3 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} a new 3D vector + */ + + function fromValues$4(x, y, z) { + var out = new ARRAY_TYPE(3); + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Copy the values from one vec3 to another + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the source vector + * @returns {vec3} out + */ + + function copy$4(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + return out; + } + /** + * Set the components of a vec3 to the given values + * + * @param {vec3} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} out + */ + + function set$4(out, x, y, z) { + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Adds two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function add$4(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function subtract$2(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + return out; + } + /** + * Multiplies two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function multiply$4(out, a, b) { + out[0] = a[0] * b[0]; + out[1] = a[1] * b[1]; + out[2] = a[2] * b[2]; + return out; + } + /** + * Divides two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function divide$2(out, a, b) { + out[0] = a[0] / b[0]; + out[1] = a[1] / b[1]; + out[2] = a[2] / b[2]; + return out; + } + /** + * Math.ceil the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to ceil + * @returns {vec3} out + */ + + function ceil$2(out, a) { + out[0] = Math.ceil(a[0]); + out[1] = Math.ceil(a[1]); + out[2] = Math.ceil(a[2]); + return out; + } + /** + * Math.floor the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to floor + * @returns {vec3} out + */ + + function floor$2(out, a) { + out[0] = Math.floor(a[0]); + out[1] = Math.floor(a[1]); + out[2] = Math.floor(a[2]); + return out; + } + /** + * Returns the minimum of two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function min$2(out, a, b) { + out[0] = Math.min(a[0], b[0]); + out[1] = Math.min(a[1], b[1]); + out[2] = Math.min(a[2], b[2]); + return out; + } + /** + * Returns the maximum of two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function max$2(out, a, b) { + out[0] = Math.max(a[0], b[0]); + out[1] = Math.max(a[1], b[1]); + out[2] = Math.max(a[2], b[2]); + return out; + } + /** + * Math.round the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to round + * @returns {vec3} out + */ + + function round$2(out, a) { + out[0] = Math.round(a[0]); + out[1] = Math.round(a[1]); + out[2] = Math.round(a[2]); + return out; + } + /** + * Scales a vec3 by a scalar number + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec3} out + */ + + function scale$4(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + return out; + } + /** + * Adds two vec3's after scaling the second operand by a scalar value + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {Number} scale the amount to scale b by before adding + * @returns {vec3} out + */ + + function scaleAndAdd$2(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + return out; + } + /** + * Calculates the euclidian distance between two vec3's + * + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {Number} distance between a and b + */ + + function distance$2(a, b) { + var x = b[0] - a[0]; + var y = b[1] - a[1]; + var z = b[2] - a[2]; + return Math.hypot(x, y, z); + } + /** + * Calculates the squared euclidian distance between two vec3's + * + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {Number} squared distance between a and b + */ + + function squaredDistance$2(a, b) { + var x = b[0] - a[0]; + var y = b[1] - a[1]; + var z = b[2] - a[2]; + return x * x + y * y + z * z; + } + /** + * Calculates the squared length of a vec3 + * + * @param {ReadonlyVec3} a vector to calculate squared length of + * @returns {Number} squared length of a + */ + + function squaredLength$4(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + return x * x + y * y + z * z; + } + /** + * Negates the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to negate + * @returns {vec3} out + */ + + function negate$2(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + out[2] = -a[2]; + return out; + } + /** + * Returns the inverse of the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to invert + * @returns {vec3} out + */ + + function inverse$2(out, a) { + out[0] = 1.0 / a[0]; + out[1] = 1.0 / a[1]; + out[2] = 1.0 / a[2]; + return out; + } + /** + * Normalize a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to normalize + * @returns {vec3} out + */ + + function normalize$4(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var len = x * x + y * y + z * z; + + if (len > 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } + + out[0] = a[0] * len; + out[1] = a[1] * len; + out[2] = a[2] * len; + return out; + } + /** + * Calculates the dot product of two vec3's + * + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot$4(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + /** + * Computes the cross product of two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function cross$2(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2]; + var bx = b[0], + by = b[1], + bz = b[2]; + out[0] = ay * bz - az * by; + out[1] = az * bx - ax * bz; + out[2] = ax * by - ay * bx; + return out; + } + /** + * Performs a linear interpolation between two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec3} out + */ + + function lerp$4(out, a, b, t) { + var ax = a[0]; + var ay = a[1]; + var az = a[2]; + out[0] = ax + t * (b[0] - ax); + out[1] = ay + t * (b[1] - ay); + out[2] = az + t * (b[2] - az); + return out; + } + /** + * Performs a spherical linear interpolation between two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec3} out + */ + + function slerp$1(out, a, b, t) { + var angle = Math.acos(Math.min(Math.max(dot$4(a, b), -1), 1)); + var sinTotal = Math.sin(angle); + var ratioA = Math.sin((1 - t) * angle) / sinTotal; + var ratioB = Math.sin(t * angle) / sinTotal; + out[0] = ratioA * a[0] + ratioB * b[0]; + out[1] = ratioA * a[1] + ratioB * b[1]; + out[2] = ratioA * a[2] + ratioB * b[2]; + return out; + } + /** + * Performs a hermite interpolation with two control points + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {ReadonlyVec3} c the third operand + * @param {ReadonlyVec3} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec3} out + */ + + function hermite(out, a, b, c, d, t) { + var factorTimes2 = t * t; + var factor1 = factorTimes2 * (2 * t - 3) + 1; + var factor2 = factorTimes2 * (t - 2) + t; + var factor3 = factorTimes2 * (t - 1); + var factor4 = factorTimes2 * (3 - 2 * t); + out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; + out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; + out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; + return out; + } + /** + * Performs a bezier interpolation with two control points + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {ReadonlyVec3} c the third operand + * @param {ReadonlyVec3} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec3} out + */ + + function bezier(out, a, b, c, d, t) { + var inverseFactor = 1 - t; + var inverseFactorTimesTwo = inverseFactor * inverseFactor; + var factorTimes2 = t * t; + var factor1 = inverseFactorTimesTwo * inverseFactor; + var factor2 = 3 * t * inverseFactorTimesTwo; + var factor3 = 3 * factorTimes2 * inverseFactor; + var factor4 = factorTimes2 * t; + out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; + out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; + out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; + return out; + } + /** + * Generates a random vector with the given scale + * + * @param {vec3} out the receiving vector + * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned + * @returns {vec3} out + */ + + function random$3(out, scale) { + scale = scale === undefined ? 1.0 : scale; + var r = RANDOM() * 2.0 * Math.PI; + var z = RANDOM() * 2.0 - 1.0; + var zScale = Math.sqrt(1.0 - z * z) * scale; + out[0] = Math.cos(r) * zScale; + out[1] = Math.sin(r) * zScale; + out[2] = z * scale; + return out; + } + /** + * Transforms the vec3 with a mat4. + * 4th vector component is implicitly '1' + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with + * @returns {vec3} out + */ + + function transformMat4$2(out, a, m) { + var x = a[0], + y = a[1], + z = a[2]; + var w = m[3] * x + m[7] * y + m[11] * z + m[15]; + w = w || 1.0; + out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w; + out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w; + out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w; + return out; + } + /** + * Transforms the vec3 with a mat3. + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat3} m the 3x3 matrix to transform with + * @returns {vec3} out + */ + + function transformMat3$1(out, a, m) { + var x = a[0], + y = a[1], + z = a[2]; + out[0] = x * m[0] + y * m[3] + z * m[6]; + out[1] = x * m[1] + y * m[4] + z * m[7]; + out[2] = x * m[2] + y * m[5] + z * m[8]; + return out; + } + /** + * Transforms the vec3 with a quat + * Can also be used for dual quaternions. (Multiply it with the real part) + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyQuat} q quaternion to transform with + * @returns {vec3} out + */ + + function transformQuat$1(out, a, q) { + // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3]; + var x = a[0], + y = a[1], + z = a[2]; // var qvec = [qx, qy, qz]; + // var uv = vec3.cross([], qvec, a); + + var uvx = qy * z - qz * y, + uvy = qz * x - qx * z, + uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv); + + var uuvx = qy * uvz - qz * uvy, + uuvy = qz * uvx - qx * uvz, + uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w); + + var w2 = qw * 2; + uvx *= w2; + uvy *= w2; + uvz *= w2; // vec3.scale(uuv, uuv, 2); + + uuvx *= 2; + uuvy *= 2; + uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv)); + + out[0] = x + uvx + uuvx; + out[1] = y + uvy + uuvy; + out[2] = z + uvz + uuvz; + return out; + } + /** + * Rotate a 3D vector around the x-axis + * @param {vec3} out The receiving vec3 + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians + * @returns {vec3} out + */ + + function rotateX$2(out, a, b, rad) { + var p = [], + r = []; //Translate point to the origin + + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; //perform rotation + + r[0] = p[0]; + r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad); + r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad); //translate to correct position + + out[0] = r[0] + b[0]; + out[1] = r[1] + b[1]; + out[2] = r[2] + b[2]; + return out; + } + /** + * Rotate a 3D vector around the y-axis + * @param {vec3} out The receiving vec3 + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians + * @returns {vec3} out + */ + + function rotateY$2(out, a, b, rad) { + var p = [], + r = []; //Translate point to the origin + + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; //perform rotation + + r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad); + r[1] = p[1]; + r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad); //translate to correct position + + out[0] = r[0] + b[0]; + out[1] = r[1] + b[1]; + out[2] = r[2] + b[2]; + return out; + } + /** + * Rotate a 3D vector around the z-axis + * @param {vec3} out The receiving vec3 + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians + * @returns {vec3} out + */ + + function rotateZ$2(out, a, b, rad) { + var p = [], + r = []; //Translate point to the origin + + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; //perform rotation + + r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad); + r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad); + r[2] = p[2]; //translate to correct position + + out[0] = r[0] + b[0]; + out[1] = r[1] + b[1]; + out[2] = r[2] + b[2]; + return out; + } + /** + * Get the angle between two 3D vectors + * @param {ReadonlyVec3} a The first operand + * @param {ReadonlyVec3} b The second operand + * @returns {Number} The angle in radians + */ + + function angle$1(a, b) { + var ax = a[0], + ay = a[1], + az = a[2], + bx = b[0], + by = b[1], + bz = b[2], + mag = Math.sqrt((ax * ax + ay * ay + az * az) * (bx * bx + by * by + bz * bz)), + cosine = mag && dot$4(a, b) / mag; + return Math.acos(Math.min(Math.max(cosine, -1), 1)); + } + /** + * Set the components of a vec3 to zero + * + * @param {vec3} out the receiving vector + * @returns {vec3} out + */ + + function zero$2(out) { + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + return out; + } + /** + * Returns a string representation of a vector + * + * @param {ReadonlyVec3} a vector to represent as a string + * @returns {String} string representation of the vector + */ + + function str$4(a) { + return "vec3(" + a[0] + ", " + a[1] + ", " + a[2] + ")"; + } + /** + * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyVec3} a The first vector. + * @param {ReadonlyVec3} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function exactEquals$4(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2]; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {ReadonlyVec3} a The first vector. + * @param {ReadonlyVec3} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function equals$4(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2]; + var b0 = b[0], + b1 = b[1], + b2 = b[2]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)); + } + /** + * Alias for {@link vec3.subtract} + * @function + */ + + var sub$2 = subtract$2; + /** + * Alias for {@link vec3.multiply} + * @function + */ + + var mul$4 = multiply$4; + /** + * Alias for {@link vec3.divide} + * @function + */ + + var div$2 = divide$2; + /** + * Alias for {@link vec3.distance} + * @function + */ + + var dist$2 = distance$2; + /** + * Alias for {@link vec3.squaredDistance} + * @function + */ + + var sqrDist$2 = squaredDistance$2; + /** + * Alias for {@link vec3.length} + * @function + */ + + var len$4 = length$4; + /** + * Alias for {@link vec3.squaredLength} + * @function + */ + + var sqrLen$4 = squaredLength$4; + /** + * Perform some operation over an array of vec3s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach$2 = function () { + var vec = create$4(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 3; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + } + + return a; + }; + }(); + + var vec3 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$4, + clone: clone$4, + length: length$4, + fromValues: fromValues$4, + copy: copy$4, + set: set$4, + add: add$4, + subtract: subtract$2, + multiply: multiply$4, + divide: divide$2, + ceil: ceil$2, + floor: floor$2, + min: min$2, + max: max$2, + round: round$2, + scale: scale$4, + scaleAndAdd: scaleAndAdd$2, + distance: distance$2, + squaredDistance: squaredDistance$2, + squaredLength: squaredLength$4, + negate: negate$2, + inverse: inverse$2, + normalize: normalize$4, + dot: dot$4, + cross: cross$2, + lerp: lerp$4, + slerp: slerp$1, + hermite: hermite, + bezier: bezier, + random: random$3, + transformMat4: transformMat4$2, + transformMat3: transformMat3$1, + transformQuat: transformQuat$1, + rotateX: rotateX$2, + rotateY: rotateY$2, + rotateZ: rotateZ$2, + angle: angle$1, + zero: zero$2, + str: str$4, + exactEquals: exactEquals$4, + equals: equals$4, + sub: sub$2, + mul: mul$4, + div: div$2, + dist: dist$2, + sqrDist: sqrDist$2, + len: len$4, + sqrLen: sqrLen$4, + forEach: forEach$2 + }); + + /** + * 4 Dimensional Vector + * @module vec4 + */ + + /** + * Creates a new, empty vec4 + * + * @returns {vec4} a new 4D vector + */ + + function create$3() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 0; + } + + return out; + } + /** + * Creates a new vec4 initialized with values from an existing vector + * + * @param {ReadonlyVec4} a vector to clone + * @returns {vec4} a new 4D vector + */ + + function clone$3(a) { + var out = new ARRAY_TYPE(4); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Creates a new vec4 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} a new 4D vector + */ + + function fromValues$3(x, y, z, w) { + var out = new ARRAY_TYPE(4); + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Copy the values from one vec4 to another + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the source vector + * @returns {vec4} out + */ + + function copy$3(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Set the components of a vec4 to the given values + * + * @param {vec4} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} out + */ + + function set$3(out, x, y, z, w) { + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Adds two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function add$3(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function subtract$1(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + return out; + } + /** + * Multiplies two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function multiply$3(out, a, b) { + out[0] = a[0] * b[0]; + out[1] = a[1] * b[1]; + out[2] = a[2] * b[2]; + out[3] = a[3] * b[3]; + return out; + } + /** + * Divides two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function divide$1(out, a, b) { + out[0] = a[0] / b[0]; + out[1] = a[1] / b[1]; + out[2] = a[2] / b[2]; + out[3] = a[3] / b[3]; + return out; + } + /** + * Math.ceil the components of a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to ceil + * @returns {vec4} out + */ + + function ceil$1(out, a) { + out[0] = Math.ceil(a[0]); + out[1] = Math.ceil(a[1]); + out[2] = Math.ceil(a[2]); + out[3] = Math.ceil(a[3]); + return out; + } + /** + * Math.floor the components of a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to floor + * @returns {vec4} out + */ + + function floor$1(out, a) { + out[0] = Math.floor(a[0]); + out[1] = Math.floor(a[1]); + out[2] = Math.floor(a[2]); + out[3] = Math.floor(a[3]); + return out; + } + /** + * Returns the minimum of two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function min$1(out, a, b) { + out[0] = Math.min(a[0], b[0]); + out[1] = Math.min(a[1], b[1]); + out[2] = Math.min(a[2], b[2]); + out[3] = Math.min(a[3], b[3]); + return out; + } + /** + * Returns the maximum of two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function max$1(out, a, b) { + out[0] = Math.max(a[0], b[0]); + out[1] = Math.max(a[1], b[1]); + out[2] = Math.max(a[2], b[2]); + out[3] = Math.max(a[3], b[3]); + return out; + } + /** + * Math.round the components of a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to round + * @returns {vec4} out + */ + + function round$1(out, a) { + out[0] = Math.round(a[0]); + out[1] = Math.round(a[1]); + out[2] = Math.round(a[2]); + out[3] = Math.round(a[3]); + return out; + } + /** + * Scales a vec4 by a scalar number + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec4} out + */ + + function scale$3(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + return out; + } + /** + * Adds two vec4's after scaling the second operand by a scalar value + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @param {Number} scale the amount to scale b by before adding + * @returns {vec4} out + */ + + function scaleAndAdd$1(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + return out; + } + /** + * Calculates the euclidian distance between two vec4's + * + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {Number} distance between a and b + */ + + function distance$1(a, b) { + var x = b[0] - a[0]; + var y = b[1] - a[1]; + var z = b[2] - a[2]; + var w = b[3] - a[3]; + return Math.hypot(x, y, z, w); + } + /** + * Calculates the squared euclidian distance between two vec4's + * + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {Number} squared distance between a and b + */ + + function squaredDistance$1(a, b) { + var x = b[0] - a[0]; + var y = b[1] - a[1]; + var z = b[2] - a[2]; + var w = b[3] - a[3]; + return x * x + y * y + z * z + w * w; + } + /** + * Calculates the length of a vec4 + * + * @param {ReadonlyVec4} a vector to calculate length of + * @returns {Number} length of a + */ + + function length$3(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var w = a[3]; + return Math.hypot(x, y, z, w); + } + /** + * Calculates the squared length of a vec4 + * + * @param {ReadonlyVec4} a vector to calculate squared length of + * @returns {Number} squared length of a + */ + + function squaredLength$3(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var w = a[3]; + return x * x + y * y + z * z + w * w; + } + /** + * Negates the components of a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to negate + * @returns {vec4} out + */ + + function negate$1(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + out[2] = -a[2]; + out[3] = -a[3]; + return out; + } + /** + * Returns the inverse of the components of a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to invert + * @returns {vec4} out + */ + + function inverse$1(out, a) { + out[0] = 1.0 / a[0]; + out[1] = 1.0 / a[1]; + out[2] = 1.0 / a[2]; + out[3] = 1.0 / a[3]; + return out; + } + /** + * Normalize a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to normalize + * @returns {vec4} out + */ + + function normalize$3(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var w = a[3]; + var len = x * x + y * y + z * z + w * w; + + if (len > 0) { + len = 1 / Math.sqrt(len); + } + + out[0] = x * len; + out[1] = y * len; + out[2] = z * len; + out[3] = w * len; + return out; + } + /** + * Calculates the dot product of two vec4's + * + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot$3(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; + } + /** + * Returns the cross-product of three vectors in a 4-dimensional space + * + * @param {ReadonlyVec4} result the receiving vector + * @param {ReadonlyVec4} U the first vector + * @param {ReadonlyVec4} V the second vector + * @param {ReadonlyVec4} W the third vector + * @returns {vec4} result + */ + + function cross$1(out, u, v, w) { + var A = v[0] * w[1] - v[1] * w[0], + B = v[0] * w[2] - v[2] * w[0], + C = v[0] * w[3] - v[3] * w[0], + D = v[1] * w[2] - v[2] * w[1], + E = v[1] * w[3] - v[3] * w[1], + F = v[2] * w[3] - v[3] * w[2]; + var G = u[0]; + var H = u[1]; + var I = u[2]; + var J = u[3]; + out[0] = H * F - I * E + J * D; + out[1] = -(G * F) + I * C - J * B; + out[2] = G * E - H * C + J * A; + out[3] = -(G * D) + H * B - I * A; + return out; + } + /** + * Performs a linear interpolation between two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec4} out + */ + + function lerp$3(out, a, b, t) { + var ax = a[0]; + var ay = a[1]; + var az = a[2]; + var aw = a[3]; + out[0] = ax + t * (b[0] - ax); + out[1] = ay + t * (b[1] - ay); + out[2] = az + t * (b[2] - az); + out[3] = aw + t * (b[3] - aw); + return out; + } + /** + * Generates a random vector with the given scale + * + * @param {vec4} out the receiving vector + * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned + * @returns {vec4} out + */ + + function random$2(out, scale) { + scale = scale === undefined ? 1.0 : scale; // Marsaglia, George. Choosing a Point from the Surface of a + // Sphere. Ann. Math. Statist. 43 (1972), no. 2, 645--646. + // http://projecteuclid.org/euclid.aoms/1177692644; + + var v1, v2, v3, v4; + var s1, s2; + + do { + v1 = RANDOM() * 2 - 1; + v2 = RANDOM() * 2 - 1; + s1 = v1 * v1 + v2 * v2; + } while (s1 >= 1); + + do { + v3 = RANDOM() * 2 - 1; + v4 = RANDOM() * 2 - 1; + s2 = v3 * v3 + v4 * v4; + } while (s2 >= 1); + + var d = Math.sqrt((1 - s1) / s2); + out[0] = scale * v1; + out[1] = scale * v2; + out[2] = scale * v3 * d; + out[3] = scale * v4 * d; + return out; + } + /** + * Transforms the vec4 with a mat4. + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with + * @returns {vec4} out + */ + + function transformMat4$1(out, a, m) { + var x = a[0], + y = a[1], + z = a[2], + w = a[3]; + out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; + out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; + out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; + out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; + return out; + } + /** + * Transforms the vec4 with a quat + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the vector to transform + * @param {ReadonlyQuat} q quaternion to transform with + * @returns {vec4} out + */ + + function transformQuat(out, a, q) { + var x = a[0], + y = a[1], + z = a[2]; + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3]; // calculate quat * vec + + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + + out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; + out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; + out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; + out[3] = a[3]; + return out; + } + /** + * Set the components of a vec4 to zero + * + * @param {vec4} out the receiving vector + * @returns {vec4} out + */ + + function zero$1(out) { + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + return out; + } + /** + * Returns a string representation of a vector + * + * @param {ReadonlyVec4} a vector to represent as a string + * @returns {String} string representation of the vector + */ + + function str$3(a) { + return "vec4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; + } + /** + * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function exactEquals$3(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function equals$3(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)); + } + /** + * Alias for {@link vec4.subtract} + * @function + */ + + var sub$1 = subtract$1; + /** + * Alias for {@link vec4.multiply} + * @function + */ + + var mul$3 = multiply$3; + /** + * Alias for {@link vec4.divide} + * @function + */ + + var div$1 = divide$1; + /** + * Alias for {@link vec4.distance} + * @function + */ + + var dist$1 = distance$1; + /** + * Alias for {@link vec4.squaredDistance} + * @function + */ + + var sqrDist$1 = squaredDistance$1; + /** + * Alias for {@link vec4.length} + * @function + */ + + var len$3 = length$3; + /** + * Alias for {@link vec4.squaredLength} + * @function + */ + + var sqrLen$3 = squaredLength$3; + /** + * Perform some operation over an array of vec4s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach$1 = function () { + var vec = create$3(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 4; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + vec[3] = a[i + 3]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + a[i + 3] = vec[3]; + } + + return a; + }; + }(); + + var vec4 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$3, + clone: clone$3, + fromValues: fromValues$3, + copy: copy$3, + set: set$3, + add: add$3, + subtract: subtract$1, + multiply: multiply$3, + divide: divide$1, + ceil: ceil$1, + floor: floor$1, + min: min$1, + max: max$1, + round: round$1, + scale: scale$3, + scaleAndAdd: scaleAndAdd$1, + distance: distance$1, + squaredDistance: squaredDistance$1, + length: length$3, + squaredLength: squaredLength$3, + negate: negate$1, + inverse: inverse$1, + normalize: normalize$3, + dot: dot$3, + cross: cross$1, + lerp: lerp$3, + random: random$2, + transformMat4: transformMat4$1, + transformQuat: transformQuat, + zero: zero$1, + str: str$3, + exactEquals: exactEquals$3, + equals: equals$3, + sub: sub$1, + mul: mul$3, + div: div$1, + dist: dist$1, + sqrDist: sqrDist$1, + len: len$3, + sqrLen: sqrLen$3, + forEach: forEach$1 + }); + + /** + * Quaternion in the format XYZW + * @module quat + */ + + /** + * Creates a new identity quat + * + * @returns {quat} a new quaternion + */ + + function create$2() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + out[3] = 1; + return out; + } + /** + * Set a quat to the identity quaternion + * + * @param {quat} out the receiving quaternion + * @returns {quat} out + */ + + function identity$1(out) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } + /** + * Sets a quat from the given angle and rotation axis, + * then returns it. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyVec3} axis the axis around which to rotate + * @param {Number} rad the angle in radians + * @returns {quat} out + **/ + + function setAxisAngle(out, axis, rad) { + rad = rad * 0.5; + var s = Math.sin(rad); + out[0] = s * axis[0]; + out[1] = s * axis[1]; + out[2] = s * axis[2]; + out[3] = Math.cos(rad); + return out; + } + /** + * Gets the rotation axis and angle for a given + * quaternion. If a quaternion is created with + * setAxisAngle, this method will return the same + * values as providied in the original parameter list + * OR functionally equivalent values. + * Example: The quaternion formed by axis [0, 0, 1] and + * angle -90 is the same as the quaternion formed by + * [0, 0, 1] and 270. This method favors the latter. + * @param {vec3} out_axis Vector receiving the axis of rotation + * @param {ReadonlyQuat} q Quaternion to be decomposed + * @return {Number} Angle, in radians, of the rotation + */ + + function getAxisAngle(out_axis, q) { + var rad = Math.acos(q[3]) * 2.0; + var s = Math.sin(rad / 2.0); + + if (s > EPSILON) { + out_axis[0] = q[0] / s; + out_axis[1] = q[1] / s; + out_axis[2] = q[2] / s; + } else { + // If s is zero, return any axis (no rotation - axis does not matter) + out_axis[0] = 1; + out_axis[1] = 0; + out_axis[2] = 0; + } + + return rad; + } + /** + * Gets the angular distance between two unit quaternions + * + * @param {ReadonlyQuat} a Origin unit quaternion + * @param {ReadonlyQuat} b Destination unit quaternion + * @return {Number} Angle, in radians, between the two quaternions + */ + + function getAngle(a, b) { + var dotproduct = dot$2(a, b); + return Math.acos(2 * dotproduct * dotproduct - 1); + } + /** + * Multiplies two quat's + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @returns {quat} out + */ + + function multiply$2(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + out[0] = ax * bw + aw * bx + ay * bz - az * by; + out[1] = ay * bw + aw * by + az * bx - ax * bz; + out[2] = az * bw + aw * bz + ax * by - ay * bx; + out[3] = aw * bw - ax * bx - ay * by - az * bz; + return out; + } + /** + * Rotates a quaternion by the given angle about the X axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateX$1(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw + aw * bx; + out[1] = ay * bw + az * bx; + out[2] = az * bw - ay * bx; + out[3] = aw * bw - ax * bx; + return out; + } + /** + * Rotates a quaternion by the given angle about the Y axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateY$1(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var by = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw - az * by; + out[1] = ay * bw + aw * by; + out[2] = az * bw + ax * by; + out[3] = aw * bw - ay * by; + return out; + } + /** + * Rotates a quaternion by the given angle about the Z axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateZ$1(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bz = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw + ay * bz; + out[1] = ay * bw - ax * bz; + out[2] = az * bw + aw * bz; + out[3] = aw * bw - az * bz; + return out; + } + /** + * Calculates the W component of a quat from the X, Y, and Z components. + * Assumes that quaternion is 1 unit in length. + * Any existing W component will be ignored. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate W component of + * @returns {quat} out + */ + + function calculateW(out, a) { + var x = a[0], + y = a[1], + z = a[2]; + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z)); + return out; + } + /** + * Calculate the exponential of a unit quaternion. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate the exponential of + * @returns {quat} out + */ + + function exp(out, a) { + var x = a[0], + y = a[1], + z = a[2], + w = a[3]; + var r = Math.sqrt(x * x + y * y + z * z); + var et = Math.exp(w); + var s = r > 0 ? et * Math.sin(r) / r : 0; + out[0] = x * s; + out[1] = y * s; + out[2] = z * s; + out[3] = et * Math.cos(r); + return out; + } + /** + * Calculate the natural logarithm of a unit quaternion. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate the exponential of + * @returns {quat} out + */ + + function ln(out, a) { + var x = a[0], + y = a[1], + z = a[2], + w = a[3]; + var r = Math.sqrt(x * x + y * y + z * z); + var t = r > 0 ? Math.atan2(r, w) / r : 0; + out[0] = x * t; + out[1] = y * t; + out[2] = z * t; + out[3] = 0.5 * Math.log(x * x + y * y + z * z + w * w); + return out; + } + /** + * Calculate the scalar power of a unit quaternion. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate the exponential of + * @param {Number} b amount to scale the quaternion by + * @returns {quat} out + */ + + function pow(out, a, b) { + ln(out, a); + scale$2(out, out, b); + exp(out, out); + return out; + } + /** + * Performs a spherical linear interpolation between two quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + function slerp(out, a, b, t) { + // benchmarks: + // http://jsperf.com/quaternion-slerp-implementations + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + var omega, cosom, sinom, scale0, scale1; // calc cosine + + cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) + + if (cosom < 0.0) { + cosom = -cosom; + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + } // calculate coefficients + + + if (1.0 - cosom > EPSILON) { + // standard case (slerp) + omega = Math.acos(cosom); + sinom = Math.sin(omega); + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } else { + // "from" and "to" quaternions are very close + // ... so we can do a linear interpolation + scale0 = 1.0 - t; + scale1 = t; + } // calculate final values + + + out[0] = scale0 * ax + scale1 * bx; + out[1] = scale0 * ay + scale1 * by; + out[2] = scale0 * az + scale1 * bz; + out[3] = scale0 * aw + scale1 * bw; + return out; + } + /** + * Generates a random unit quaternion + * + * @param {quat} out the receiving quaternion + * @returns {quat} out + */ + + function random$1(out) { + // Implementation of http://planning.cs.uiuc.edu/node198.html + // TODO: Calling random 3 times is probably not the fastest solution + var u1 = RANDOM(); + var u2 = RANDOM(); + var u3 = RANDOM(); + var sqrt1MinusU1 = Math.sqrt(1 - u1); + var sqrtU1 = Math.sqrt(u1); + out[0] = sqrt1MinusU1 * Math.sin(2.0 * Math.PI * u2); + out[1] = sqrt1MinusU1 * Math.cos(2.0 * Math.PI * u2); + out[2] = sqrtU1 * Math.sin(2.0 * Math.PI * u3); + out[3] = sqrtU1 * Math.cos(2.0 * Math.PI * u3); + return out; + } + /** + * Calculates the inverse of a quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate inverse of + * @returns {quat} out + */ + + function invert$1(out, a) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3; + var invDot = dot ? 1.0 / dot : 0; // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0 + + out[0] = -a0 * invDot; + out[1] = -a1 * invDot; + out[2] = -a2 * invDot; + out[3] = a3 * invDot; + return out; + } + /** + * Calculates the conjugate of a quat + * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate conjugate of + * @returns {quat} out + */ + + function conjugate$1(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + out[2] = -a[2]; + out[3] = a[3]; + return out; + } + /** + * Creates a quaternion from the given 3x3 rotation matrix. + * + * NOTE: The resultant quaternion is not normalized, so you should be sure + * to renormalize the quaternion yourself where necessary. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyMat3} m rotation matrix + * @returns {quat} out + * @function + */ + + function fromMat3(out, m) { + // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes + // article "Quaternion Calculus and Fast Animation". + var fTrace = m[0] + m[4] + m[8]; + var fRoot; + + if (fTrace > 0.0) { + // |w| > 1/2, may as well choose w > 1/2 + fRoot = Math.sqrt(fTrace + 1.0); // 2w + + out[3] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; // 1/(4w) + + out[0] = (m[5] - m[7]) * fRoot; + out[1] = (m[6] - m[2]) * fRoot; + out[2] = (m[1] - m[3]) * fRoot; + } else { + // |w| <= 1/2 + var i = 0; + if (m[4] > m[0]) i = 1; + if (m[8] > m[i * 3 + i]) i = 2; + var j = (i + 1) % 3; + var k = (i + 2) % 3; + fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0); + out[i] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; + out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot; + out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot; + out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot; + } + + return out; + } + /** + * Creates a quaternion from the given euler angle x, y, z using the provided intrinsic order for the conversion. + * + * @param {quat} out the receiving quaternion + * @param {x} x Angle to rotate around X axis in degrees. + * @param {y} y Angle to rotate around Y axis in degrees. + * @param {z} z Angle to rotate around Z axis in degrees. + * @param {'zyx'|'xyz'|'yxz'|'yzx'|'zxy'|'zyx'} order Intrinsic order for conversion, default is zyx. + * @returns {quat} out + * @function + */ + + function fromEuler(out, x, y, z) { + var order = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : ANGLE_ORDER; + var halfToRad = Math.PI / 360; + x *= halfToRad; + z *= halfToRad; + y *= halfToRad; + var sx = Math.sin(x); + var cx = Math.cos(x); + var sy = Math.sin(y); + var cy = Math.cos(y); + var sz = Math.sin(z); + var cz = Math.cos(z); + + switch (order) { + case "xyz": + out[0] = sx * cy * cz + cx * sy * sz; + out[1] = cx * sy * cz - sx * cy * sz; + out[2] = cx * cy * sz + sx * sy * cz; + out[3] = cx * cy * cz - sx * sy * sz; + break; + + case "xzy": + out[0] = sx * cy * cz - cx * sy * sz; + out[1] = cx * sy * cz - sx * cy * sz; + out[2] = cx * cy * sz + sx * sy * cz; + out[3] = cx * cy * cz + sx * sy * sz; + break; + + case "yxz": + out[0] = sx * cy * cz + cx * sy * sz; + out[1] = cx * sy * cz - sx * cy * sz; + out[2] = cx * cy * sz - sx * sy * cz; + out[3] = cx * cy * cz + sx * sy * sz; + break; + + case "yzx": + out[0] = sx * cy * cz + cx * sy * sz; + out[1] = cx * sy * cz + sx * cy * sz; + out[2] = cx * cy * sz - sx * sy * cz; + out[3] = cx * cy * cz - sx * sy * sz; + break; + + case "zxy": + out[0] = sx * cy * cz - cx * sy * sz; + out[1] = cx * sy * cz + sx * cy * sz; + out[2] = cx * cy * sz + sx * sy * cz; + out[3] = cx * cy * cz - sx * sy * sz; + break; + + case "zyx": + out[0] = sx * cy * cz - cx * sy * sz; + out[1] = cx * sy * cz + sx * cy * sz; + out[2] = cx * cy * sz - sx * sy * cz; + out[3] = cx * cy * cz + sx * sy * sz; + break; + + default: + throw new Error('Unknown angle order ' + order); + } + + return out; + } + /** + * Returns a string representation of a quaternion + * + * @param {ReadonlyQuat} a vector to represent as a string + * @returns {String} string representation of the vector + */ + + function str$2(a) { + return "quat(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; + } + /** + * Creates a new quat initialized with values from an existing quaternion + * + * @param {ReadonlyQuat} a quaternion to clone + * @returns {quat} a new quaternion + * @function + */ + + var clone$2 = clone$3; + /** + * Creates a new quat initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} a new quaternion + * @function + */ + + var fromValues$2 = fromValues$3; + /** + * Copy the values from one quat to another + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the source quaternion + * @returns {quat} out + * @function + */ + + var copy$2 = copy$3; + /** + * Set the components of a quat to the given values + * + * @param {quat} out the receiving quaternion + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} out + * @function + */ + + var set$2 = set$3; + /** + * Adds two quat's + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @returns {quat} out + * @function + */ + + var add$2 = add$3; + /** + * Alias for {@link quat.multiply} + * @function + */ + + var mul$2 = multiply$2; + /** + * Scales a quat by a scalar number + * + * @param {quat} out the receiving vector + * @param {ReadonlyQuat} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {quat} out + * @function + */ + + var scale$2 = scale$3; + /** + * Calculates the dot product of two quat's + * + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @returns {Number} dot product of a and b + * @function + */ + + var dot$2 = dot$3; + /** + * Performs a linear interpolation between two quat's + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + * @function + */ + + var lerp$2 = lerp$3; + /** + * Calculates the length of a quat + * + * @param {ReadonlyQuat} a vector to calculate length of + * @returns {Number} length of a + */ + + var length$2 = length$3; + /** + * Alias for {@link quat.length} + * @function + */ + + var len$2 = length$2; + /** + * Calculates the squared length of a quat + * + * @param {ReadonlyQuat} a vector to calculate squared length of + * @returns {Number} squared length of a + * @function + */ + + var squaredLength$2 = squaredLength$3; + /** + * Alias for {@link quat.squaredLength} + * @function + */ + + var sqrLen$2 = squaredLength$2; + /** + * Normalize a quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quaternion to normalize + * @returns {quat} out + * @function + */ + + var normalize$2 = normalize$3; + /** + * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyQuat} a The first quaternion. + * @param {ReadonlyQuat} b The second quaternion. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + var exactEquals$2 = exactEquals$3; + /** + * Returns whether or not the quaternions point approximately to the same direction. + * + * Both quaternions are assumed to be unit length. + * + * @param {ReadonlyQuat} a The first unit quaternion. + * @param {ReadonlyQuat} b The second unit quaternion. + * @returns {Boolean} True if the quaternions are equal, false otherwise. + */ + + function equals$2(a, b) { + return Math.abs(dot$3(a, b)) >= 1 - EPSILON; + } + /** + * Sets a quaternion to represent the shortest rotation from one + * vector to another. + * + * Both vectors are assumed to be unit length. + * + * @param {quat} out the receiving quaternion. + * @param {ReadonlyVec3} a the initial vector + * @param {ReadonlyVec3} b the destination vector + * @returns {quat} out + */ + + var rotationTo = function () { + var tmpvec3 = create$4(); + var xUnitVec3 = fromValues$4(1, 0, 0); + var yUnitVec3 = fromValues$4(0, 1, 0); + return function (out, a, b) { + var dot = dot$4(a, b); + + if (dot < -0.999999) { + cross$2(tmpvec3, xUnitVec3, a); + if (len$4(tmpvec3) < 0.000001) cross$2(tmpvec3, yUnitVec3, a); + normalize$4(tmpvec3, tmpvec3); + setAxisAngle(out, tmpvec3, Math.PI); + return out; + } else if (dot > 0.999999) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } else { + cross$2(tmpvec3, a, b); + out[0] = tmpvec3[0]; + out[1] = tmpvec3[1]; + out[2] = tmpvec3[2]; + out[3] = 1 + dot; + return normalize$2(out, out); + } + }; + }(); + /** + * Performs a spherical linear interpolation with two control points + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {ReadonlyQuat} c the third operand + * @param {ReadonlyQuat} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + var sqlerp = function () { + var temp1 = create$2(); + var temp2 = create$2(); + return function (out, a, b, c, d, t) { + slerp(temp1, a, d, t); + slerp(temp2, b, c, t); + slerp(out, temp1, temp2, 2 * t * (1 - t)); + return out; + }; + }(); + /** + * Sets the specified quaternion with values corresponding to the given + * axes. Each axis is a vec3 and is expected to be unit length and + * perpendicular to all other specified axes. + * + * @param {ReadonlyVec3} view the vector representing the viewing direction + * @param {ReadonlyVec3} right the vector representing the local "right" direction + * @param {ReadonlyVec3} up the vector representing the local "up" direction + * @returns {quat} out + */ + + var setAxes = function () { + var matr = create$6(); + return function (out, view, right, up) { + matr[0] = right[0]; + matr[3] = right[1]; + matr[6] = right[2]; + matr[1] = up[0]; + matr[4] = up[1]; + matr[7] = up[2]; + matr[2] = -view[0]; + matr[5] = -view[1]; + matr[8] = -view[2]; + return normalize$2(out, fromMat3(out, matr)); + }; + }(); + + var quat = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$2, + identity: identity$1, + setAxisAngle: setAxisAngle, + getAxisAngle: getAxisAngle, + getAngle: getAngle, + multiply: multiply$2, + rotateX: rotateX$1, + rotateY: rotateY$1, + rotateZ: rotateZ$1, + calculateW: calculateW, + exp: exp, + ln: ln, + pow: pow, + slerp: slerp, + random: random$1, + invert: invert$1, + conjugate: conjugate$1, + fromMat3: fromMat3, + fromEuler: fromEuler, + str: str$2, + clone: clone$2, + fromValues: fromValues$2, + copy: copy$2, + set: set$2, + add: add$2, + mul: mul$2, + scale: scale$2, + dot: dot$2, + lerp: lerp$2, + length: length$2, + len: len$2, + squaredLength: squaredLength$2, + sqrLen: sqrLen$2, + normalize: normalize$2, + exactEquals: exactEquals$2, + equals: equals$2, + rotationTo: rotationTo, + sqlerp: sqlerp, + setAxes: setAxes + }); + + /** + * Dual Quaternion
+ * Format: [real, dual]
+ * Quaternion format: XYZW
+ * Make sure to have normalized dual quaternions, otherwise the functions may not work as intended.
+ * @module quat2 + */ + + /** + * Creates a new identity dual quat + * + * @returns {quat2} a new dual quaternion [real -> rotation, dual -> translation] + */ + + function create$1() { + var dq = new ARRAY_TYPE(8); + + if (ARRAY_TYPE != Float32Array) { + dq[0] = 0; + dq[1] = 0; + dq[2] = 0; + dq[4] = 0; + dq[5] = 0; + dq[6] = 0; + dq[7] = 0; + } + + dq[3] = 1; + return dq; + } + /** + * Creates a new quat initialized with values from an existing quaternion + * + * @param {ReadonlyQuat2} a dual quaternion to clone + * @returns {quat2} new dual quaternion + * @function + */ + + function clone$1(a) { + var dq = new ARRAY_TYPE(8); + dq[0] = a[0]; + dq[1] = a[1]; + dq[2] = a[2]; + dq[3] = a[3]; + dq[4] = a[4]; + dq[5] = a[5]; + dq[6] = a[6]; + dq[7] = a[7]; + return dq; + } + /** + * Creates a new dual quat initialized with the given values + * + * @param {Number} x1 X component + * @param {Number} y1 Y component + * @param {Number} z1 Z component + * @param {Number} w1 W component + * @param {Number} x2 X component + * @param {Number} y2 Y component + * @param {Number} z2 Z component + * @param {Number} w2 W component + * @returns {quat2} new dual quaternion + * @function + */ + + function fromValues$1(x1, y1, z1, w1, x2, y2, z2, w2) { + var dq = new ARRAY_TYPE(8); + dq[0] = x1; + dq[1] = y1; + dq[2] = z1; + dq[3] = w1; + dq[4] = x2; + dq[5] = y2; + dq[6] = z2; + dq[7] = w2; + return dq; + } + /** + * Creates a new dual quat from the given values (quat and translation) + * + * @param {Number} x1 X component + * @param {Number} y1 Y component + * @param {Number} z1 Z component + * @param {Number} w1 W component + * @param {Number} x2 X component (translation) + * @param {Number} y2 Y component (translation) + * @param {Number} z2 Z component (translation) + * @returns {quat2} new dual quaternion + * @function + */ + + function fromRotationTranslationValues(x1, y1, z1, w1, x2, y2, z2) { + var dq = new ARRAY_TYPE(8); + dq[0] = x1; + dq[1] = y1; + dq[2] = z1; + dq[3] = w1; + var ax = x2 * 0.5, + ay = y2 * 0.5, + az = z2 * 0.5; + dq[4] = ax * w1 + ay * z1 - az * y1; + dq[5] = ay * w1 + az * x1 - ax * z1; + dq[6] = az * w1 + ax * y1 - ay * x1; + dq[7] = -ax * x1 - ay * y1 - az * z1; + return dq; + } + /** + * Creates a dual quat from a quaternion and a translation + * + * @param {ReadonlyQuat2} dual quaternion receiving operation result + * @param {ReadonlyQuat} q a normalized quaternion + * @param {ReadonlyVec3} t translation vector + * @returns {quat2} dual quaternion receiving operation result + * @function + */ + + function fromRotationTranslation(out, q, t) { + var ax = t[0] * 0.5, + ay = t[1] * 0.5, + az = t[2] * 0.5, + bx = q[0], + by = q[1], + bz = q[2], + bw = q[3]; + out[0] = bx; + out[1] = by; + out[2] = bz; + out[3] = bw; + out[4] = ax * bw + ay * bz - az * by; + out[5] = ay * bw + az * bx - ax * bz; + out[6] = az * bw + ax * by - ay * bx; + out[7] = -ax * bx - ay * by - az * bz; + return out; + } + /** + * Creates a dual quat from a translation + * + * @param {ReadonlyQuat2} dual quaternion receiving operation result + * @param {ReadonlyVec3} t translation vector + * @returns {quat2} dual quaternion receiving operation result + * @function + */ + + function fromTranslation(out, t) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = t[0] * 0.5; + out[5] = t[1] * 0.5; + out[6] = t[2] * 0.5; + out[7] = 0; + return out; + } + /** + * Creates a dual quat from a quaternion + * + * @param {ReadonlyQuat2} dual quaternion receiving operation result + * @param {ReadonlyQuat} q the quaternion + * @returns {quat2} dual quaternion receiving operation result + * @function + */ + + function fromRotation(out, q) { + out[0] = q[0]; + out[1] = q[1]; + out[2] = q[2]; + out[3] = q[3]; + out[4] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + return out; + } + /** + * Creates a new dual quat from a matrix (4x4) + * + * @param {quat2} out the dual quaternion + * @param {ReadonlyMat4} a the matrix + * @returns {quat2} dual quat receiving operation result + * @function + */ + + function fromMat4(out, a) { + //TODO Optimize this + var outer = create$2(); + getRotation(outer, a); + var t = new ARRAY_TYPE(3); + getTranslation$1(t, a); + fromRotationTranslation(out, outer, t); + return out; + } + /** + * Copy the values from one dual quat to another + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the source dual quaternion + * @returns {quat2} out + * @function + */ + + function copy$1(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + return out; + } + /** + * Set a dual quat to the identity dual quaternion + * + * @param {quat2} out the receiving quaternion + * @returns {quat2} out + */ + + function identity(out) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + return out; + } + /** + * Set the components of a dual quat to the given values + * + * @param {quat2} out the receiving quaternion + * @param {Number} x1 X component + * @param {Number} y1 Y component + * @param {Number} z1 Z component + * @param {Number} w1 W component + * @param {Number} x2 X component + * @param {Number} y2 Y component + * @param {Number} z2 Z component + * @param {Number} w2 W component + * @returns {quat2} out + * @function + */ + + function set$1(out, x1, y1, z1, w1, x2, y2, z2, w2) { + out[0] = x1; + out[1] = y1; + out[2] = z1; + out[3] = w1; + out[4] = x2; + out[5] = y2; + out[6] = z2; + out[7] = w2; + return out; + } + /** + * Gets the real part of a dual quat + * @param {quat} out real part + * @param {ReadonlyQuat2} a Dual Quaternion + * @return {quat} real part + */ + + var getReal = copy$2; + /** + * Gets the dual part of a dual quat + * @param {quat} out dual part + * @param {ReadonlyQuat2} a Dual Quaternion + * @return {quat} dual part + */ + + function getDual(out, a) { + out[0] = a[4]; + out[1] = a[5]; + out[2] = a[6]; + out[3] = a[7]; + return out; + } + /** + * Set the real component of a dual quat to the given quaternion + * + * @param {quat2} out the receiving quaternion + * @param {ReadonlyQuat} q a quaternion representing the real part + * @returns {quat2} out + * @function + */ + + var setReal = copy$2; + /** + * Set the dual component of a dual quat to the given quaternion + * + * @param {quat2} out the receiving quaternion + * @param {ReadonlyQuat} q a quaternion representing the dual part + * @returns {quat2} out + * @function + */ + + function setDual(out, q) { + out[4] = q[0]; + out[5] = q[1]; + out[6] = q[2]; + out[7] = q[3]; + return out; + } + /** + * Gets the translation of a normalized dual quat + * @param {vec3} out translation + * @param {ReadonlyQuat2} a Dual Quaternion to be decomposed + * @return {vec3} translation + */ + + function getTranslation(out, a) { + var ax = a[4], + ay = a[5], + az = a[6], + aw = a[7], + bx = -a[0], + by = -a[1], + bz = -a[2], + bw = a[3]; + out[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2; + out[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2; + out[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2; + return out; + } + /** + * Translates a dual quat by the given vector + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to translate + * @param {ReadonlyVec3} v vector to translate by + * @returns {quat2} out + */ + + function translate(out, a, v) { + var ax1 = a[0], + ay1 = a[1], + az1 = a[2], + aw1 = a[3], + bx1 = v[0] * 0.5, + by1 = v[1] * 0.5, + bz1 = v[2] * 0.5, + ax2 = a[4], + ay2 = a[5], + az2 = a[6], + aw2 = a[7]; + out[0] = ax1; + out[1] = ay1; + out[2] = az1; + out[3] = aw1; + out[4] = aw1 * bx1 + ay1 * bz1 - az1 * by1 + ax2; + out[5] = aw1 * by1 + az1 * bx1 - ax1 * bz1 + ay2; + out[6] = aw1 * bz1 + ax1 * by1 - ay1 * bx1 + az2; + out[7] = -ax1 * bx1 - ay1 * by1 - az1 * bz1 + aw2; + return out; + } + /** + * Rotates a dual quat around the X axis + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {number} rad how far should the rotation be + * @returns {quat2} out + */ + + function rotateX(out, a, rad) { + var bx = -a[0], + by = -a[1], + bz = -a[2], + bw = a[3], + ax = a[4], + ay = a[5], + az = a[6], + aw = a[7], + ax1 = ax * bw + aw * bx + ay * bz - az * by, + ay1 = ay * bw + aw * by + az * bx - ax * bz, + az1 = az * bw + aw * bz + ax * by - ay * bx, + aw1 = aw * bw - ax * bx - ay * by - az * bz; + rotateX$1(out, a, rad); + bx = out[0]; + by = out[1]; + bz = out[2]; + bw = out[3]; + out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; + out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; + out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; + out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; + return out; + } + /** + * Rotates a dual quat around the Y axis + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {number} rad how far should the rotation be + * @returns {quat2} out + */ + + function rotateY(out, a, rad) { + var bx = -a[0], + by = -a[1], + bz = -a[2], + bw = a[3], + ax = a[4], + ay = a[5], + az = a[6], + aw = a[7], + ax1 = ax * bw + aw * bx + ay * bz - az * by, + ay1 = ay * bw + aw * by + az * bx - ax * bz, + az1 = az * bw + aw * bz + ax * by - ay * bx, + aw1 = aw * bw - ax * bx - ay * by - az * bz; + rotateY$1(out, a, rad); + bx = out[0]; + by = out[1]; + bz = out[2]; + bw = out[3]; + out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; + out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; + out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; + out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; + return out; + } + /** + * Rotates a dual quat around the Z axis + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {number} rad how far should the rotation be + * @returns {quat2} out + */ + + function rotateZ(out, a, rad) { + var bx = -a[0], + by = -a[1], + bz = -a[2], + bw = a[3], + ax = a[4], + ay = a[5], + az = a[6], + aw = a[7], + ax1 = ax * bw + aw * bx + ay * bz - az * by, + ay1 = ay * bw + aw * by + az * bx - ax * bz, + az1 = az * bw + aw * bz + ax * by - ay * bx, + aw1 = aw * bw - ax * bx - ay * by - az * bz; + rotateZ$1(out, a, rad); + bx = out[0]; + by = out[1]; + bz = out[2]; + bw = out[3]; + out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; + out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; + out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; + out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; + return out; + } + /** + * Rotates a dual quat by a given quaternion (a * q) + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {ReadonlyQuat} q quaternion to rotate by + * @returns {quat2} out + */ + + function rotateByQuatAppend(out, a, q) { + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3], + ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + out[0] = ax * qw + aw * qx + ay * qz - az * qy; + out[1] = ay * qw + aw * qy + az * qx - ax * qz; + out[2] = az * qw + aw * qz + ax * qy - ay * qx; + out[3] = aw * qw - ax * qx - ay * qy - az * qz; + ax = a[4]; + ay = a[5]; + az = a[6]; + aw = a[7]; + out[4] = ax * qw + aw * qx + ay * qz - az * qy; + out[5] = ay * qw + aw * qy + az * qx - ax * qz; + out[6] = az * qw + aw * qz + ax * qy - ay * qx; + out[7] = aw * qw - ax * qx - ay * qy - az * qz; + return out; + } + /** + * Rotates a dual quat by a given quaternion (q * a) + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat} q quaternion to rotate by + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @returns {quat2} out + */ + + function rotateByQuatPrepend(out, q, a) { + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3], + bx = a[0], + by = a[1], + bz = a[2], + bw = a[3]; + out[0] = qx * bw + qw * bx + qy * bz - qz * by; + out[1] = qy * bw + qw * by + qz * bx - qx * bz; + out[2] = qz * bw + qw * bz + qx * by - qy * bx; + out[3] = qw * bw - qx * bx - qy * by - qz * bz; + bx = a[4]; + by = a[5]; + bz = a[6]; + bw = a[7]; + out[4] = qx * bw + qw * bx + qy * bz - qz * by; + out[5] = qy * bw + qw * by + qz * bx - qx * bz; + out[6] = qz * bw + qw * bz + qx * by - qy * bx; + out[7] = qw * bw - qx * bx - qy * by - qz * bz; + return out; + } + /** + * Rotates a dual quat around a given axis. Does the normalisation automatically + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {ReadonlyVec3} axis the axis to rotate around + * @param {Number} rad how far the rotation should be + * @returns {quat2} out + */ + + function rotateAroundAxis(out, a, axis, rad) { + //Special case for rad = 0 + if (Math.abs(rad) < EPSILON) { + return copy$1(out, a); + } + + var axisLength = Math.hypot(axis[0], axis[1], axis[2]); + rad = rad * 0.5; + var s = Math.sin(rad); + var bx = s * axis[0] / axisLength; + var by = s * axis[1] / axisLength; + var bz = s * axis[2] / axisLength; + var bw = Math.cos(rad); + var ax1 = a[0], + ay1 = a[1], + az1 = a[2], + aw1 = a[3]; + out[0] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; + out[1] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; + out[2] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; + out[3] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; + var ax = a[4], + ay = a[5], + az = a[6], + aw = a[7]; + out[4] = ax * bw + aw * bx + ay * bz - az * by; + out[5] = ay * bw + aw * by + az * bx - ax * bz; + out[6] = az * bw + aw * bz + ax * by - ay * bx; + out[7] = aw * bw - ax * bx - ay * by - az * bz; + return out; + } + /** + * Adds two dual quat's + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand + * @returns {quat2} out + * @function + */ + + function add$1(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; + out[7] = a[7] + b[7]; + return out; + } + /** + * Multiplies two dual quat's + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand + * @returns {quat2} out + */ + + function multiply$1(out, a, b) { + var ax0 = a[0], + ay0 = a[1], + az0 = a[2], + aw0 = a[3], + bx1 = b[4], + by1 = b[5], + bz1 = b[6], + bw1 = b[7], + ax1 = a[4], + ay1 = a[5], + az1 = a[6], + aw1 = a[7], + bx0 = b[0], + by0 = b[1], + bz0 = b[2], + bw0 = b[3]; + out[0] = ax0 * bw0 + aw0 * bx0 + ay0 * bz0 - az0 * by0; + out[1] = ay0 * bw0 + aw0 * by0 + az0 * bx0 - ax0 * bz0; + out[2] = az0 * bw0 + aw0 * bz0 + ax0 * by0 - ay0 * bx0; + out[3] = aw0 * bw0 - ax0 * bx0 - ay0 * by0 - az0 * bz0; + out[4] = ax0 * bw1 + aw0 * bx1 + ay0 * bz1 - az0 * by1 + ax1 * bw0 + aw1 * bx0 + ay1 * bz0 - az1 * by0; + out[5] = ay0 * bw1 + aw0 * by1 + az0 * bx1 - ax0 * bz1 + ay1 * bw0 + aw1 * by0 + az1 * bx0 - ax1 * bz0; + out[6] = az0 * bw1 + aw0 * bz1 + ax0 * by1 - ay0 * bx1 + az1 * bw0 + aw1 * bz0 + ax1 * by0 - ay1 * bx0; + out[7] = aw0 * bw1 - ax0 * bx1 - ay0 * by1 - az0 * bz1 + aw1 * bw0 - ax1 * bx0 - ay1 * by0 - az1 * bz0; + return out; + } + /** + * Alias for {@link quat2.multiply} + * @function + */ + + var mul$1 = multiply$1; + /** + * Scales a dual quat by a scalar number + * + * @param {quat2} out the receiving dual quat + * @param {ReadonlyQuat2} a the dual quat to scale + * @param {Number} b amount to scale the dual quat by + * @returns {quat2} out + * @function + */ + + function scale$1(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + out[4] = a[4] * b; + out[5] = a[5] * b; + out[6] = a[6] * b; + out[7] = a[7] * b; + return out; + } + /** + * Calculates the dot product of two dual quat's (The dot product of the real parts) + * + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand + * @returns {Number} dot product of a and b + * @function + */ + + var dot$1 = dot$2; + /** + * Performs a linear interpolation between two dual quats's + * NOTE: The resulting dual quaternions won't always be normalized (The error is most noticeable when t = 0.5) + * + * @param {quat2} out the receiving dual quat + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat2} out + */ + + function lerp$1(out, a, b, t) { + var mt = 1 - t; + if (dot$1(a, b) < 0) t = -t; + out[0] = a[0] * mt + b[0] * t; + out[1] = a[1] * mt + b[1] * t; + out[2] = a[2] * mt + b[2] * t; + out[3] = a[3] * mt + b[3] * t; + out[4] = a[4] * mt + b[4] * t; + out[5] = a[5] * mt + b[5] * t; + out[6] = a[6] * mt + b[6] * t; + out[7] = a[7] * mt + b[7] * t; + return out; + } + /** + * Calculates the inverse of a dual quat. If they are normalized, conjugate is cheaper + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a dual quat to calculate inverse of + * @returns {quat2} out + */ + + function invert(out, a) { + var sqlen = squaredLength$1(a); + out[0] = -a[0] / sqlen; + out[1] = -a[1] / sqlen; + out[2] = -a[2] / sqlen; + out[3] = a[3] / sqlen; + out[4] = -a[4] / sqlen; + out[5] = -a[5] / sqlen; + out[6] = -a[6] / sqlen; + out[7] = a[7] / sqlen; + return out; + } + /** + * Calculates the conjugate of a dual quat + * If the dual quaternion is normalized, this function is faster than quat2.inverse and produces the same result. + * + * @param {quat2} out the receiving quaternion + * @param {ReadonlyQuat2} a quat to calculate conjugate of + * @returns {quat2} out + */ + + function conjugate(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + out[2] = -a[2]; + out[3] = a[3]; + out[4] = -a[4]; + out[5] = -a[5]; + out[6] = -a[6]; + out[7] = a[7]; + return out; + } + /** + * Calculates the length of a dual quat + * + * @param {ReadonlyQuat2} a dual quat to calculate length of + * @returns {Number} length of a + * @function + */ + + var length$1 = length$2; + /** + * Alias for {@link quat2.length} + * @function + */ + + var len$1 = length$1; + /** + * Calculates the squared length of a dual quat + * + * @param {ReadonlyQuat2} a dual quat to calculate squared length of + * @returns {Number} squared length of a + * @function + */ + + var squaredLength$1 = squaredLength$2; + /** + * Alias for {@link quat2.squaredLength} + * @function + */ + + var sqrLen$1 = squaredLength$1; + /** + * Normalize a dual quat + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a dual quaternion to normalize + * @returns {quat2} out + * @function + */ + + function normalize$1(out, a) { + var magnitude = squaredLength$1(a); + + if (magnitude > 0) { + magnitude = Math.sqrt(magnitude); + var a0 = a[0] / magnitude; + var a1 = a[1] / magnitude; + var a2 = a[2] / magnitude; + var a3 = a[3] / magnitude; + var b0 = a[4]; + var b1 = a[5]; + var b2 = a[6]; + var b3 = a[7]; + var a_dot_b = a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3; + out[0] = a0; + out[1] = a1; + out[2] = a2; + out[3] = a3; + out[4] = (b0 - a0 * a_dot_b) / magnitude; + out[5] = (b1 - a1 * a_dot_b) / magnitude; + out[6] = (b2 - a2 * a_dot_b) / magnitude; + out[7] = (b3 - a3 * a_dot_b) / magnitude; + } + + return out; + } + /** + * Returns a string representation of a dual quaternion + * + * @param {ReadonlyQuat2} a dual quaternion to represent as a string + * @returns {String} string representation of the dual quat + */ + + function str$1(a) { + return "quat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ")"; + } + /** + * Returns whether or not the dual quaternions have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyQuat2} a the first dual quaternion. + * @param {ReadonlyQuat2} b the second dual quaternion. + * @returns {Boolean} true if the dual quaternions are equal, false otherwise. + */ + + function exactEquals$1(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7]; + } + /** + * Returns whether or not the dual quaternions have approximately the same elements in the same position. + * + * @param {ReadonlyQuat2} a the first dual quat. + * @param {ReadonlyQuat2} b the second dual quat. + * @returns {Boolean} true if the dual quats are equal, false otherwise. + */ + + function equals$1(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5], + a6 = a[6], + a7 = a[7]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)); + } + + var quat2 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$1, + clone: clone$1, + fromValues: fromValues$1, + fromRotationTranslationValues: fromRotationTranslationValues, + fromRotationTranslation: fromRotationTranslation, + fromTranslation: fromTranslation, + fromRotation: fromRotation, + fromMat4: fromMat4, + copy: copy$1, + identity: identity, + set: set$1, + getReal: getReal, + getDual: getDual, + setReal: setReal, + setDual: setDual, + getTranslation: getTranslation, + translate: translate, + rotateX: rotateX, + rotateY: rotateY, + rotateZ: rotateZ, + rotateByQuatAppend: rotateByQuatAppend, + rotateByQuatPrepend: rotateByQuatPrepend, + rotateAroundAxis: rotateAroundAxis, + add: add$1, + multiply: multiply$1, + mul: mul$1, + scale: scale$1, + dot: dot$1, + lerp: lerp$1, + invert: invert, + conjugate: conjugate, + length: length$1, + len: len$1, + squaredLength: squaredLength$1, + sqrLen: sqrLen$1, + normalize: normalize$1, + str: str$1, + exactEquals: exactEquals$1, + equals: equals$1 + }); + + /** + * 2 Dimensional Vector + * @module vec2 + */ + + /** + * Creates a new, empty vec2 + * + * @returns {vec2} a new 2D vector + */ + + function create() { + var out = new ARRAY_TYPE(2); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + } + + return out; + } + /** + * Creates a new vec2 initialized with values from an existing vector + * + * @param {ReadonlyVec2} a vector to clone + * @returns {vec2} a new 2D vector + */ + + function clone(a) { + var out = new ARRAY_TYPE(2); + out[0] = a[0]; + out[1] = a[1]; + return out; + } + /** + * Creates a new vec2 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @returns {vec2} a new 2D vector + */ + + function fromValues(x, y) { + var out = new ARRAY_TYPE(2); + out[0] = x; + out[1] = y; + return out; + } + /** + * Copy the values from one vec2 to another + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the source vector + * @returns {vec2} out + */ + + function copy(out, a) { + out[0] = a[0]; + out[1] = a[1]; + return out; + } + /** + * Set the components of a vec2 to the given values + * + * @param {vec2} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @returns {vec2} out + */ + + function set(out, x, y) { + out[0] = x; + out[1] = y; + return out; + } + /** + * Adds two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function add(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function subtract(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + return out; + } + /** + * Multiplies two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function multiply(out, a, b) { + out[0] = a[0] * b[0]; + out[1] = a[1] * b[1]; + return out; + } + /** + * Divides two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function divide(out, a, b) { + out[0] = a[0] / b[0]; + out[1] = a[1] / b[1]; + return out; + } + /** + * Math.ceil the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to ceil + * @returns {vec2} out + */ + + function ceil(out, a) { + out[0] = Math.ceil(a[0]); + out[1] = Math.ceil(a[1]); + return out; + } + /** + * Math.floor the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to floor + * @returns {vec2} out + */ + + function floor(out, a) { + out[0] = Math.floor(a[0]); + out[1] = Math.floor(a[1]); + return out; + } + /** + * Returns the minimum of two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function min(out, a, b) { + out[0] = Math.min(a[0], b[0]); + out[1] = Math.min(a[1], b[1]); + return out; + } + /** + * Returns the maximum of two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function max(out, a, b) { + out[0] = Math.max(a[0], b[0]); + out[1] = Math.max(a[1], b[1]); + return out; + } + /** + * Math.round the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to round + * @returns {vec2} out + */ + + function round(out, a) { + out[0] = Math.round(a[0]); + out[1] = Math.round(a[1]); + return out; + } + /** + * Scales a vec2 by a scalar number + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec2} out + */ + + function scale(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + return out; + } + /** + * Adds two vec2's after scaling the second operand by a scalar value + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @param {Number} scale the amount to scale b by before adding + * @returns {vec2} out + */ + + function scaleAndAdd(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + return out; + } + /** + * Calculates the euclidian distance between two vec2's + * + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {Number} distance between a and b + */ + + function distance(a, b) { + var x = b[0] - a[0], + y = b[1] - a[1]; + return Math.hypot(x, y); + } + /** + * Calculates the squared euclidian distance between two vec2's + * + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {Number} squared distance between a and b + */ + + function squaredDistance(a, b) { + var x = b[0] - a[0], + y = b[1] - a[1]; + return x * x + y * y; + } + /** + * Calculates the length of a vec2 + * + * @param {ReadonlyVec2} a vector to calculate length of + * @returns {Number} length of a + */ + + function length(a) { + var x = a[0], + y = a[1]; + return Math.hypot(x, y); + } + /** + * Calculates the squared length of a vec2 + * + * @param {ReadonlyVec2} a vector to calculate squared length of + * @returns {Number} squared length of a + */ + + function squaredLength(a) { + var x = a[0], + y = a[1]; + return x * x + y * y; + } + /** + * Negates the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to negate + * @returns {vec2} out + */ + + function negate(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + return out; + } + /** + * Returns the inverse of the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to invert + * @returns {vec2} out + */ + + function inverse(out, a) { + out[0] = 1.0 / a[0]; + out[1] = 1.0 / a[1]; + return out; + } + /** + * Normalize a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to normalize + * @returns {vec2} out + */ + + function normalize(out, a) { + var x = a[0], + y = a[1]; + var len = x * x + y * y; + + if (len > 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } + + out[0] = a[0] * len; + out[1] = a[1] * len; + return out; + } + /** + * Calculates the dot product of two vec2's + * + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot(a, b) { + return a[0] * b[0] + a[1] * b[1]; + } + /** + * Computes the cross product of two vec2's + * Note that the cross product must by definition produce a 3D vector + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec3} out + */ + + function cross(out, a, b) { + var z = a[0] * b[1] - a[1] * b[0]; + out[0] = out[1] = 0; + out[2] = z; + return out; + } + /** + * Performs a linear interpolation between two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec2} out + */ + + function lerp(out, a, b, t) { + var ax = a[0], + ay = a[1]; + out[0] = ax + t * (b[0] - ax); + out[1] = ay + t * (b[1] - ay); + return out; + } + /** + * Generates a random vector with the given scale + * + * @param {vec2} out the receiving vector + * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned + * @returns {vec2} out + */ + + function random(out, scale) { + scale = scale === undefined ? 1.0 : scale; + var r = RANDOM() * 2.0 * Math.PI; + out[0] = Math.cos(r) * scale; + out[1] = Math.sin(r) * scale; + return out; + } + /** + * Transforms the vec2 with a mat2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat2} m matrix to transform with + * @returns {vec2} out + */ + + function transformMat2(out, a, m) { + var x = a[0], + y = a[1]; + out[0] = m[0] * x + m[2] * y; + out[1] = m[1] * x + m[3] * y; + return out; + } + /** + * Transforms the vec2 with a mat2d + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat2d} m matrix to transform with + * @returns {vec2} out + */ + + function transformMat2d(out, a, m) { + var x = a[0], + y = a[1]; + out[0] = m[0] * x + m[2] * y + m[4]; + out[1] = m[1] * x + m[3] * y + m[5]; + return out; + } + /** + * Transforms the vec2 with a mat3 + * 3rd vector component is implicitly '1' + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat3} m matrix to transform with + * @returns {vec2} out + */ + + function transformMat3(out, a, m) { + var x = a[0], + y = a[1]; + out[0] = m[0] * x + m[3] * y + m[6]; + out[1] = m[1] * x + m[4] * y + m[7]; + return out; + } + /** + * Transforms the vec2 with a mat4 + * 3rd vector component is implicitly '0' + * 4th vector component is implicitly '1' + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with + * @returns {vec2} out + */ + + function transformMat4(out, a, m) { + var x = a[0]; + var y = a[1]; + out[0] = m[0] * x + m[4] * y + m[12]; + out[1] = m[1] * x + m[5] * y + m[13]; + return out; + } + /** + * Rotate a 2D vector + * @param {vec2} out The receiving vec2 + * @param {ReadonlyVec2} a The vec2 point to rotate + * @param {ReadonlyVec2} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians + * @returns {vec2} out + */ + + function rotate(out, a, b, rad) { + //Translate point to the origin + var p0 = a[0] - b[0], + p1 = a[1] - b[1], + sinC = Math.sin(rad), + cosC = Math.cos(rad); //perform rotation and translate to correct position + + out[0] = p0 * cosC - p1 * sinC + b[0]; + out[1] = p0 * sinC + p1 * cosC + b[1]; + return out; + } + /** + * Get the angle between two 2D vectors + * @param {ReadonlyVec2} a The first operand + * @param {ReadonlyVec2} b The second operand + * @returns {Number} The angle in radians + */ + + function angle(a, b) { + var x1 = a[0], + y1 = a[1], + x2 = b[0], + y2 = b[1], + // mag is the product of the magnitudes of a and b + mag = Math.sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2)), + // mag &&.. short circuits if mag == 0 + cosine = mag && (x1 * x2 + y1 * y2) / mag; // Math.min(Math.max(cosine, -1), 1) clamps the cosine between -1 and 1 + + return Math.acos(Math.min(Math.max(cosine, -1), 1)); + } + /** + * Set the components of a vec2 to zero + * + * @param {vec2} out the receiving vector + * @returns {vec2} out + */ + + function zero(out) { + out[0] = 0.0; + out[1] = 0.0; + return out; + } + /** + * Returns a string representation of a vector + * + * @param {ReadonlyVec2} a vector to represent as a string + * @returns {String} string representation of the vector + */ + + function str(a) { + return "vec2(" + a[0] + ", " + a[1] + ")"; + } + /** + * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) + * + * @param {ReadonlyVec2} a The first vector. + * @param {ReadonlyVec2} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function exactEquals(a, b) { + return a[0] === b[0] && a[1] === b[1]; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {ReadonlyVec2} a The first vector. + * @param {ReadonlyVec2} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function equals(a, b) { + var a0 = a[0], + a1 = a[1]; + var b0 = b[0], + b1 = b[1]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)); + } + /** + * Alias for {@link vec2.length} + * @function + */ + + var len = length; + /** + * Alias for {@link vec2.subtract} + * @function + */ + + var sub = subtract; + /** + * Alias for {@link vec2.multiply} + * @function + */ + + var mul = multiply; + /** + * Alias for {@link vec2.divide} + * @function + */ + + var div = divide; + /** + * Alias for {@link vec2.distance} + * @function + */ + + var dist = distance; + /** + * Alias for {@link vec2.squaredDistance} + * @function + */ + + var sqrDist = squaredDistance; + /** + * Alias for {@link vec2.squaredLength} + * @function + */ + + var sqrLen = squaredLength; + /** + * Perform some operation over an array of vec2s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach = function () { + var vec = create(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 2; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + } + + return a; + }; + }(); + + var vec2 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create, + clone: clone, + fromValues: fromValues, + copy: copy, + set: set, + add: add, + subtract: subtract, + multiply: multiply, + divide: divide, + ceil: ceil, + floor: floor, + min: min, + max: max, + round: round, + scale: scale, + scaleAndAdd: scaleAndAdd, + distance: distance, + squaredDistance: squaredDistance, + length: length, + squaredLength: squaredLength, + negate: negate, + inverse: inverse, + normalize: normalize, + dot: dot, + cross: cross, + lerp: lerp, + random: random, + transformMat2: transformMat2, + transformMat2d: transformMat2d, + transformMat3: transformMat3, + transformMat4: transformMat4, + rotate: rotate, + angle: angle, + zero: zero, + str: str, + exactEquals: exactEquals, + equals: equals, + len: len, + sub: sub, + mul: mul, + div: div, + dist: dist, + sqrDist: sqrDist, + sqrLen: sqrLen, + forEach: forEach + }); + + exports.glMatrix = common; + exports.mat2 = mat2; + exports.mat2d = mat2d; + exports.mat3 = mat3; + exports.mat4 = mat4; + exports.quat = quat; + exports.quat2 = quat2; + exports.vec2 = vec2; + exports.vec3 = vec3; + exports.vec4 = vec4; + + Object.defineProperty(exports, '__esModule', { value: true }); + + })); + \ No newline at end of file diff --git a/Übung_23112023/aufgabe1/common/initShaders.js b/Übung_23112023/aufgabe1/common/initShaders.js new file mode 100644 index 0000000..e972f6a --- /dev/null +++ b/Übung_23112023/aufgabe1/common/initShaders.js @@ -0,0 +1,48 @@ +"use strict" ; + +// +// initShaders.js +// + +function initShaders( gl, vertexShaderId, fragmentShaderId ) +{ + const compileShader = ( gl, gl_shaderType, shaderSource ) => { + // Create the shader + let shader = gl.createShader( gl_shaderType ); + + // Set the shader source code + gl.shaderSource( shader, shaderSource ); + + // Compile the shader to make it readable for the GPU + gl.compileShader( shader ); + var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + + if (!success) { + // Something went wrong during compilation; get the error + throw "could not compile shader:" + gl.getShaderInfoLog(shader); + } + else { + return shader; + } + } + + /* + * Setup shader program + */ + let vShaderSource = document.querySelector( '#' + vertexShaderId ).text; + let fShaderSource = document.querySelector( '#' + fragmentShaderId ).text; + + let vertexShader = compileShader( gl, gl.VERTEX_SHADER, vShaderSource ); + let fragmentShader = compileShader( gl, gl.FRAGMENT_SHADER, fShaderSource ); + + // Build the program + const program = gl.createProgram(); + + // Attach shaders to it + gl.attachShader( program, vertexShader ); + gl.attachShader( program, fragmentShader ); + + gl.linkProgram( program ); + + return program; +} \ No newline at end of file diff --git a/Übung_23112023/aufgabe1/index.html b/Übung_23112023/aufgabe1/index.html new file mode 100644 index 0000000..370e3b1 --- /dev/null +++ b/Übung_23112023/aufgabe1/index.html @@ -0,0 +1,56 @@ + + + + + WebGL Example + + + + + + + + +

Lorem Ipsum

+ + + If you see this, your browser doesn't support WebGL. + + + + + diff --git a/Übung_23112023/aufgabe1/main.js b/Übung_23112023/aufgabe1/main.js new file mode 100644 index 0000000..49ea3a0 --- /dev/null +++ b/Übung_23112023/aufgabe1/main.js @@ -0,0 +1,62 @@ +"use strict" ; + +let gl; +let viewLoc; +let program; +let objects = []; +let posLoc, + colorLoc; + +function main() { + + // Get canvas and setup WebGL context + const canvas = document.getElementById("gl-canvas"); + gl = canvas.getContext('webgl2'); + + // Configure viewport + gl.viewport(0,0,canvas.width,canvas.height); + gl.clearColor(1.0,1.0,1.0,1.0); + + gl.enable(gl.DEPTH_TEST); + + // Init shader program via additional function and bind it + program = initShaders(gl, "vertex-shader", "fragment-shader"); + gl.useProgram(program); + + // Get locations of shader variables + posLoc = gl.getAttribLocation(program, "vPosition"); + colorLoc = gl.getAttribLocation(program, "vColor"); + + // Create object instances + let island = new Island(); + objects.push(island); + let river = new River(); + objects.push(river); + + // View Matrix + var mat = new Float32Array([ + 0.1767766922712326 , -0.0589255653321743 , -0.013334667310118675 , 0 , + 0 , 0.2357022613286972 , -0.006667333655059338 , 0 , + -0.1767766922712326 , -0.0589255653321743 , -0.013334667310118675 , 0 , + 0 , 0 , -0.8801880478858948 , 1 + ]); + viewLoc = gl.getUniformLocation(program,"viewMatrix"); + gl.uniformMatrix4fv(viewLoc,false,mat); + + render(); +}; + +function render() { + + // Only clear once + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + // Call render function of each scene object + // and don't mix up "of" and "in" up here, both keywords + // are valid but have different meanings + for(let object of objects) { + object.Render(); + }; +} + +main(); diff --git a/Übung_23112023/aufgabe2/common/Object3D.js b/Übung_23112023/aufgabe2/common/Object3D.js new file mode 100644 index 0000000..e268378 --- /dev/null +++ b/Übung_23112023/aufgabe2/common/Object3D.js @@ -0,0 +1,408 @@ +"use strict" ; + +class Object3D { + constructor() { + this.posVBO = gl.createBuffer(); + this.colorVBO = gl.createBuffer(); + this.indexVBO = gl.createBuffer(); + } + + InitBuffers() { + gl.bindBuffer(gl.ARRAY_BUFFER, this.posVBO); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.positions), gl.STATIC_DRAW); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.colorVBO); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.colors), gl.STATIC_DRAW); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexVBO); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.indices), gl.STATIC_DRAW); + } + + Render() { + // Link data in VBO to shader variables + gl.bindBuffer(gl.ARRAY_BUFFER, this.posVBO); + gl.enableVertexAttribArray(posLoc); + gl.vertexAttribPointer(posLoc, 3, gl.FLOAT, false, 0, 0); + + // Link data in VBO to shader variables + gl.bindBuffer(gl.ARRAY_BUFFER, this.colorVBO); + gl.enableVertexAttribArray(colorLoc); + gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0); + + // Render + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexVBO); + gl.drawElements(gl.TRIANGLES, this.indices.length, gl.UNSIGNED_SHORT, 0); + } +} + +class Cube extends Object3D { + constructor() { + super(); + + this.positions = [ + -1, -1, -1, // index 0 + -1, -1, 1, // index 1 + -1, 1, -1, // index 2 + -1, 1, 1, // index 3 + 1, -1, -1, // index 4 + 1, -1, 1, // index 5 + 1, 1, -1, // index 6 + 1, 1, 1 // index 7 + ]; + this.indices = [ + 1, 7, 3, 1, 5, 7, // Front + 5, 6, 7, 5, 4, 6, // Right + 4, 2, 0, 4, 6, 2, // Back + 0, 3, 2, 0, 1, 3, // Left + 0, 5, 1, 0, 4, 5, // Bottom + 3, 6, 2, 3, 7, 6 // Top + ]; + this.colors = [ + 0, 0, 0, 1, // index 0 + 1, 0, 0, 1, // index 1 + 0, 1, 0, 1, // index 2 + 0, 0, 1, 1, // index 3 + 1, 1, 0, 1, // index 4 + 1, 0, 1, 1, // index 5 + 0, 1, 1, 1, // index 6 + 1, 1, 1, 1 // index 7 + ]; + this.InitBuffers(); + } +} + +class Island extends Object3D { + + constructor() { + super(); + + this.positions = [ + -0.344503,-0.106899,-2.313329, + 0.254658,0.065420,-2.430170, + 0.506020,-0.293147,-2.207084, + 1.415955,0.064912,-1.957500, + 1.489208,-0.318759,-1.320762, + 1.685851,0.084184,-1.268915, + 2.014675,-0.126122,-0.782958, + 0.957233,-1.089151,-0.905606, + 0.454708,-1.256676,-0.897711, + 0.810208,-0.709404,-1.141590, + 0.739686,-1.249709,-0.541415, + 0.231851,-1.904112,-0.621845, + 0.052641,-1.633897,-0.758536, + -0.020753,-0.743329,-1.377161, + 1.364762,-0.324582,0.647285, + 2.074500,0.090083,0.068582, + 1.608835,0.037777,0.559365, + 1.955554,-0.191974,0.132568, + 1.393132,0.037777,1.383312, + 1.210661,-0.322174,1.134609, + 0.514977,-0.286422,1.576757, + 0.507135,-1.581211,0.348922, + 0.342563,-2.052501,-0.027325, + 0.620568,-1.491335,-0.146730, + 0.745909,-0.723539,0.485115, + 0.089439,-1.345612,0.360167, + 1.089500,-0.770651,-0.314462, + -0.123718,-0.298339,1.611730, + -0.930959,0.037777,1.550149, + -0.866234,-0.291222,1.300128, + -0.414258,0.037777,1.808618, + -1.444312,-0.282136,0.794076, + -1.591571,0.097928,0.827036, + -1.839477,-0.177971,0.145553, + -0.936850,-0.751093,-0.176985, + -0.611777,-1.317411,-0.262516, + -0.326162,-1.310280,0.225784, + 0.289486,-0.743127,0.679448, + 0.020776,-1.770522,0.330532, + -1.675519,-0.336500,-0.606829, + -1.607249,0.010755,-1.680275, + -0.625318,-0.725192,-1.039731, + -2.011082,0.043485,-0.744422, + -1.247727,0.059337,-1.332687, + -0.934732,-0.314137,-1.943344, + -0.184171,-0.491687,-2.096484, + -0.707720,0.065178,-2.205832, + -0.350659,-1.373304,-0.758204, + -0.299529,-2.155551,-0.308846, + -0.086080,-2.478361,-0.004677, + 0.091215,-2.267556,0.130842, + -0.260030,-2.240649,0.060849, + -0.470828,-1.954876,0.024811, + -0.278168,0.037777,-0.209083, + -0.914878,0.210568,-1.267986, + -0.862298,0.231412,-0.781910, + -0.302799,0.520691,-1.301783, + -1.068480,0.101026,-0.360536, + -1.736910,0.103204,0.106553, + 0.236277,0.037777,0.701510, + 0.656348,0.037777,-0.098120, + 0.501631,0.037777,1.688231, + 1.034499,0.275328,-1.269756, + 0.471459,0.267036,-1.698558, + 0.637660,0.376390,-1.207861, + 0.812177,0.491673,-0.567514, + 1.244986,0.398908,-0.324291, + 1.002755,0.639249,-0.717163, + 1.381545,0.288786,-0.765328, + 1.348978,0.284964,-1.076072, + -0.505260,0.213488,-1.704558, + -0.221831,0.306144,-1.838428, + -0.274246,0.065420,-2.359878, + 2.054775,0.091828,-0.677912, + -0.148262,0.773865,-0.947432, + 0.101020,0.922236,-0.839739, + 0.312442,0.779166,-1.109731, + -0.262315,0.721321,-1.533752, + -0.404757,0.197895,-0.782219, + 0.568488,0.537125,-0.913448, + 0.115069,0.760356,-1.450921, + -0.061115,0.654189,-0.643377, + 0.205810,0.801703,-0.757537, + 0.344937,0.262088,-0.492076, + 0.077232,0.934717,-1.202342, + -0.102879,0.422805,-0.489015, + -0.269697,0.566033,-0.874217, + -0.186512,0.743264,-1.152426 + ]; + + this.indices = [ + 0,1,2, + 3,4,2, + 5,6,4, + 7,8,9, + 8,10,11, + 9,12,13, + 14,15,16, + 14,6,17, + 6,15,17, + 14,18,19, + 18,20,19, + 21,22,23, + 24,25,21, + 24,23,26, + 27,28,29, + 20,30,27, + 28,31,29, + 32,33,31, + 34,35,36, + 36,25,37, + 36,38,25, + 39,40,41, + 40,42,43, + 33,42,39, + 40,44,41, + 44,0,45, + 40,46,44, + 46,0,44, + 41,12,47, + 47,12,48, + 41,35,34, + 48,35,47, + 48,11,49, + 11,50,49, + 50,51,49, + 50,52,51, + 51,48,49, + 53,32,28, + 54,55,56, + 57,58,32, + 59,16,60, + 28,59,53, + 59,61,18, + 62,63,64, + 65,66,67, + 68,5,69, + 70,43,54, + 63,1,71, + 71,72,46, + 13,45,2, + 9,4,7, + 4,26,7, + 26,14,24, + 26,6,14, + 19,37,24, + 37,29,36, + 29,34,36, + 44,13,41, + 2,1,3, + 2,45,0, + 0,72,1, + 9,2,4, + 3,5,4, + 5,73,6, + 7,10,8, + 7,26,10, + 9,8,12, + 8,11,12, + 14,17,15, + 6,73,15, + 14,16,18, + 18,61,20, + 24,21,23, + 21,38,22, + 24,37,25, + 21,25,38, + 26,23,10, + 23,22,10, + 27,30,28, + 20,61,30, + 28,32,31, + 32,58,33, + 36,35,52, + 74,75,76, + 36,52,38, + 40,39,42, + 33,58,42, + 40,43,46, + 46,72,0, + 41,13,12, + 41,47,35, + 48,52,35, + 48,12,11, + 11,22,50, + 11,10,22, + 50,38,52, + 22,38,50, + 48,51,52, + 53,57,32, + 43,42,57, + 57,42,58, + 59,18,16, + 28,30,59, + 59,30,61, + 5,62,69, + 60,16,15, + 66,73,68, + 71,70,77, + 63,3,1, + 71,1,72, + 13,2,9, + 4,6,26, + 14,19,24, + 19,20,37, + 37,27,29, + 37,20,27, + 29,31,34, + 31,33,34, + 34,39,41, + 34,33,39, + 44,45,13, + 55,78,56, + 59,60,53, + 79,60,65, + 77,56,80, + 81,82,75, + 82,76,75, + 60,76,83, + 76,80,84, + 53,83,85, + 86,74,87, + 64,76,79, + 74,84,87, + 53,60,83, + 78,85,86, + 67,64,79, + 67,79,65, + 67,66,68, + 67,69,62, + 67,68,69, + 60,66,65, + 67,62,64, + 62,3,63, + 68,73,5, + 5,3,62, + 66,15,73, + 79,76,60, + 64,63,76, + 60,15,66, + 76,82,83, + 85,82,81, + 85,83,82, + 74,85,81, + 56,78,86, + 56,87,84, + 56,86,87, + 56,84,80, + 71,80,63, + 53,55,57, + 56,77,70, + 56,70,54, + 43,55,54, + 70,46,43, + 71,46,70, + 76,63,80, + 86,85,74, + 74,76,84, + 78,53,85, + 71,77,80, + 53,78,55, + 43,57,55, + 74,81,75 + ]; + + this.colors = []; + for(let i = 0; i < this.positions.length; i += 3) { + this.colors.push(Math.random(), Math.random(), Math.random(), 1); + } + + this.InitBuffers(); + } +} + + +class River extends Object3D { + constructor() { + super(); + + this.positions = [ + 0.0, 0.0, 14.0, // index 0 + 0.75, 0.0, 12.5, // index 1 + 1.25, 0.0, 12.5, // index 2 + 1.0, 0.0, 11.0, // index 3 + 2.0, 0.0, 11.0, // index 4 + 0.75, 0.0, 9.5, // index 5 + 2.25, 0.0, 9.5, // index 6 + 0.0, 0.0, 8.0, // index 7 + 2.0, 0.0, 8.0, // index 8 + -2.25, 0.0, 6.1875, // index 9 + 0.25, 0.0, 6.1875, // index 10 + -3.0, 0.0, 4.0, // index 11 + 0.0, 0.0, 4.0, // index 12 + -2.25, 0.0, 1.8125, // index 13 + 1.25, 0.0, 1.8125, // index 14 + 0.0, 0.0, 0.0, // index 15 + 4.0, 0.0, 0.0, // index 16 + 0.0, -7.0, 0.0, // index 17 -> additional for waterfall + 4.0, -6.0, 0.0 // index 18 -> additional for waterfall + ]; + + this.indices = [ + 0, 1, 2, + 1, 2, 3, + 2, 3, 4, + 3, 4, 5, + 4, 5, 6, + 5, 6, 7, + 6, 7, 8, + 7, 8, 9, + 8, 9, 10, + 9, 10, 11, + 10, 11, 12, + 11, 12, 13, + 12, 13, 14, + 13, 14, 15, + 14, 15, 16, + 15, 16, 17, // additional for waterfall + 16, 17, 18 // additional for waterfall + ]; + + this.colors = []; + for(let i = 0; i < this.positions.length; i += 3) { + this.colors.push(0.2, 0.2, 0.8, 1); + } + + this.InitBuffers(); + } +} diff --git a/Übung_23112023/aufgabe2/common/gl-matrix.js b/Übung_23112023/aufgabe2/common/gl-matrix.js new file mode 100644 index 0000000..0799c59 --- /dev/null +++ b/Übung_23112023/aufgabe2/common/gl-matrix.js @@ -0,0 +1,7861 @@ + +/*! +@fileoverview gl-matrix - High performance matrix and vector operations +@author Brandon Jones +@author Colin MacKenzie IV +@version 3.4.0 + +Copyright (c) 2015-2021, Brandon Jones, Colin MacKenzie IV. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.glMatrix = {})); + })(this, (function (exports) { 'use strict'; + + /** + * Common utilities + * @module glMatrix + */ + // Configuration Constants + var EPSILON = 0.000001; + var ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array; + var RANDOM = Math.random; + var ANGLE_ORDER = "zyx"; + /** + * Sets the type of array used when creating new vectors and matrices + * + * @param {Float32ArrayConstructor | ArrayConstructor} type Array type, such as Float32Array or Array + */ + + function setMatrixArrayType(type) { + ARRAY_TYPE = type; + } + var degree = Math.PI / 180; + /** + * Convert Degree To Radian + * + * @param {Number} a Angle in Degrees + */ + + function toRadian(a) { + return a * degree; + } + /** + * Tests whether or not the arguments have approximately the same value, within an absolute + * or relative tolerance of glMatrix.EPSILON (an absolute tolerance is used for values less + * than or equal to 1.0, and a relative tolerance is used for larger values) + * + * @param {Number} a The first number to test. + * @param {Number} b The second number to test. + * @returns {Boolean} True if the numbers are approximately equal, false otherwise. + */ + + function equals$9(a, b) { + return Math.abs(a - b) <= EPSILON * Math.max(1.0, Math.abs(a), Math.abs(b)); + } + if (!Math.hypot) Math.hypot = function () { + var y = 0, + i = arguments.length; + + while (i--) { + y += arguments[i] * arguments[i]; + } + + return Math.sqrt(y); + }; + + var common = /*#__PURE__*/Object.freeze({ + __proto__: null, + EPSILON: EPSILON, + get ARRAY_TYPE () { return ARRAY_TYPE; }, + RANDOM: RANDOM, + ANGLE_ORDER: ANGLE_ORDER, + setMatrixArrayType: setMatrixArrayType, + toRadian: toRadian, + equals: equals$9 + }); + + /** + * 2x2 Matrix + * @module mat2 + */ + + /** + * Creates a new identity mat2 + * + * @returns {mat2} a new 2x2 matrix + */ + + function create$8() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + } + + out[0] = 1; + out[3] = 1; + return out; + } + /** + * Creates a new mat2 initialized with values from an existing matrix + * + * @param {ReadonlyMat2} a matrix to clone + * @returns {mat2} a new 2x2 matrix + */ + + function clone$8(a) { + var out = new ARRAY_TYPE(4); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Copy the values from one mat2 to another + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the source matrix + * @returns {mat2} out + */ + + function copy$8(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Set a mat2 to the identity matrix + * + * @param {mat2} out the receiving matrix + * @returns {mat2} out + */ + + function identity$5(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } + /** + * Create a new mat2 with the given values + * + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m10 Component in column 1, row 0 position (index 2) + * @param {Number} m11 Component in column 1, row 1 position (index 3) + * @returns {mat2} out A new 2x2 matrix + */ + + function fromValues$8(m00, m01, m10, m11) { + var out = new ARRAY_TYPE(4); + out[0] = m00; + out[1] = m01; + out[2] = m10; + out[3] = m11; + return out; + } + /** + * Set the components of a mat2 to the given values + * + * @param {mat2} out the receiving matrix + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m10 Component in column 1, row 0 position (index 2) + * @param {Number} m11 Component in column 1, row 1 position (index 3) + * @returns {mat2} out + */ + + function set$8(out, m00, m01, m10, m11) { + out[0] = m00; + out[1] = m01; + out[2] = m10; + out[3] = m11; + return out; + } + /** + * Transpose the values of a mat2 + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the source matrix + * @returns {mat2} out + */ + + function transpose$2(out, a) { + // If we are transposing ourselves we can skip a few steps but have to cache + // some values + if (out === a) { + var a1 = a[1]; + out[1] = a[2]; + out[2] = a1; + } else { + out[0] = a[0]; + out[1] = a[2]; + out[2] = a[1]; + out[3] = a[3]; + } + + return out; + } + /** + * Inverts a mat2 + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the source matrix + * @returns {mat2} out + */ + + function invert$5(out, a) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; // Calculate the determinant + + var det = a0 * a3 - a2 * a1; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = a3 * det; + out[1] = -a1 * det; + out[2] = -a2 * det; + out[3] = a0 * det; + return out; + } + /** + * Calculates the adjugate of a mat2 + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the source matrix + * @returns {mat2} out + */ + + function adjoint$2(out, a) { + // Caching this value is necessary if out == a + var a0 = a[0]; + out[0] = a[3]; + out[1] = -a[1]; + out[2] = -a[2]; + out[3] = a0; + return out; + } + /** + * Calculates the determinant of a mat2 + * + * @param {ReadonlyMat2} a the source matrix + * @returns {Number} determinant of a + */ + + function determinant$3(a) { + return a[0] * a[3] - a[2] * a[1]; + } + /** + * Multiplies two mat2's + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand + * @returns {mat2} out + */ + + function multiply$8(out, a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + out[0] = a0 * b0 + a2 * b1; + out[1] = a1 * b0 + a3 * b1; + out[2] = a0 * b2 + a2 * b3; + out[3] = a1 * b2 + a3 * b3; + return out; + } + /** + * Rotates a mat2 by the given angle + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2} out + */ + + function rotate$4(out, a, rad) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var s = Math.sin(rad); + var c = Math.cos(rad); + out[0] = a0 * c + a2 * s; + out[1] = a1 * c + a3 * s; + out[2] = a0 * -s + a2 * c; + out[3] = a1 * -s + a3 * c; + return out; + } + /** + * Scales the mat2 by the dimensions in the given vec2 + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the matrix to rotate + * @param {ReadonlyVec2} v the vec2 to scale the matrix by + * @returns {mat2} out + **/ + + function scale$8(out, a, v) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var v0 = v[0], + v1 = v[1]; + out[0] = a0 * v0; + out[1] = a1 * v0; + out[2] = a2 * v1; + out[3] = a3 * v1; + return out; + } + /** + * Creates a matrix from a given angle + * This is equivalent to (but much faster than): + * + * mat2.identity(dest); + * mat2.rotate(dest, dest, rad); + * + * @param {mat2} out mat2 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2} out + */ + + function fromRotation$4(out, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + out[0] = c; + out[1] = s; + out[2] = -s; + out[3] = c; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat2.identity(dest); + * mat2.scale(dest, dest, vec); + * + * @param {mat2} out mat2 receiving operation result + * @param {ReadonlyVec2} v Scaling vector + * @returns {mat2} out + */ + + function fromScaling$3(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = v[1]; + return out; + } + /** + * Returns a string representation of a mat2 + * + * @param {ReadonlyMat2} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ + + function str$8(a) { + return "mat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; + } + /** + * Returns Frobenius norm of a mat2 + * + * @param {ReadonlyMat2} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ + + function frob$3(a) { + return Math.hypot(a[0], a[1], a[2], a[3]); + } + /** + * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix + * @param {ReadonlyMat2} L the lower triangular matrix + * @param {ReadonlyMat2} D the diagonal matrix + * @param {ReadonlyMat2} U the upper triangular matrix + * @param {ReadonlyMat2} a the input matrix to factorize + */ + + function LDU(L, D, U, a) { + L[2] = a[2] / a[0]; + U[0] = a[0]; + U[1] = a[1]; + U[3] = a[3] - L[2] * U[1]; + return [L, D, U]; + } + /** + * Adds two mat2's + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand + * @returns {mat2} out + */ + + function add$8(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand + * @returns {mat2} out + */ + + function subtract$6(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyMat2} a The first matrix. + * @param {ReadonlyMat2} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function exactEquals$8(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {ReadonlyMat2} a The first matrix. + * @param {ReadonlyMat2} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function equals$8(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)); + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat2} out the receiving matrix + * @param {ReadonlyMat2} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat2} out + */ + + function multiplyScalar$3(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + return out; + } + /** + * Adds two mat2's after multiplying each element of the second operand by a scalar value. + * + * @param {mat2} out the receiving vector + * @param {ReadonlyMat2} a the first operand + * @param {ReadonlyMat2} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat2} out + */ + + function multiplyScalarAndAdd$3(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + return out; + } + /** + * Alias for {@link mat2.multiply} + * @function + */ + + var mul$8 = multiply$8; + /** + * Alias for {@link mat2.subtract} + * @function + */ + + var sub$6 = subtract$6; + + var mat2 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$8, + clone: clone$8, + copy: copy$8, + identity: identity$5, + fromValues: fromValues$8, + set: set$8, + transpose: transpose$2, + invert: invert$5, + adjoint: adjoint$2, + determinant: determinant$3, + multiply: multiply$8, + rotate: rotate$4, + scale: scale$8, + fromRotation: fromRotation$4, + fromScaling: fromScaling$3, + str: str$8, + frob: frob$3, + LDU: LDU, + add: add$8, + subtract: subtract$6, + exactEquals: exactEquals$8, + equals: equals$8, + multiplyScalar: multiplyScalar$3, + multiplyScalarAndAdd: multiplyScalarAndAdd$3, + mul: mul$8, + sub: sub$6 + }); + + /** + * 2x3 Matrix + * @module mat2d + * @description + * A mat2d contains six elements defined as: + *
+     * [a, b,
+     *  c, d,
+     *  tx, ty]
+     * 
+ * This is a short form for the 3x3 matrix: + *
+     * [a, b, 0,
+     *  c, d, 0,
+     *  tx, ty, 1]
+     * 
+ * The last column is ignored so the array is shorter and operations are faster. + */ + + /** + * Creates a new identity mat2d + * + * @returns {mat2d} a new 2x3 matrix + */ + + function create$7() { + var out = new ARRAY_TYPE(6); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[4] = 0; + out[5] = 0; + } + + out[0] = 1; + out[3] = 1; + return out; + } + /** + * Creates a new mat2d initialized with values from an existing matrix + * + * @param {ReadonlyMat2d} a matrix to clone + * @returns {mat2d} a new 2x3 matrix + */ + + function clone$7(a) { + var out = new ARRAY_TYPE(6); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + return out; + } + /** + * Copy the values from one mat2d to another + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the source matrix + * @returns {mat2d} out + */ + + function copy$7(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + return out; + } + /** + * Set a mat2d to the identity matrix + * + * @param {mat2d} out the receiving matrix + * @returns {mat2d} out + */ + + function identity$4(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = 0; + out[5] = 0; + return out; + } + /** + * Create a new mat2d with the given values + * + * @param {Number} a Component A (index 0) + * @param {Number} b Component B (index 1) + * @param {Number} c Component C (index 2) + * @param {Number} d Component D (index 3) + * @param {Number} tx Component TX (index 4) + * @param {Number} ty Component TY (index 5) + * @returns {mat2d} A new mat2d + */ + + function fromValues$7(a, b, c, d, tx, ty) { + var out = new ARRAY_TYPE(6); + out[0] = a; + out[1] = b; + out[2] = c; + out[3] = d; + out[4] = tx; + out[5] = ty; + return out; + } + /** + * Set the components of a mat2d to the given values + * + * @param {mat2d} out the receiving matrix + * @param {Number} a Component A (index 0) + * @param {Number} b Component B (index 1) + * @param {Number} c Component C (index 2) + * @param {Number} d Component D (index 3) + * @param {Number} tx Component TX (index 4) + * @param {Number} ty Component TY (index 5) + * @returns {mat2d} out + */ + + function set$7(out, a, b, c, d, tx, ty) { + out[0] = a; + out[1] = b; + out[2] = c; + out[3] = d; + out[4] = tx; + out[5] = ty; + return out; + } + /** + * Inverts a mat2d + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the source matrix + * @returns {mat2d} out + */ + + function invert$4(out, a) { + var aa = a[0], + ab = a[1], + ac = a[2], + ad = a[3]; + var atx = a[4], + aty = a[5]; + var det = aa * ad - ab * ac; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = ad * det; + out[1] = -ab * det; + out[2] = -ac * det; + out[3] = aa * det; + out[4] = (ac * aty - ad * atx) * det; + out[5] = (ab * atx - aa * aty) * det; + return out; + } + /** + * Calculates the determinant of a mat2d + * + * @param {ReadonlyMat2d} a the source matrix + * @returns {Number} determinant of a + */ + + function determinant$2(a) { + return a[0] * a[3] - a[1] * a[2]; + } + /** + * Multiplies two mat2d's + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the first operand + * @param {ReadonlyMat2d} b the second operand + * @returns {mat2d} out + */ + + function multiply$7(out, a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5]; + out[0] = a0 * b0 + a2 * b1; + out[1] = a1 * b0 + a3 * b1; + out[2] = a0 * b2 + a2 * b3; + out[3] = a1 * b2 + a3 * b3; + out[4] = a0 * b4 + a2 * b5 + a4; + out[5] = a1 * b4 + a3 * b5 + a5; + return out; + } + /** + * Rotates a mat2d by the given angle + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2d} out + */ + + function rotate$3(out, a, rad) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var s = Math.sin(rad); + var c = Math.cos(rad); + out[0] = a0 * c + a2 * s; + out[1] = a1 * c + a3 * s; + out[2] = a0 * -s + a2 * c; + out[3] = a1 * -s + a3 * c; + out[4] = a4; + out[5] = a5; + return out; + } + /** + * Scales the mat2d by the dimensions in the given vec2 + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the matrix to translate + * @param {ReadonlyVec2} v the vec2 to scale the matrix by + * @returns {mat2d} out + **/ + + function scale$7(out, a, v) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var v0 = v[0], + v1 = v[1]; + out[0] = a0 * v0; + out[1] = a1 * v0; + out[2] = a2 * v1; + out[3] = a3 * v1; + out[4] = a4; + out[5] = a5; + return out; + } + /** + * Translates the mat2d by the dimensions in the given vec2 + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the matrix to translate + * @param {ReadonlyVec2} v the vec2 to translate the matrix by + * @returns {mat2d} out + **/ + + function translate$3(out, a, v) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var v0 = v[0], + v1 = v[1]; + out[0] = a0; + out[1] = a1; + out[2] = a2; + out[3] = a3; + out[4] = a0 * v0 + a2 * v1 + a4; + out[5] = a1 * v0 + a3 * v1 + a5; + return out; + } + /** + * Creates a matrix from a given angle + * This is equivalent to (but much faster than): + * + * mat2d.identity(dest); + * mat2d.rotate(dest, dest, rad); + * + * @param {mat2d} out mat2d receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2d} out + */ + + function fromRotation$3(out, rad) { + var s = Math.sin(rad), + c = Math.cos(rad); + out[0] = c; + out[1] = s; + out[2] = -s; + out[3] = c; + out[4] = 0; + out[5] = 0; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat2d.identity(dest); + * mat2d.scale(dest, dest, vec); + * + * @param {mat2d} out mat2d receiving operation result + * @param {ReadonlyVec2} v Scaling vector + * @returns {mat2d} out + */ + + function fromScaling$2(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = v[1]; + out[4] = 0; + out[5] = 0; + return out; + } + /** + * Creates a matrix from a vector translation + * This is equivalent to (but much faster than): + * + * mat2d.identity(dest); + * mat2d.translate(dest, dest, vec); + * + * @param {mat2d} out mat2d receiving operation result + * @param {ReadonlyVec2} v Translation vector + * @returns {mat2d} out + */ + + function fromTranslation$3(out, v) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = v[0]; + out[5] = v[1]; + return out; + } + /** + * Returns a string representation of a mat2d + * + * @param {ReadonlyMat2d} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ + + function str$7(a) { + return "mat2d(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ")"; + } + /** + * Returns Frobenius norm of a mat2d + * + * @param {ReadonlyMat2d} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ + + function frob$2(a) { + return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], 1); + } + /** + * Adds two mat2d's + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the first operand + * @param {ReadonlyMat2d} b the second operand + * @returns {mat2d} out + */ + + function add$7(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the first operand + * @param {ReadonlyMat2d} b the second operand + * @returns {mat2d} out + */ + + function subtract$5(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + out[4] = a[4] - b[4]; + out[5] = a[5] - b[5]; + return out; + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat2d} out the receiving matrix + * @param {ReadonlyMat2d} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat2d} out + */ + + function multiplyScalar$2(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + out[4] = a[4] * b; + out[5] = a[5] * b; + return out; + } + /** + * Adds two mat2d's after multiplying each element of the second operand by a scalar value. + * + * @param {mat2d} out the receiving vector + * @param {ReadonlyMat2d} a the first operand + * @param {ReadonlyMat2d} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat2d} out + */ + + function multiplyScalarAndAdd$2(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + out[4] = a[4] + b[4] * scale; + out[5] = a[5] + b[5] * scale; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyMat2d} a The first matrix. + * @param {ReadonlyMat2d} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function exactEquals$7(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {ReadonlyMat2d} a The first matrix. + * @param {ReadonlyMat2d} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function equals$7(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)); + } + /** + * Alias for {@link mat2d.multiply} + * @function + */ + + var mul$7 = multiply$7; + /** + * Alias for {@link mat2d.subtract} + * @function + */ + + var sub$5 = subtract$5; + + var mat2d = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$7, + clone: clone$7, + copy: copy$7, + identity: identity$4, + fromValues: fromValues$7, + set: set$7, + invert: invert$4, + determinant: determinant$2, + multiply: multiply$7, + rotate: rotate$3, + scale: scale$7, + translate: translate$3, + fromRotation: fromRotation$3, + fromScaling: fromScaling$2, + fromTranslation: fromTranslation$3, + str: str$7, + frob: frob$2, + add: add$7, + subtract: subtract$5, + multiplyScalar: multiplyScalar$2, + multiplyScalarAndAdd: multiplyScalarAndAdd$2, + exactEquals: exactEquals$7, + equals: equals$7, + mul: mul$7, + sub: sub$5 + }); + + /** + * 3x3 Matrix + * @module mat3 + */ + + /** + * Creates a new identity mat3 + * + * @returns {mat3} a new 3x3 matrix + */ + + function create$6() { + var out = new ARRAY_TYPE(9); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + } + + out[0] = 1; + out[4] = 1; + out[8] = 1; + return out; + } + /** + * Copies the upper-left 3x3 values into the given mat3. + * + * @param {mat3} out the receiving 3x3 matrix + * @param {ReadonlyMat4} a the source 4x4 matrix + * @returns {mat3} out + */ + + function fromMat4$1(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[4]; + out[4] = a[5]; + out[5] = a[6]; + out[6] = a[8]; + out[7] = a[9]; + out[8] = a[10]; + return out; + } + /** + * Creates a new mat3 initialized with values from an existing matrix + * + * @param {ReadonlyMat3} a matrix to clone + * @returns {mat3} a new 3x3 matrix + */ + + function clone$6(a) { + var out = new ARRAY_TYPE(9); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + return out; + } + /** + * Copy the values from one mat3 to another + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + + function copy$6(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + return out; + } + /** + * Create a new mat3 with the given values + * + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m10 Component in column 1, row 0 position (index 3) + * @param {Number} m11 Component in column 1, row 1 position (index 4) + * @param {Number} m12 Component in column 1, row 2 position (index 5) + * @param {Number} m20 Component in column 2, row 0 position (index 6) + * @param {Number} m21 Component in column 2, row 1 position (index 7) + * @param {Number} m22 Component in column 2, row 2 position (index 8) + * @returns {mat3} A new mat3 + */ + + function fromValues$6(m00, m01, m02, m10, m11, m12, m20, m21, m22) { + var out = new ARRAY_TYPE(9); + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m10; + out[4] = m11; + out[5] = m12; + out[6] = m20; + out[7] = m21; + out[8] = m22; + return out; + } + /** + * Set the components of a mat3 to the given values + * + * @param {mat3} out the receiving matrix + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m10 Component in column 1, row 0 position (index 3) + * @param {Number} m11 Component in column 1, row 1 position (index 4) + * @param {Number} m12 Component in column 1, row 2 position (index 5) + * @param {Number} m20 Component in column 2, row 0 position (index 6) + * @param {Number} m21 Component in column 2, row 1 position (index 7) + * @param {Number} m22 Component in column 2, row 2 position (index 8) + * @returns {mat3} out + */ + + function set$6(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) { + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m10; + out[4] = m11; + out[5] = m12; + out[6] = m20; + out[7] = m21; + out[8] = m22; + return out; + } + /** + * Set a mat3 to the identity matrix + * + * @param {mat3} out the receiving matrix + * @returns {mat3} out + */ + + function identity$3(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 1; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 1; + return out; + } + /** + * Transpose the values of a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + + function transpose$1(out, a) { + // If we are transposing ourselves we can skip a few steps but have to cache some values + if (out === a) { + var a01 = a[1], + a02 = a[2], + a12 = a[5]; + out[1] = a[3]; + out[2] = a[6]; + out[3] = a01; + out[5] = a[7]; + out[6] = a02; + out[7] = a12; + } else { + out[0] = a[0]; + out[1] = a[3]; + out[2] = a[6]; + out[3] = a[1]; + out[4] = a[4]; + out[5] = a[7]; + out[6] = a[2]; + out[7] = a[5]; + out[8] = a[8]; + } + + return out; + } + /** + * Inverts a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + + function invert$3(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + var b01 = a22 * a11 - a12 * a21; + var b11 = -a22 * a10 + a12 * a20; + var b21 = a21 * a10 - a11 * a20; // Calculate the determinant + + var det = a00 * b01 + a01 * b11 + a02 * b21; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = b01 * det; + out[1] = (-a22 * a01 + a02 * a21) * det; + out[2] = (a12 * a01 - a02 * a11) * det; + out[3] = b11 * det; + out[4] = (a22 * a00 - a02 * a20) * det; + out[5] = (-a12 * a00 + a02 * a10) * det; + out[6] = b21 * det; + out[7] = (-a21 * a00 + a01 * a20) * det; + out[8] = (a11 * a00 - a01 * a10) * det; + return out; + } + /** + * Calculates the adjugate of a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the source matrix + * @returns {mat3} out + */ + + function adjoint$1(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + out[0] = a11 * a22 - a12 * a21; + out[1] = a02 * a21 - a01 * a22; + out[2] = a01 * a12 - a02 * a11; + out[3] = a12 * a20 - a10 * a22; + out[4] = a00 * a22 - a02 * a20; + out[5] = a02 * a10 - a00 * a12; + out[6] = a10 * a21 - a11 * a20; + out[7] = a01 * a20 - a00 * a21; + out[8] = a00 * a11 - a01 * a10; + return out; + } + /** + * Calculates the determinant of a mat3 + * + * @param {ReadonlyMat3} a the source matrix + * @returns {Number} determinant of a + */ + + function determinant$1(a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); + } + /** + * Multiplies two mat3's + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the first operand + * @param {ReadonlyMat3} b the second operand + * @returns {mat3} out + */ + + function multiply$6(out, a, b) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + var b00 = b[0], + b01 = b[1], + b02 = b[2]; + var b10 = b[3], + b11 = b[4], + b12 = b[5]; + var b20 = b[6], + b21 = b[7], + b22 = b[8]; + out[0] = b00 * a00 + b01 * a10 + b02 * a20; + out[1] = b00 * a01 + b01 * a11 + b02 * a21; + out[2] = b00 * a02 + b01 * a12 + b02 * a22; + out[3] = b10 * a00 + b11 * a10 + b12 * a20; + out[4] = b10 * a01 + b11 * a11 + b12 * a21; + out[5] = b10 * a02 + b11 * a12 + b12 * a22; + out[6] = b20 * a00 + b21 * a10 + b22 * a20; + out[7] = b20 * a01 + b21 * a11 + b22 * a21; + out[8] = b20 * a02 + b21 * a12 + b22 * a22; + return out; + } + /** + * Translate a mat3 by the given vector + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the matrix to translate + * @param {ReadonlyVec2} v vector to translate by + * @returns {mat3} out + */ + + function translate$2(out, a, v) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a10 = a[3], + a11 = a[4], + a12 = a[5], + a20 = a[6], + a21 = a[7], + a22 = a[8], + x = v[0], + y = v[1]; + out[0] = a00; + out[1] = a01; + out[2] = a02; + out[3] = a10; + out[4] = a11; + out[5] = a12; + out[6] = x * a00 + y * a10 + a20; + out[7] = x * a01 + y * a11 + a21; + out[8] = x * a02 + y * a12 + a22; + return out; + } + /** + * Rotates a mat3 by the given angle + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat3} out + */ + + function rotate$2(out, a, rad) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a10 = a[3], + a11 = a[4], + a12 = a[5], + a20 = a[6], + a21 = a[7], + a22 = a[8], + s = Math.sin(rad), + c = Math.cos(rad); + out[0] = c * a00 + s * a10; + out[1] = c * a01 + s * a11; + out[2] = c * a02 + s * a12; + out[3] = c * a10 - s * a00; + out[4] = c * a11 - s * a01; + out[5] = c * a12 - s * a02; + out[6] = a20; + out[7] = a21; + out[8] = a22; + return out; + } + /** + * Scales the mat3 by the dimensions in the given vec2 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the matrix to rotate + * @param {ReadonlyVec2} v the vec2 to scale the matrix by + * @returns {mat3} out + **/ + + function scale$6(out, a, v) { + var x = v[0], + y = v[1]; + out[0] = x * a[0]; + out[1] = x * a[1]; + out[2] = x * a[2]; + out[3] = y * a[3]; + out[4] = y * a[4]; + out[5] = y * a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + return out; + } + /** + * Creates a matrix from a vector translation + * This is equivalent to (but much faster than): + * + * mat3.identity(dest); + * mat3.translate(dest, dest, vec); + * + * @param {mat3} out mat3 receiving operation result + * @param {ReadonlyVec2} v Translation vector + * @returns {mat3} out + */ + + function fromTranslation$2(out, v) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 1; + out[5] = 0; + out[6] = v[0]; + out[7] = v[1]; + out[8] = 1; + return out; + } + /** + * Creates a matrix from a given angle + * This is equivalent to (but much faster than): + * + * mat3.identity(dest); + * mat3.rotate(dest, dest, rad); + * + * @param {mat3} out mat3 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat3} out + */ + + function fromRotation$2(out, rad) { + var s = Math.sin(rad), + c = Math.cos(rad); + out[0] = c; + out[1] = s; + out[2] = 0; + out[3] = -s; + out[4] = c; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 1; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat3.identity(dest); + * mat3.scale(dest, dest, vec); + * + * @param {mat3} out mat3 receiving operation result + * @param {ReadonlyVec2} v Scaling vector + * @returns {mat3} out + */ + + function fromScaling$1(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = v[1]; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 1; + return out; + } + /** + * Copies the values from a mat2d into a mat3 + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat2d} a the matrix to copy + * @returns {mat3} out + **/ + + function fromMat2d(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = 0; + out[3] = a[2]; + out[4] = a[3]; + out[5] = 0; + out[6] = a[4]; + out[7] = a[5]; + out[8] = 1; + return out; + } + /** + * Calculates a 3x3 matrix from the given quaternion + * + * @param {mat3} out mat3 receiving operation result + * @param {ReadonlyQuat} q Quaternion to create matrix from + * + * @returns {mat3} out + */ + + function fromQuat$1(out, q) { + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var yx = y * x2; + var yy = y * y2; + var zx = z * x2; + var zy = z * y2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - yy - zz; + out[3] = yx - wz; + out[6] = zx + wy; + out[1] = yx + wz; + out[4] = 1 - xx - zz; + out[7] = zy - wx; + out[2] = zx - wy; + out[5] = zy + wx; + out[8] = 1 - xx - yy; + return out; + } + /** + * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix + * + * @param {mat3} out mat3 receiving operation result + * @param {ReadonlyMat4} a Mat4 to derive the normal matrix from + * + * @returns {mat3} out + */ + + function normalFromMat4(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + return out; + } + /** + * Generates a 2D projection matrix with the given bounds + * + * @param {mat3} out mat3 frustum matrix will be written into + * @param {number} width Width of your gl context + * @param {number} height Height of gl context + * @returns {mat3} out + */ + + function projection(out, width, height) { + out[0] = 2 / width; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = -2 / height; + out[5] = 0; + out[6] = -1; + out[7] = 1; + out[8] = 1; + return out; + } + /** + * Returns a string representation of a mat3 + * + * @param {ReadonlyMat3} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ + + function str$6(a) { + return "mat3(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ")"; + } + /** + * Returns Frobenius norm of a mat3 + * + * @param {ReadonlyMat3} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ + + function frob$1(a) { + return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); + } + /** + * Adds two mat3's + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the first operand + * @param {ReadonlyMat3} b the second operand + * @returns {mat3} out + */ + + function add$6(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; + out[7] = a[7] + b[7]; + out[8] = a[8] + b[8]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the first operand + * @param {ReadonlyMat3} b the second operand + * @returns {mat3} out + */ + + function subtract$4(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + out[4] = a[4] - b[4]; + out[5] = a[5] - b[5]; + out[6] = a[6] - b[6]; + out[7] = a[7] - b[7]; + out[8] = a[8] - b[8]; + return out; + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat3} out the receiving matrix + * @param {ReadonlyMat3} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat3} out + */ + + function multiplyScalar$1(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + out[4] = a[4] * b; + out[5] = a[5] * b; + out[6] = a[6] * b; + out[7] = a[7] * b; + out[8] = a[8] * b; + return out; + } + /** + * Adds two mat3's after multiplying each element of the second operand by a scalar value. + * + * @param {mat3} out the receiving vector + * @param {ReadonlyMat3} a the first operand + * @param {ReadonlyMat3} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat3} out + */ + + function multiplyScalarAndAdd$1(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + out[4] = a[4] + b[4] * scale; + out[5] = a[5] + b[5] * scale; + out[6] = a[6] + b[6] * scale; + out[7] = a[7] + b[7] * scale; + out[8] = a[8] + b[8] * scale; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyMat3} a The first matrix. + * @param {ReadonlyMat3} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function exactEquals$6(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {ReadonlyMat3} a The first matrix. + * @param {ReadonlyMat3} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function equals$6(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5], + a6 = a[6], + a7 = a[7], + a8 = a[8]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7], + b8 = b[8]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)); + } + /** + * Alias for {@link mat3.multiply} + * @function + */ + + var mul$6 = multiply$6; + /** + * Alias for {@link mat3.subtract} + * @function + */ + + var sub$4 = subtract$4; + + var mat3 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$6, + fromMat4: fromMat4$1, + clone: clone$6, + copy: copy$6, + fromValues: fromValues$6, + set: set$6, + identity: identity$3, + transpose: transpose$1, + invert: invert$3, + adjoint: adjoint$1, + determinant: determinant$1, + multiply: multiply$6, + translate: translate$2, + rotate: rotate$2, + scale: scale$6, + fromTranslation: fromTranslation$2, + fromRotation: fromRotation$2, + fromScaling: fromScaling$1, + fromMat2d: fromMat2d, + fromQuat: fromQuat$1, + normalFromMat4: normalFromMat4, + projection: projection, + str: str$6, + frob: frob$1, + add: add$6, + subtract: subtract$4, + multiplyScalar: multiplyScalar$1, + multiplyScalarAndAdd: multiplyScalarAndAdd$1, + exactEquals: exactEquals$6, + equals: equals$6, + mul: mul$6, + sub: sub$4 + }); + + /** + * 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied. + * @module mat4 + */ + + /** + * Creates a new identity mat4 + * + * @returns {mat4} a new 4x4 matrix + */ + + function create$5() { + var out = new ARRAY_TYPE(16); + + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + } + + out[0] = 1; + out[5] = 1; + out[10] = 1; + out[15] = 1; + return out; + } + /** + * Creates a new mat4 initialized with values from an existing matrix + * + * @param {ReadonlyMat4} a matrix to clone + * @returns {mat4} a new 4x4 matrix + */ + + function clone$5(a) { + var out = new ARRAY_TYPE(16); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + out[9] = a[9]; + out[10] = a[10]; + out[11] = a[11]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + return out; + } + /** + * Copy the values from one mat4 to another + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the source matrix + * @returns {mat4} out + */ + + function copy$5(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + out[9] = a[9]; + out[10] = a[10]; + out[11] = a[11]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + return out; + } + /** + * Create a new mat4 with the given values + * + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m03 Component in column 0, row 3 position (index 3) + * @param {Number} m10 Component in column 1, row 0 position (index 4) + * @param {Number} m11 Component in column 1, row 1 position (index 5) + * @param {Number} m12 Component in column 1, row 2 position (index 6) + * @param {Number} m13 Component in column 1, row 3 position (index 7) + * @param {Number} m20 Component in column 2, row 0 position (index 8) + * @param {Number} m21 Component in column 2, row 1 position (index 9) + * @param {Number} m22 Component in column 2, row 2 position (index 10) + * @param {Number} m23 Component in column 2, row 3 position (index 11) + * @param {Number} m30 Component in column 3, row 0 position (index 12) + * @param {Number} m31 Component in column 3, row 1 position (index 13) + * @param {Number} m32 Component in column 3, row 2 position (index 14) + * @param {Number} m33 Component in column 3, row 3 position (index 15) + * @returns {mat4} A new mat4 + */ + + function fromValues$5(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { + var out = new ARRAY_TYPE(16); + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m03; + out[4] = m10; + out[5] = m11; + out[6] = m12; + out[7] = m13; + out[8] = m20; + out[9] = m21; + out[10] = m22; + out[11] = m23; + out[12] = m30; + out[13] = m31; + out[14] = m32; + out[15] = m33; + return out; + } + /** + * Set the components of a mat4 to the given values + * + * @param {mat4} out the receiving matrix + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m03 Component in column 0, row 3 position (index 3) + * @param {Number} m10 Component in column 1, row 0 position (index 4) + * @param {Number} m11 Component in column 1, row 1 position (index 5) + * @param {Number} m12 Component in column 1, row 2 position (index 6) + * @param {Number} m13 Component in column 1, row 3 position (index 7) + * @param {Number} m20 Component in column 2, row 0 position (index 8) + * @param {Number} m21 Component in column 2, row 1 position (index 9) + * @param {Number} m22 Component in column 2, row 2 position (index 10) + * @param {Number} m23 Component in column 2, row 3 position (index 11) + * @param {Number} m30 Component in column 3, row 0 position (index 12) + * @param {Number} m31 Component in column 3, row 1 position (index 13) + * @param {Number} m32 Component in column 3, row 2 position (index 14) + * @param {Number} m33 Component in column 3, row 3 position (index 15) + * @returns {mat4} out + */ + + function set$5(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m03; + out[4] = m10; + out[5] = m11; + out[6] = m12; + out[7] = m13; + out[8] = m20; + out[9] = m21; + out[10] = m22; + out[11] = m23; + out[12] = m30; + out[13] = m31; + out[14] = m32; + out[15] = m33; + return out; + } + /** + * Set a mat4 to the identity matrix + * + * @param {mat4} out the receiving matrix + * @returns {mat4} out + */ + + function identity$2(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Transpose the values of a mat4 + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the source matrix + * @returns {mat4} out + */ + + function transpose(out, a) { + // If we are transposing ourselves we can skip a few steps but have to cache some values + if (out === a) { + var a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a12 = a[6], + a13 = a[7]; + var a23 = a[11]; + out[1] = a[4]; + out[2] = a[8]; + out[3] = a[12]; + out[4] = a01; + out[6] = a[9]; + out[7] = a[13]; + out[8] = a02; + out[9] = a12; + out[11] = a[14]; + out[12] = a03; + out[13] = a13; + out[14] = a23; + } else { + out[0] = a[0]; + out[1] = a[4]; + out[2] = a[8]; + out[3] = a[12]; + out[4] = a[1]; + out[5] = a[5]; + out[6] = a[9]; + out[7] = a[13]; + out[8] = a[2]; + out[9] = a[6]; + out[10] = a[10]; + out[11] = a[14]; + out[12] = a[3]; + out[13] = a[7]; + out[14] = a[11]; + out[15] = a[15]; + } + + return out; + } + /** + * Inverts a mat4 + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the source matrix + * @returns {mat4} out + */ + + function invert$2(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) { + return null; + } + + det = 1.0 / det; + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; + out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; + out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; + out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; + out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; + out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; + out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; + return out; + } + /** + * Calculates the adjugate of a mat4 + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the source matrix + * @returns {mat4} out + */ + + function adjoint(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; + out[0] = a11 * b11 - a12 * b10 + a13 * b09; + out[1] = a02 * b10 - a01 * b11 - a03 * b09; + out[2] = a31 * b05 - a32 * b04 + a33 * b03; + out[3] = a22 * b04 - a21 * b05 - a23 * b03; + out[4] = a12 * b08 - a10 * b11 - a13 * b07; + out[5] = a00 * b11 - a02 * b08 + a03 * b07; + out[6] = a32 * b02 - a30 * b05 - a33 * b01; + out[7] = a20 * b05 - a22 * b02 + a23 * b01; + out[8] = a10 * b10 - a11 * b08 + a13 * b06; + out[9] = a01 * b08 - a00 * b10 - a03 * b06; + out[10] = a30 * b04 - a31 * b02 + a33 * b00; + out[11] = a21 * b02 - a20 * b04 - a23 * b00; + out[12] = a11 * b07 - a10 * b09 - a12 * b06; + out[13] = a00 * b09 - a01 * b07 + a02 * b06; + out[14] = a31 * b01 - a30 * b03 - a32 * b00; + out[15] = a20 * b03 - a21 * b01 + a22 * b00; + return out; + } + /** + * Calculates the determinant of a mat4 + * + * @param {ReadonlyMat4} a the source matrix + * @returns {Number} determinant of a + */ + + function determinant(a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + var b0 = a00 * a11 - a01 * a10; + var b1 = a00 * a12 - a02 * a10; + var b2 = a01 * a12 - a02 * a11; + var b3 = a20 * a31 - a21 * a30; + var b4 = a20 * a32 - a22 * a30; + var b5 = a21 * a32 - a22 * a31; + var b6 = a00 * b5 - a01 * b4 + a02 * b3; + var b7 = a10 * b5 - a11 * b4 + a12 * b3; + var b8 = a20 * b2 - a21 * b1 + a22 * b0; + var b9 = a30 * b2 - a31 * b1 + a32 * b0; // Calculate the determinant + + return a13 * b6 - a03 * b7 + a33 * b8 - a23 * b9; + } + /** + * Multiplies two mat4s + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand + * @returns {mat4} out + */ + + function multiply$5(out, a, b) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; // Cache only the current line of the second matrix + + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[4]; + b1 = b[5]; + b2 = b[6]; + b3 = b[7]; + out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[8]; + b1 = b[9]; + b2 = b[10]; + b3 = b[11]; + out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[12]; + b1 = b[13]; + b2 = b[14]; + b3 = b[15]; + out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + return out; + } + /** + * Translate a mat4 by the given vector + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to translate + * @param {ReadonlyVec3} v vector to translate by + * @returns {mat4} out + */ + + function translate$1(out, a, v) { + var x = v[0], + y = v[1], + z = v[2]; + var a00, a01, a02, a03; + var a10, a11, a12, a13; + var a20, a21, a22, a23; + + if (a === out) { + out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; + out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; + out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; + out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; + } else { + a00 = a[0]; + a01 = a[1]; + a02 = a[2]; + a03 = a[3]; + a10 = a[4]; + a11 = a[5]; + a12 = a[6]; + a13 = a[7]; + a20 = a[8]; + a21 = a[9]; + a22 = a[10]; + a23 = a[11]; + out[0] = a00; + out[1] = a01; + out[2] = a02; + out[3] = a03; + out[4] = a10; + out[5] = a11; + out[6] = a12; + out[7] = a13; + out[8] = a20; + out[9] = a21; + out[10] = a22; + out[11] = a23; + out[12] = a00 * x + a10 * y + a20 * z + a[12]; + out[13] = a01 * x + a11 * y + a21 * z + a[13]; + out[14] = a02 * x + a12 * y + a22 * z + a[14]; + out[15] = a03 * x + a13 * y + a23 * z + a[15]; + } + + return out; + } + /** + * Scales the mat4 by the dimensions in the given vec3 not using vectorization + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to scale + * @param {ReadonlyVec3} v the vec3 to scale the matrix by + * @returns {mat4} out + **/ + + function scale$5(out, a, v) { + var x = v[0], + y = v[1], + z = v[2]; + out[0] = a[0] * x; + out[1] = a[1] * x; + out[2] = a[2] * x; + out[3] = a[3] * x; + out[4] = a[4] * y; + out[5] = a[5] * y; + out[6] = a[6] * y; + out[7] = a[7] * y; + out[8] = a[8] * z; + out[9] = a[9] * z; + out[10] = a[10] * z; + out[11] = a[11] * z; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + return out; + } + /** + * Rotates a mat4 by the given angle around the given axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @param {ReadonlyVec3} axis the axis to rotate around + * @returns {mat4} out + */ + + function rotate$1(out, a, rad, axis) { + var x = axis[0], + y = axis[1], + z = axis[2]; + var len = Math.hypot(x, y, z); + var s, c, t; + var a00, a01, a02, a03; + var a10, a11, a12, a13; + var a20, a21, a22, a23; + var b00, b01, b02; + var b10, b11, b12; + var b20, b21, b22; + + if (len < EPSILON) { + return null; + } + + len = 1 / len; + x *= len; + y *= len; + z *= len; + s = Math.sin(rad); + c = Math.cos(rad); + t = 1 - c; + a00 = a[0]; + a01 = a[1]; + a02 = a[2]; + a03 = a[3]; + a10 = a[4]; + a11 = a[5]; + a12 = a[6]; + a13 = a[7]; + a20 = a[8]; + a21 = a[9]; + a22 = a[10]; + a23 = a[11]; // Construct the elements of the rotation matrix + + b00 = x * x * t + c; + b01 = y * x * t + z * s; + b02 = z * x * t - y * s; + b10 = x * y * t - z * s; + b11 = y * y * t + c; + b12 = z * y * t + x * s; + b20 = x * z * t + y * s; + b21 = y * z * t - x * s; + b22 = z * z * t + c; // Perform rotation-specific matrix multiplication + + out[0] = a00 * b00 + a10 * b01 + a20 * b02; + out[1] = a01 * b00 + a11 * b01 + a21 * b02; + out[2] = a02 * b00 + a12 * b01 + a22 * b02; + out[3] = a03 * b00 + a13 * b01 + a23 * b02; + out[4] = a00 * b10 + a10 * b11 + a20 * b12; + out[5] = a01 * b10 + a11 * b11 + a21 * b12; + out[6] = a02 * b10 + a12 * b11 + a22 * b12; + out[7] = a03 * b10 + a13 * b11 + a23 * b12; + out[8] = a00 * b20 + a10 * b21 + a20 * b22; + out[9] = a01 * b20 + a11 * b21 + a21 * b22; + out[10] = a02 * b20 + a12 * b21 + a22 * b22; + out[11] = a03 * b20 + a13 * b21 + a23 * b22; + + if (a !== out) { + // If the source and destination differ, copy the unchanged last row + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } + + return out; + } + /** + * Rotates a matrix by the given angle around the X axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function rotateX$3(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + + if (a !== out) { + // If the source and destination differ, copy the unchanged rows + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[4] = a10 * c + a20 * s; + out[5] = a11 * c + a21 * s; + out[6] = a12 * c + a22 * s; + out[7] = a13 * c + a23 * s; + out[8] = a20 * c - a10 * s; + out[9] = a21 * c - a11 * s; + out[10] = a22 * c - a12 * s; + out[11] = a23 * c - a13 * s; + return out; + } + /** + * Rotates a matrix by the given angle around the Y axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function rotateY$3(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; + + if (a !== out) { + // If the source and destination differ, copy the unchanged rows + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[0] = a00 * c - a20 * s; + out[1] = a01 * c - a21 * s; + out[2] = a02 * c - a22 * s; + out[3] = a03 * c - a23 * s; + out[8] = a00 * s + a20 * c; + out[9] = a01 * s + a21 * c; + out[10] = a02 * s + a22 * c; + out[11] = a03 * s + a23 * c; + return out; + } + /** + * Rotates a matrix by the given angle around the Z axis + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function rotateZ$3(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + + if (a !== out) { + // If the source and destination differ, copy the unchanged last row + out[8] = a[8]; + out[9] = a[9]; + out[10] = a[10]; + out[11] = a[11]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[0] = a00 * c + a10 * s; + out[1] = a01 * c + a11 * s; + out[2] = a02 * c + a12 * s; + out[3] = a03 * c + a13 * s; + out[4] = a10 * c - a00 * s; + out[5] = a11 * c - a01 * s; + out[6] = a12 * c - a02 * s; + out[7] = a13 * c - a03 * s; + return out; + } + /** + * Creates a matrix from a vector translation + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, dest, vec); + * + * @param {mat4} out mat4 receiving operation result + * @param {ReadonlyVec3} v Translation vector + * @returns {mat4} out + */ + + function fromTranslation$1(out, v) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.scale(dest, dest, vec); + * + * @param {mat4} out mat4 receiving operation result + * @param {ReadonlyVec3} v Scaling vector + * @returns {mat4} out + */ + + function fromScaling(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = v[1]; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = v[2]; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from a given angle around a given axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotate(dest, dest, rad, axis); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @param {ReadonlyVec3} axis the axis to rotate around + * @returns {mat4} out + */ + + function fromRotation$1(out, rad, axis) { + var x = axis[0], + y = axis[1], + z = axis[2]; + var len = Math.hypot(x, y, z); + var s, c, t; + + if (len < EPSILON) { + return null; + } + + len = 1 / len; + x *= len; + y *= len; + z *= len; + s = Math.sin(rad); + c = Math.cos(rad); + t = 1 - c; // Perform rotation-specific matrix multiplication + + out[0] = x * x * t + c; + out[1] = y * x * t + z * s; + out[2] = z * x * t - y * s; + out[3] = 0; + out[4] = x * y * t - z * s; + out[5] = y * y * t + c; + out[6] = z * y * t + x * s; + out[7] = 0; + out[8] = x * z * t + y * s; + out[9] = y * z * t - x * s; + out[10] = z * z * t + c; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from the given angle around the X axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotateX(dest, dest, rad); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function fromXRotation(out, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); // Perform axis-specific matrix multiplication + + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = c; + out[6] = s; + out[7] = 0; + out[8] = 0; + out[9] = -s; + out[10] = c; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from the given angle around the Y axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotateY(dest, dest, rad); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function fromYRotation(out, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); // Perform axis-specific matrix multiplication + + out[0] = c; + out[1] = 0; + out[2] = -s; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = s; + out[9] = 0; + out[10] = c; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from the given angle around the Z axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotateZ(dest, dest, rad); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ + + function fromZRotation(out, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); // Perform axis-specific matrix multiplication + + out[0] = c; + out[1] = s; + out[2] = 0; + out[3] = 0; + out[4] = -s; + out[5] = c; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from a quaternion rotation and vector translation + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, vec); + * let quatMat = mat4.create(); + * quat4.toMat4(quat, quatMat); + * mat4.multiply(dest, quatMat); + * + * @param {mat4} out mat4 receiving operation result + * @param {quat4} q Rotation quaternion + * @param {ReadonlyVec3} v Translation vector + * @returns {mat4} out + */ + + function fromRotationTranslation$1(out, q, v) { + // Quaternion math + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - (yy + zz); + out[1] = xy + wz; + out[2] = xz - wy; + out[3] = 0; + out[4] = xy - wz; + out[5] = 1 - (xx + zz); + out[6] = yz + wx; + out[7] = 0; + out[8] = xz + wy; + out[9] = yz - wx; + out[10] = 1 - (xx + yy); + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + /** + * Creates a new mat4 from a dual quat. + * + * @param {mat4} out Matrix + * @param {ReadonlyQuat2} a Dual Quaternion + * @returns {mat4} mat4 receiving operation result + */ + + function fromQuat2(out, a) { + var translation = new ARRAY_TYPE(3); + var bx = -a[0], + by = -a[1], + bz = -a[2], + bw = a[3], + ax = a[4], + ay = a[5], + az = a[6], + aw = a[7]; + var magnitude = bx * bx + by * by + bz * bz + bw * bw; //Only scale if it makes sense + + if (magnitude > 0) { + translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude; + translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude; + translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude; + } else { + translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2; + translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2; + translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2; + } + + fromRotationTranslation$1(out, a, translation); + return out; + } + /** + * Returns the translation vector component of a transformation + * matrix. If a matrix is built with fromRotationTranslation, + * the returned vector will be the same as the translation vector + * originally supplied. + * @param {vec3} out Vector to receive translation component + * @param {ReadonlyMat4} mat Matrix to be decomposed (input) + * @return {vec3} out + */ + + function getTranslation$1(out, mat) { + out[0] = mat[12]; + out[1] = mat[13]; + out[2] = mat[14]; + return out; + } + /** + * Returns the scaling factor component of a transformation + * matrix. If a matrix is built with fromRotationTranslationScale + * with a normalized Quaternion paramter, the returned vector will be + * the same as the scaling vector + * originally supplied. + * @param {vec3} out Vector to receive scaling factor component + * @param {ReadonlyMat4} mat Matrix to be decomposed (input) + * @return {vec3} out + */ + + function getScaling(out, mat) { + var m11 = mat[0]; + var m12 = mat[1]; + var m13 = mat[2]; + var m21 = mat[4]; + var m22 = mat[5]; + var m23 = mat[6]; + var m31 = mat[8]; + var m32 = mat[9]; + var m33 = mat[10]; + out[0] = Math.hypot(m11, m12, m13); + out[1] = Math.hypot(m21, m22, m23); + out[2] = Math.hypot(m31, m32, m33); + return out; + } + /** + * Returns a quaternion representing the rotational component + * of a transformation matrix. If a matrix is built with + * fromRotationTranslation, the returned quaternion will be the + * same as the quaternion originally supplied. + * @param {quat} out Quaternion to receive the rotation component + * @param {ReadonlyMat4} mat Matrix to be decomposed (input) + * @return {quat} out + */ + + function getRotation(out, mat) { + var scaling = new ARRAY_TYPE(3); + getScaling(scaling, mat); + var is1 = 1 / scaling[0]; + var is2 = 1 / scaling[1]; + var is3 = 1 / scaling[2]; + var sm11 = mat[0] * is1; + var sm12 = mat[1] * is2; + var sm13 = mat[2] * is3; + var sm21 = mat[4] * is1; + var sm22 = mat[5] * is2; + var sm23 = mat[6] * is3; + var sm31 = mat[8] * is1; + var sm32 = mat[9] * is2; + var sm33 = mat[10] * is3; + var trace = sm11 + sm22 + sm33; + var S = 0; + + if (trace > 0) { + S = Math.sqrt(trace + 1.0) * 2; + out[3] = 0.25 * S; + out[0] = (sm23 - sm32) / S; + out[1] = (sm31 - sm13) / S; + out[2] = (sm12 - sm21) / S; + } else if (sm11 > sm22 && sm11 > sm33) { + S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2; + out[3] = (sm23 - sm32) / S; + out[0] = 0.25 * S; + out[1] = (sm12 + sm21) / S; + out[2] = (sm31 + sm13) / S; + } else if (sm22 > sm33) { + S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2; + out[3] = (sm31 - sm13) / S; + out[0] = (sm12 + sm21) / S; + out[1] = 0.25 * S; + out[2] = (sm23 + sm32) / S; + } else { + S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2; + out[3] = (sm12 - sm21) / S; + out[0] = (sm31 + sm13) / S; + out[1] = (sm23 + sm32) / S; + out[2] = 0.25 * S; + } + + return out; + } + /** + * Decomposes a transformation matrix into its rotation, translation + * and scale components. Returns only the rotation component + * @param {quat} out_r Quaternion to receive the rotation component + * @param {vec3} out_t Vector to receive the translation vector + * @param {vec3} out_s Vector to receive the scaling factor + * @param {ReadonlyMat4} mat Matrix to be decomposed (input) + * @returns {quat} out_r + */ + + function decompose(out_r, out_t, out_s, mat) { + out_t[0] = mat[12]; + out_t[1] = mat[13]; + out_t[2] = mat[14]; + var m11 = mat[0]; + var m12 = mat[1]; + var m13 = mat[2]; + var m21 = mat[4]; + var m22 = mat[5]; + var m23 = mat[6]; + var m31 = mat[8]; + var m32 = mat[9]; + var m33 = mat[10]; + out_s[0] = Math.hypot(m11, m12, m13); + out_s[1] = Math.hypot(m21, m22, m23); + out_s[2] = Math.hypot(m31, m32, m33); + var is1 = 1 / out_s[0]; + var is2 = 1 / out_s[1]; + var is3 = 1 / out_s[2]; + var sm11 = m11 * is1; + var sm12 = m12 * is2; + var sm13 = m13 * is3; + var sm21 = m21 * is1; + var sm22 = m22 * is2; + var sm23 = m23 * is3; + var sm31 = m31 * is1; + var sm32 = m32 * is2; + var sm33 = m33 * is3; + var trace = sm11 + sm22 + sm33; + var S = 0; + + if (trace > 0) { + S = Math.sqrt(trace + 1.0) * 2; + out_r[3] = 0.25 * S; + out_r[0] = (sm23 - sm32) / S; + out_r[1] = (sm31 - sm13) / S; + out_r[2] = (sm12 - sm21) / S; + } else if (sm11 > sm22 && sm11 > sm33) { + S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2; + out_r[3] = (sm23 - sm32) / S; + out_r[0] = 0.25 * S; + out_r[1] = (sm12 + sm21) / S; + out_r[2] = (sm31 + sm13) / S; + } else if (sm22 > sm33) { + S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2; + out_r[3] = (sm31 - sm13) / S; + out_r[0] = (sm12 + sm21) / S; + out_r[1] = 0.25 * S; + out_r[2] = (sm23 + sm32) / S; + } else { + S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2; + out_r[3] = (sm12 - sm21) / S; + out_r[0] = (sm31 + sm13) / S; + out_r[1] = (sm23 + sm32) / S; + out_r[2] = 0.25 * S; + } + + return out_r; + } + /** + * Creates a matrix from a quaternion rotation, vector translation and vector scale + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, vec); + * let quatMat = mat4.create(); + * quat4.toMat4(quat, quatMat); + * mat4.multiply(dest, quatMat); + * mat4.scale(dest, scale) + * + * @param {mat4} out mat4 receiving operation result + * @param {quat4} q Rotation quaternion + * @param {ReadonlyVec3} v Translation vector + * @param {ReadonlyVec3} s Scaling vector + * @returns {mat4} out + */ + + function fromRotationTranslationScale(out, q, v, s) { + // Quaternion math + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + var sx = s[0]; + var sy = s[1]; + var sz = s[2]; + out[0] = (1 - (yy + zz)) * sx; + out[1] = (xy + wz) * sx; + out[2] = (xz - wy) * sx; + out[3] = 0; + out[4] = (xy - wz) * sy; + out[5] = (1 - (xx + zz)) * sy; + out[6] = (yz + wx) * sy; + out[7] = 0; + out[8] = (xz + wy) * sz; + out[9] = (yz - wx) * sz; + out[10] = (1 - (xx + yy)) * sz; + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + /** + * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, vec); + * mat4.translate(dest, origin); + * let quatMat = mat4.create(); + * quat4.toMat4(quat, quatMat); + * mat4.multiply(dest, quatMat); + * mat4.scale(dest, scale) + * mat4.translate(dest, negativeOrigin); + * + * @param {mat4} out mat4 receiving operation result + * @param {quat4} q Rotation quaternion + * @param {ReadonlyVec3} v Translation vector + * @param {ReadonlyVec3} s Scaling vector + * @param {ReadonlyVec3} o The origin vector around which to scale and rotate + * @returns {mat4} out + */ + + function fromRotationTranslationScaleOrigin(out, q, v, s, o) { + // Quaternion math + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + var sx = s[0]; + var sy = s[1]; + var sz = s[2]; + var ox = o[0]; + var oy = o[1]; + var oz = o[2]; + var out0 = (1 - (yy + zz)) * sx; + var out1 = (xy + wz) * sx; + var out2 = (xz - wy) * sx; + var out4 = (xy - wz) * sy; + var out5 = (1 - (xx + zz)) * sy; + var out6 = (yz + wx) * sy; + var out8 = (xz + wy) * sz; + var out9 = (yz - wx) * sz; + var out10 = (1 - (xx + yy)) * sz; + out[0] = out0; + out[1] = out1; + out[2] = out2; + out[3] = 0; + out[4] = out4; + out[5] = out5; + out[6] = out6; + out[7] = 0; + out[8] = out8; + out[9] = out9; + out[10] = out10; + out[11] = 0; + out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz); + out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz); + out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz); + out[15] = 1; + return out; + } + /** + * Calculates a 4x4 matrix from the given quaternion + * + * @param {mat4} out mat4 receiving operation result + * @param {ReadonlyQuat} q Quaternion to create matrix from + * + * @returns {mat4} out + */ + + function fromQuat(out, q) { + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var yx = y * x2; + var yy = y * y2; + var zx = z * x2; + var zy = z * y2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - yy - zz; + out[1] = yx + wz; + out[2] = zx - wy; + out[3] = 0; + out[4] = yx - wz; + out[5] = 1 - xx - zz; + out[6] = zy + wx; + out[7] = 0; + out[8] = zx + wy; + out[9] = zy - wx; + out[10] = 1 - xx - yy; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Generates a frustum matrix with the given bounds + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {Number} left Left bound of the frustum + * @param {Number} right Right bound of the frustum + * @param {Number} bottom Bottom bound of the frustum + * @param {Number} top Top bound of the frustum + * @param {Number} near Near bound of the frustum + * @param {Number} far Far bound of the frustum + * @returns {mat4} out + */ + + function frustum(out, left, right, bottom, top, near, far) { + var rl = 1 / (right - left); + var tb = 1 / (top - bottom); + var nf = 1 / (near - far); + out[0] = near * 2 * rl; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = near * 2 * tb; + out[6] = 0; + out[7] = 0; + out[8] = (right + left) * rl; + out[9] = (top + bottom) * tb; + out[10] = (far + near) * nf; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[14] = far * near * 2 * nf; + out[15] = 0; + return out; + } + /** + * Generates a perspective projection matrix with the given bounds. + * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1], + * which matches WebGL/OpenGL's clip volume. + * Passing null/undefined/no value for far will generate infinite projection matrix. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} fovy Vertical field of view in radians + * @param {number} aspect Aspect ratio. typically viewport width/height + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum, can be null or Infinity + * @returns {mat4} out + */ + + function perspectiveNO(out, fovy, aspect, near, far) { + var f = 1.0 / Math.tan(fovy / 2); + out[0] = f / aspect; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = f; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[15] = 0; + + if (far != null && far !== Infinity) { + var nf = 1 / (near - far); + out[10] = (far + near) * nf; + out[14] = 2 * far * near * nf; + } else { + out[10] = -1; + out[14] = -2 * near; + } + + return out; + } + /** + * Alias for {@link mat4.perspectiveNO} + * @function + */ + + var perspective = perspectiveNO; + /** + * Generates a perspective projection matrix suitable for WebGPU with the given bounds. + * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1], + * which matches WebGPU/Vulkan/DirectX/Metal's clip volume. + * Passing null/undefined/no value for far will generate infinite projection matrix. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} fovy Vertical field of view in radians + * @param {number} aspect Aspect ratio. typically viewport width/height + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum, can be null or Infinity + * @returns {mat4} out + */ + + function perspectiveZO(out, fovy, aspect, near, far) { + var f = 1.0 / Math.tan(fovy / 2); + out[0] = f / aspect; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = f; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[15] = 0; + + if (far != null && far !== Infinity) { + var nf = 1 / (near - far); + out[10] = far * nf; + out[14] = far * near * nf; + } else { + out[10] = -1; + out[14] = -near; + } + + return out; + } + /** + * Generates a perspective projection matrix with the given field of view. + * This is primarily useful for generating projection matrices to be used + * with the still experiemental WebVR API. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum + * @returns {mat4} out + */ + + function perspectiveFromFieldOfView(out, fov, near, far) { + var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0); + var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0); + var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0); + var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0); + var xScale = 2.0 / (leftTan + rightTan); + var yScale = 2.0 / (upTan + downTan); + out[0] = xScale; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + out[4] = 0.0; + out[5] = yScale; + out[6] = 0.0; + out[7] = 0.0; + out[8] = -((leftTan - rightTan) * xScale * 0.5); + out[9] = (upTan - downTan) * yScale * 0.5; + out[10] = far / (near - far); + out[11] = -1.0; + out[12] = 0.0; + out[13] = 0.0; + out[14] = far * near / (near - far); + out[15] = 0.0; + return out; + } + /** + * Generates a orthogonal projection matrix with the given bounds. + * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1], + * which matches WebGL/OpenGL's clip volume. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} left Left bound of the frustum + * @param {number} right Right bound of the frustum + * @param {number} bottom Bottom bound of the frustum + * @param {number} top Top bound of the frustum + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum + * @returns {mat4} out + */ + + function orthoNO(out, left, right, bottom, top, near, far) { + var lr = 1 / (left - right); + var bt = 1 / (bottom - top); + var nf = 1 / (near - far); + out[0] = -2 * lr; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = -2 * bt; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 2 * nf; + out[11] = 0; + out[12] = (left + right) * lr; + out[13] = (top + bottom) * bt; + out[14] = (far + near) * nf; + out[15] = 1; + return out; + } + /** + * Alias for {@link mat4.orthoNO} + * @function + */ + + var ortho = orthoNO; + /** + * Generates a orthogonal projection matrix with the given bounds. + * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1], + * which matches WebGPU/Vulkan/DirectX/Metal's clip volume. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} left Left bound of the frustum + * @param {number} right Right bound of the frustum + * @param {number} bottom Bottom bound of the frustum + * @param {number} top Top bound of the frustum + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum + * @returns {mat4} out + */ + + function orthoZO(out, left, right, bottom, top, near, far) { + var lr = 1 / (left - right); + var bt = 1 / (bottom - top); + var nf = 1 / (near - far); + out[0] = -2 * lr; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = -2 * bt; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = nf; + out[11] = 0; + out[12] = (left + right) * lr; + out[13] = (top + bottom) * bt; + out[14] = near * nf; + out[15] = 1; + return out; + } + /** + * Generates a look-at matrix with the given eye position, focal point, and up axis. + * If you want a matrix that actually makes an object look at another object, you should use targetTo instead. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {ReadonlyVec3} eye Position of the viewer + * @param {ReadonlyVec3} center Point the viewer is looking at + * @param {ReadonlyVec3} up vec3 pointing up + * @returns {mat4} out + */ + + function lookAt(out, eye, center, up) { + var x0, x1, x2, y0, y1, y2, z0, z1, z2, len; + var eyex = eye[0]; + var eyey = eye[1]; + var eyez = eye[2]; + var upx = up[0]; + var upy = up[1]; + var upz = up[2]; + var centerx = center[0]; + var centery = center[1]; + var centerz = center[2]; + + if (Math.abs(eyex - centerx) < EPSILON && Math.abs(eyey - centery) < EPSILON && Math.abs(eyez - centerz) < EPSILON) { + return identity$2(out); + } + + z0 = eyex - centerx; + z1 = eyey - centery; + z2 = eyez - centerz; + len = 1 / Math.hypot(z0, z1, z2); + z0 *= len; + z1 *= len; + z2 *= len; + x0 = upy * z2 - upz * z1; + x1 = upz * z0 - upx * z2; + x2 = upx * z1 - upy * z0; + len = Math.hypot(x0, x1, x2); + + if (!len) { + x0 = 0; + x1 = 0; + x2 = 0; + } else { + len = 1 / len; + x0 *= len; + x1 *= len; + x2 *= len; + } + + y0 = z1 * x2 - z2 * x1; + y1 = z2 * x0 - z0 * x2; + y2 = z0 * x1 - z1 * x0; + len = Math.hypot(y0, y1, y2); + + if (!len) { + y0 = 0; + y1 = 0; + y2 = 0; + } else { + len = 1 / len; + y0 *= len; + y1 *= len; + y2 *= len; + } + + out[0] = x0; + out[1] = y0; + out[2] = z0; + out[3] = 0; + out[4] = x1; + out[5] = y1; + out[6] = z1; + out[7] = 0; + out[8] = x2; + out[9] = y2; + out[10] = z2; + out[11] = 0; + out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); + out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); + out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); + out[15] = 1; + return out; + } + /** + * Generates a matrix that makes something look at something else. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {ReadonlyVec3} eye Position of the viewer + * @param {ReadonlyVec3} center Point the viewer is looking at + * @param {ReadonlyVec3} up vec3 pointing up + * @returns {mat4} out + */ + + function targetTo(out, eye, target, up) { + var eyex = eye[0], + eyey = eye[1], + eyez = eye[2], + upx = up[0], + upy = up[1], + upz = up[2]; + var z0 = eyex - target[0], + z1 = eyey - target[1], + z2 = eyez - target[2]; + var len = z0 * z0 + z1 * z1 + z2 * z2; + + if (len > 0) { + len = 1 / Math.sqrt(len); + z0 *= len; + z1 *= len; + z2 *= len; + } + + var x0 = upy * z2 - upz * z1, + x1 = upz * z0 - upx * z2, + x2 = upx * z1 - upy * z0; + len = x0 * x0 + x1 * x1 + x2 * x2; + + if (len > 0) { + len = 1 / Math.sqrt(len); + x0 *= len; + x1 *= len; + x2 *= len; + } + + out[0] = x0; + out[1] = x1; + out[2] = x2; + out[3] = 0; + out[4] = z1 * x2 - z2 * x1; + out[5] = z2 * x0 - z0 * x2; + out[6] = z0 * x1 - z1 * x0; + out[7] = 0; + out[8] = z0; + out[9] = z1; + out[10] = z2; + out[11] = 0; + out[12] = eyex; + out[13] = eyey; + out[14] = eyez; + out[15] = 1; + return out; + } + /** + * Returns a string representation of a mat4 + * + * @param {ReadonlyMat4} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ + + function str$5(a) { + return "mat4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + ")"; + } + /** + * Returns Frobenius norm of a mat4 + * + * @param {ReadonlyMat4} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ + + function frob(a) { + return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); + } + /** + * Adds two mat4's + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand + * @returns {mat4} out + */ + + function add$5(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; + out[7] = a[7] + b[7]; + out[8] = a[8] + b[8]; + out[9] = a[9] + b[9]; + out[10] = a[10] + b[10]; + out[11] = a[11] + b[11]; + out[12] = a[12] + b[12]; + out[13] = a[13] + b[13]; + out[14] = a[14] + b[14]; + out[15] = a[15] + b[15]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand + * @returns {mat4} out + */ + + function subtract$3(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + out[4] = a[4] - b[4]; + out[5] = a[5] - b[5]; + out[6] = a[6] - b[6]; + out[7] = a[7] - b[7]; + out[8] = a[8] - b[8]; + out[9] = a[9] - b[9]; + out[10] = a[10] - b[10]; + out[11] = a[11] - b[11]; + out[12] = a[12] - b[12]; + out[13] = a[13] - b[13]; + out[14] = a[14] - b[14]; + out[15] = a[15] - b[15]; + return out; + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat4} out the receiving matrix + * @param {ReadonlyMat4} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat4} out + */ + + function multiplyScalar(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + out[4] = a[4] * b; + out[5] = a[5] * b; + out[6] = a[6] * b; + out[7] = a[7] * b; + out[8] = a[8] * b; + out[9] = a[9] * b; + out[10] = a[10] * b; + out[11] = a[11] * b; + out[12] = a[12] * b; + out[13] = a[13] * b; + out[14] = a[14] * b; + out[15] = a[15] * b; + return out; + } + /** + * Adds two mat4's after multiplying each element of the second operand by a scalar value. + * + * @param {mat4} out the receiving vector + * @param {ReadonlyMat4} a the first operand + * @param {ReadonlyMat4} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat4} out + */ + + function multiplyScalarAndAdd(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + out[4] = a[4] + b[4] * scale; + out[5] = a[5] + b[5] * scale; + out[6] = a[6] + b[6] * scale; + out[7] = a[7] + b[7] * scale; + out[8] = a[8] + b[8] * scale; + out[9] = a[9] + b[9] * scale; + out[10] = a[10] + b[10] * scale; + out[11] = a[11] + b[11] * scale; + out[12] = a[12] + b[12] * scale; + out[13] = a[13] + b[13] * scale; + out[14] = a[14] + b[14] * scale; + out[15] = a[15] + b[15] * scale; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyMat4} a The first matrix. + * @param {ReadonlyMat4} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function exactEquals$5(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {ReadonlyMat4} a The first matrix. + * @param {ReadonlyMat4} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + + function equals$5(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var a4 = a[4], + a5 = a[5], + a6 = a[6], + a7 = a[7]; + var a8 = a[8], + a9 = a[9], + a10 = a[10], + a11 = a[11]; + var a12 = a[12], + a13 = a[13], + a14 = a[14], + a15 = a[15]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + var b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7]; + var b8 = b[8], + b9 = b[9], + b10 = b[10], + b11 = b[11]; + var b12 = b[12], + b13 = b[13], + b14 = b[14], + b15 = b[15]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15)); + } + /** + * Alias for {@link mat4.multiply} + * @function + */ + + var mul$5 = multiply$5; + /** + * Alias for {@link mat4.subtract} + * @function + */ + + var sub$3 = subtract$3; + + var mat4 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$5, + clone: clone$5, + copy: copy$5, + fromValues: fromValues$5, + set: set$5, + identity: identity$2, + transpose: transpose, + invert: invert$2, + adjoint: adjoint, + determinant: determinant, + multiply: multiply$5, + translate: translate$1, + scale: scale$5, + rotate: rotate$1, + rotateX: rotateX$3, + rotateY: rotateY$3, + rotateZ: rotateZ$3, + fromTranslation: fromTranslation$1, + fromScaling: fromScaling, + fromRotation: fromRotation$1, + fromXRotation: fromXRotation, + fromYRotation: fromYRotation, + fromZRotation: fromZRotation, + fromRotationTranslation: fromRotationTranslation$1, + fromQuat2: fromQuat2, + getTranslation: getTranslation$1, + getScaling: getScaling, + getRotation: getRotation, + decompose: decompose, + fromRotationTranslationScale: fromRotationTranslationScale, + fromRotationTranslationScaleOrigin: fromRotationTranslationScaleOrigin, + fromQuat: fromQuat, + frustum: frustum, + perspectiveNO: perspectiveNO, + perspective: perspective, + perspectiveZO: perspectiveZO, + perspectiveFromFieldOfView: perspectiveFromFieldOfView, + orthoNO: orthoNO, + ortho: ortho, + orthoZO: orthoZO, + lookAt: lookAt, + targetTo: targetTo, + str: str$5, + frob: frob, + add: add$5, + subtract: subtract$3, + multiplyScalar: multiplyScalar, + multiplyScalarAndAdd: multiplyScalarAndAdd, + exactEquals: exactEquals$5, + equals: equals$5, + mul: mul$5, + sub: sub$3 + }); + + /** + * 3 Dimensional Vector + * @module vec3 + */ + + /** + * Creates a new, empty vec3 + * + * @returns {vec3} a new 3D vector + */ + + function create$4() { + var out = new ARRAY_TYPE(3); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + return out; + } + /** + * Creates a new vec3 initialized with values from an existing vector + * + * @param {ReadonlyVec3} a vector to clone + * @returns {vec3} a new 3D vector + */ + + function clone$4(a) { + var out = new ARRAY_TYPE(3); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + return out; + } + /** + * Calculates the length of a vec3 + * + * @param {ReadonlyVec3} a vector to calculate length of + * @returns {Number} length of a + */ + + function length$4(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + return Math.hypot(x, y, z); + } + /** + * Creates a new vec3 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} a new 3D vector + */ + + function fromValues$4(x, y, z) { + var out = new ARRAY_TYPE(3); + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Copy the values from one vec3 to another + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the source vector + * @returns {vec3} out + */ + + function copy$4(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + return out; + } + /** + * Set the components of a vec3 to the given values + * + * @param {vec3} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} out + */ + + function set$4(out, x, y, z) { + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Adds two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function add$4(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function subtract$2(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + return out; + } + /** + * Multiplies two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function multiply$4(out, a, b) { + out[0] = a[0] * b[0]; + out[1] = a[1] * b[1]; + out[2] = a[2] * b[2]; + return out; + } + /** + * Divides two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function divide$2(out, a, b) { + out[0] = a[0] / b[0]; + out[1] = a[1] / b[1]; + out[2] = a[2] / b[2]; + return out; + } + /** + * Math.ceil the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to ceil + * @returns {vec3} out + */ + + function ceil$2(out, a) { + out[0] = Math.ceil(a[0]); + out[1] = Math.ceil(a[1]); + out[2] = Math.ceil(a[2]); + return out; + } + /** + * Math.floor the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to floor + * @returns {vec3} out + */ + + function floor$2(out, a) { + out[0] = Math.floor(a[0]); + out[1] = Math.floor(a[1]); + out[2] = Math.floor(a[2]); + return out; + } + /** + * Returns the minimum of two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function min$2(out, a, b) { + out[0] = Math.min(a[0], b[0]); + out[1] = Math.min(a[1], b[1]); + out[2] = Math.min(a[2], b[2]); + return out; + } + /** + * Returns the maximum of two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function max$2(out, a, b) { + out[0] = Math.max(a[0], b[0]); + out[1] = Math.max(a[1], b[1]); + out[2] = Math.max(a[2], b[2]); + return out; + } + /** + * Math.round the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to round + * @returns {vec3} out + */ + + function round$2(out, a) { + out[0] = Math.round(a[0]); + out[1] = Math.round(a[1]); + out[2] = Math.round(a[2]); + return out; + } + /** + * Scales a vec3 by a scalar number + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec3} out + */ + + function scale$4(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + return out; + } + /** + * Adds two vec3's after scaling the second operand by a scalar value + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {Number} scale the amount to scale b by before adding + * @returns {vec3} out + */ + + function scaleAndAdd$2(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + return out; + } + /** + * Calculates the euclidian distance between two vec3's + * + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {Number} distance between a and b + */ + + function distance$2(a, b) { + var x = b[0] - a[0]; + var y = b[1] - a[1]; + var z = b[2] - a[2]; + return Math.hypot(x, y, z); + } + /** + * Calculates the squared euclidian distance between two vec3's + * + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {Number} squared distance between a and b + */ + + function squaredDistance$2(a, b) { + var x = b[0] - a[0]; + var y = b[1] - a[1]; + var z = b[2] - a[2]; + return x * x + y * y + z * z; + } + /** + * Calculates the squared length of a vec3 + * + * @param {ReadonlyVec3} a vector to calculate squared length of + * @returns {Number} squared length of a + */ + + function squaredLength$4(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + return x * x + y * y + z * z; + } + /** + * Negates the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to negate + * @returns {vec3} out + */ + + function negate$2(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + out[2] = -a[2]; + return out; + } + /** + * Returns the inverse of the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to invert + * @returns {vec3} out + */ + + function inverse$2(out, a) { + out[0] = 1.0 / a[0]; + out[1] = 1.0 / a[1]; + out[2] = 1.0 / a[2]; + return out; + } + /** + * Normalize a vec3 + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a vector to normalize + * @returns {vec3} out + */ + + function normalize$4(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var len = x * x + y * y + z * z; + + if (len > 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } + + out[0] = a[0] * len; + out[1] = a[1] * len; + out[2] = a[2] * len; + return out; + } + /** + * Calculates the dot product of two vec3's + * + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot$4(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + /** + * Computes the cross product of two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @returns {vec3} out + */ + + function cross$2(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2]; + var bx = b[0], + by = b[1], + bz = b[2]; + out[0] = ay * bz - az * by; + out[1] = az * bx - ax * bz; + out[2] = ax * by - ay * bx; + return out; + } + /** + * Performs a linear interpolation between two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec3} out + */ + + function lerp$4(out, a, b, t) { + var ax = a[0]; + var ay = a[1]; + var az = a[2]; + out[0] = ax + t * (b[0] - ax); + out[1] = ay + t * (b[1] - ay); + out[2] = az + t * (b[2] - az); + return out; + } + /** + * Performs a spherical linear interpolation between two vec3's + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec3} out + */ + + function slerp$1(out, a, b, t) { + var angle = Math.acos(Math.min(Math.max(dot$4(a, b), -1), 1)); + var sinTotal = Math.sin(angle); + var ratioA = Math.sin((1 - t) * angle) / sinTotal; + var ratioB = Math.sin(t * angle) / sinTotal; + out[0] = ratioA * a[0] + ratioB * b[0]; + out[1] = ratioA * a[1] + ratioB * b[1]; + out[2] = ratioA * a[2] + ratioB * b[2]; + return out; + } + /** + * Performs a hermite interpolation with two control points + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {ReadonlyVec3} c the third operand + * @param {ReadonlyVec3} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec3} out + */ + + function hermite(out, a, b, c, d, t) { + var factorTimes2 = t * t; + var factor1 = factorTimes2 * (2 * t - 3) + 1; + var factor2 = factorTimes2 * (t - 2) + t; + var factor3 = factorTimes2 * (t - 1); + var factor4 = factorTimes2 * (3 - 2 * t); + out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; + out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; + out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; + return out; + } + /** + * Performs a bezier interpolation with two control points + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the first operand + * @param {ReadonlyVec3} b the second operand + * @param {ReadonlyVec3} c the third operand + * @param {ReadonlyVec3} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec3} out + */ + + function bezier(out, a, b, c, d, t) { + var inverseFactor = 1 - t; + var inverseFactorTimesTwo = inverseFactor * inverseFactor; + var factorTimes2 = t * t; + var factor1 = inverseFactorTimesTwo * inverseFactor; + var factor2 = 3 * t * inverseFactorTimesTwo; + var factor3 = 3 * factorTimes2 * inverseFactor; + var factor4 = factorTimes2 * t; + out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; + out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; + out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; + return out; + } + /** + * Generates a random vector with the given scale + * + * @param {vec3} out the receiving vector + * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned + * @returns {vec3} out + */ + + function random$3(out, scale) { + scale = scale === undefined ? 1.0 : scale; + var r = RANDOM() * 2.0 * Math.PI; + var z = RANDOM() * 2.0 - 1.0; + var zScale = Math.sqrt(1.0 - z * z) * scale; + out[0] = Math.cos(r) * zScale; + out[1] = Math.sin(r) * zScale; + out[2] = z * scale; + return out; + } + /** + * Transforms the vec3 with a mat4. + * 4th vector component is implicitly '1' + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with + * @returns {vec3} out + */ + + function transformMat4$2(out, a, m) { + var x = a[0], + y = a[1], + z = a[2]; + var w = m[3] * x + m[7] * y + m[11] * z + m[15]; + w = w || 1.0; + out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w; + out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w; + out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w; + return out; + } + /** + * Transforms the vec3 with a mat3. + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyMat3} m the 3x3 matrix to transform with + * @returns {vec3} out + */ + + function transformMat3$1(out, a, m) { + var x = a[0], + y = a[1], + z = a[2]; + out[0] = x * m[0] + y * m[3] + z * m[6]; + out[1] = x * m[1] + y * m[4] + z * m[7]; + out[2] = x * m[2] + y * m[5] + z * m[8]; + return out; + } + /** + * Transforms the vec3 with a quat + * Can also be used for dual quaternions. (Multiply it with the real part) + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec3} a the vector to transform + * @param {ReadonlyQuat} q quaternion to transform with + * @returns {vec3} out + */ + + function transformQuat$1(out, a, q) { + // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3]; + var x = a[0], + y = a[1], + z = a[2]; // var qvec = [qx, qy, qz]; + // var uv = vec3.cross([], qvec, a); + + var uvx = qy * z - qz * y, + uvy = qz * x - qx * z, + uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv); + + var uuvx = qy * uvz - qz * uvy, + uuvy = qz * uvx - qx * uvz, + uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w); + + var w2 = qw * 2; + uvx *= w2; + uvy *= w2; + uvz *= w2; // vec3.scale(uuv, uuv, 2); + + uuvx *= 2; + uuvy *= 2; + uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv)); + + out[0] = x + uvx + uuvx; + out[1] = y + uvy + uuvy; + out[2] = z + uvz + uuvz; + return out; + } + /** + * Rotate a 3D vector around the x-axis + * @param {vec3} out The receiving vec3 + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians + * @returns {vec3} out + */ + + function rotateX$2(out, a, b, rad) { + var p = [], + r = []; //Translate point to the origin + + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; //perform rotation + + r[0] = p[0]; + r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad); + r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad); //translate to correct position + + out[0] = r[0] + b[0]; + out[1] = r[1] + b[1]; + out[2] = r[2] + b[2]; + return out; + } + /** + * Rotate a 3D vector around the y-axis + * @param {vec3} out The receiving vec3 + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians + * @returns {vec3} out + */ + + function rotateY$2(out, a, b, rad) { + var p = [], + r = []; //Translate point to the origin + + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; //perform rotation + + r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad); + r[1] = p[1]; + r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad); //translate to correct position + + out[0] = r[0] + b[0]; + out[1] = r[1] + b[1]; + out[2] = r[2] + b[2]; + return out; + } + /** + * Rotate a 3D vector around the z-axis + * @param {vec3} out The receiving vec3 + * @param {ReadonlyVec3} a The vec3 point to rotate + * @param {ReadonlyVec3} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians + * @returns {vec3} out + */ + + function rotateZ$2(out, a, b, rad) { + var p = [], + r = []; //Translate point to the origin + + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; //perform rotation + + r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad); + r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad); + r[2] = p[2]; //translate to correct position + + out[0] = r[0] + b[0]; + out[1] = r[1] + b[1]; + out[2] = r[2] + b[2]; + return out; + } + /** + * Get the angle between two 3D vectors + * @param {ReadonlyVec3} a The first operand + * @param {ReadonlyVec3} b The second operand + * @returns {Number} The angle in radians + */ + + function angle$1(a, b) { + var ax = a[0], + ay = a[1], + az = a[2], + bx = b[0], + by = b[1], + bz = b[2], + mag = Math.sqrt((ax * ax + ay * ay + az * az) * (bx * bx + by * by + bz * bz)), + cosine = mag && dot$4(a, b) / mag; + return Math.acos(Math.min(Math.max(cosine, -1), 1)); + } + /** + * Set the components of a vec3 to zero + * + * @param {vec3} out the receiving vector + * @returns {vec3} out + */ + + function zero$2(out) { + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + return out; + } + /** + * Returns a string representation of a vector + * + * @param {ReadonlyVec3} a vector to represent as a string + * @returns {String} string representation of the vector + */ + + function str$4(a) { + return "vec3(" + a[0] + ", " + a[1] + ", " + a[2] + ")"; + } + /** + * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyVec3} a The first vector. + * @param {ReadonlyVec3} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function exactEquals$4(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2]; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {ReadonlyVec3} a The first vector. + * @param {ReadonlyVec3} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function equals$4(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2]; + var b0 = b[0], + b1 = b[1], + b2 = b[2]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)); + } + /** + * Alias for {@link vec3.subtract} + * @function + */ + + var sub$2 = subtract$2; + /** + * Alias for {@link vec3.multiply} + * @function + */ + + var mul$4 = multiply$4; + /** + * Alias for {@link vec3.divide} + * @function + */ + + var div$2 = divide$2; + /** + * Alias for {@link vec3.distance} + * @function + */ + + var dist$2 = distance$2; + /** + * Alias for {@link vec3.squaredDistance} + * @function + */ + + var sqrDist$2 = squaredDistance$2; + /** + * Alias for {@link vec3.length} + * @function + */ + + var len$4 = length$4; + /** + * Alias for {@link vec3.squaredLength} + * @function + */ + + var sqrLen$4 = squaredLength$4; + /** + * Perform some operation over an array of vec3s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach$2 = function () { + var vec = create$4(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 3; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + } + + return a; + }; + }(); + + var vec3 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$4, + clone: clone$4, + length: length$4, + fromValues: fromValues$4, + copy: copy$4, + set: set$4, + add: add$4, + subtract: subtract$2, + multiply: multiply$4, + divide: divide$2, + ceil: ceil$2, + floor: floor$2, + min: min$2, + max: max$2, + round: round$2, + scale: scale$4, + scaleAndAdd: scaleAndAdd$2, + distance: distance$2, + squaredDistance: squaredDistance$2, + squaredLength: squaredLength$4, + negate: negate$2, + inverse: inverse$2, + normalize: normalize$4, + dot: dot$4, + cross: cross$2, + lerp: lerp$4, + slerp: slerp$1, + hermite: hermite, + bezier: bezier, + random: random$3, + transformMat4: transformMat4$2, + transformMat3: transformMat3$1, + transformQuat: transformQuat$1, + rotateX: rotateX$2, + rotateY: rotateY$2, + rotateZ: rotateZ$2, + angle: angle$1, + zero: zero$2, + str: str$4, + exactEquals: exactEquals$4, + equals: equals$4, + sub: sub$2, + mul: mul$4, + div: div$2, + dist: dist$2, + sqrDist: sqrDist$2, + len: len$4, + sqrLen: sqrLen$4, + forEach: forEach$2 + }); + + /** + * 4 Dimensional Vector + * @module vec4 + */ + + /** + * Creates a new, empty vec4 + * + * @returns {vec4} a new 4D vector + */ + + function create$3() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 0; + } + + return out; + } + /** + * Creates a new vec4 initialized with values from an existing vector + * + * @param {ReadonlyVec4} a vector to clone + * @returns {vec4} a new 4D vector + */ + + function clone$3(a) { + var out = new ARRAY_TYPE(4); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Creates a new vec4 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} a new 4D vector + */ + + function fromValues$3(x, y, z, w) { + var out = new ARRAY_TYPE(4); + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Copy the values from one vec4 to another + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the source vector + * @returns {vec4} out + */ + + function copy$3(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Set the components of a vec4 to the given values + * + * @param {vec4} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} out + */ + + function set$3(out, x, y, z, w) { + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Adds two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function add$3(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function subtract$1(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + return out; + } + /** + * Multiplies two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function multiply$3(out, a, b) { + out[0] = a[0] * b[0]; + out[1] = a[1] * b[1]; + out[2] = a[2] * b[2]; + out[3] = a[3] * b[3]; + return out; + } + /** + * Divides two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function divide$1(out, a, b) { + out[0] = a[0] / b[0]; + out[1] = a[1] / b[1]; + out[2] = a[2] / b[2]; + out[3] = a[3] / b[3]; + return out; + } + /** + * Math.ceil the components of a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to ceil + * @returns {vec4} out + */ + + function ceil$1(out, a) { + out[0] = Math.ceil(a[0]); + out[1] = Math.ceil(a[1]); + out[2] = Math.ceil(a[2]); + out[3] = Math.ceil(a[3]); + return out; + } + /** + * Math.floor the components of a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to floor + * @returns {vec4} out + */ + + function floor$1(out, a) { + out[0] = Math.floor(a[0]); + out[1] = Math.floor(a[1]); + out[2] = Math.floor(a[2]); + out[3] = Math.floor(a[3]); + return out; + } + /** + * Returns the minimum of two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function min$1(out, a, b) { + out[0] = Math.min(a[0], b[0]); + out[1] = Math.min(a[1], b[1]); + out[2] = Math.min(a[2], b[2]); + out[3] = Math.min(a[3], b[3]); + return out; + } + /** + * Returns the maximum of two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {vec4} out + */ + + function max$1(out, a, b) { + out[0] = Math.max(a[0], b[0]); + out[1] = Math.max(a[1], b[1]); + out[2] = Math.max(a[2], b[2]); + out[3] = Math.max(a[3], b[3]); + return out; + } + /** + * Math.round the components of a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to round + * @returns {vec4} out + */ + + function round$1(out, a) { + out[0] = Math.round(a[0]); + out[1] = Math.round(a[1]); + out[2] = Math.round(a[2]); + out[3] = Math.round(a[3]); + return out; + } + /** + * Scales a vec4 by a scalar number + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec4} out + */ + + function scale$3(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + return out; + } + /** + * Adds two vec4's after scaling the second operand by a scalar value + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @param {Number} scale the amount to scale b by before adding + * @returns {vec4} out + */ + + function scaleAndAdd$1(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + return out; + } + /** + * Calculates the euclidian distance between two vec4's + * + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {Number} distance between a and b + */ + + function distance$1(a, b) { + var x = b[0] - a[0]; + var y = b[1] - a[1]; + var z = b[2] - a[2]; + var w = b[3] - a[3]; + return Math.hypot(x, y, z, w); + } + /** + * Calculates the squared euclidian distance between two vec4's + * + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {Number} squared distance between a and b + */ + + function squaredDistance$1(a, b) { + var x = b[0] - a[0]; + var y = b[1] - a[1]; + var z = b[2] - a[2]; + var w = b[3] - a[3]; + return x * x + y * y + z * z + w * w; + } + /** + * Calculates the length of a vec4 + * + * @param {ReadonlyVec4} a vector to calculate length of + * @returns {Number} length of a + */ + + function length$3(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var w = a[3]; + return Math.hypot(x, y, z, w); + } + /** + * Calculates the squared length of a vec4 + * + * @param {ReadonlyVec4} a vector to calculate squared length of + * @returns {Number} squared length of a + */ + + function squaredLength$3(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var w = a[3]; + return x * x + y * y + z * z + w * w; + } + /** + * Negates the components of a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to negate + * @returns {vec4} out + */ + + function negate$1(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + out[2] = -a[2]; + out[3] = -a[3]; + return out; + } + /** + * Returns the inverse of the components of a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to invert + * @returns {vec4} out + */ + + function inverse$1(out, a) { + out[0] = 1.0 / a[0]; + out[1] = 1.0 / a[1]; + out[2] = 1.0 / a[2]; + out[3] = 1.0 / a[3]; + return out; + } + /** + * Normalize a vec4 + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a vector to normalize + * @returns {vec4} out + */ + + function normalize$3(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var w = a[3]; + var len = x * x + y * y + z * z + w * w; + + if (len > 0) { + len = 1 / Math.sqrt(len); + } + + out[0] = x * len; + out[1] = y * len; + out[2] = z * len; + out[3] = w * len; + return out; + } + /** + * Calculates the dot product of two vec4's + * + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot$3(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; + } + /** + * Returns the cross-product of three vectors in a 4-dimensional space + * + * @param {ReadonlyVec4} result the receiving vector + * @param {ReadonlyVec4} U the first vector + * @param {ReadonlyVec4} V the second vector + * @param {ReadonlyVec4} W the third vector + * @returns {vec4} result + */ + + function cross$1(out, u, v, w) { + var A = v[0] * w[1] - v[1] * w[0], + B = v[0] * w[2] - v[2] * w[0], + C = v[0] * w[3] - v[3] * w[0], + D = v[1] * w[2] - v[2] * w[1], + E = v[1] * w[3] - v[3] * w[1], + F = v[2] * w[3] - v[3] * w[2]; + var G = u[0]; + var H = u[1]; + var I = u[2]; + var J = u[3]; + out[0] = H * F - I * E + J * D; + out[1] = -(G * F) + I * C - J * B; + out[2] = G * E - H * C + J * A; + out[3] = -(G * D) + H * B - I * A; + return out; + } + /** + * Performs a linear interpolation between two vec4's + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the first operand + * @param {ReadonlyVec4} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec4} out + */ + + function lerp$3(out, a, b, t) { + var ax = a[0]; + var ay = a[1]; + var az = a[2]; + var aw = a[3]; + out[0] = ax + t * (b[0] - ax); + out[1] = ay + t * (b[1] - ay); + out[2] = az + t * (b[2] - az); + out[3] = aw + t * (b[3] - aw); + return out; + } + /** + * Generates a random vector with the given scale + * + * @param {vec4} out the receiving vector + * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned + * @returns {vec4} out + */ + + function random$2(out, scale) { + scale = scale === undefined ? 1.0 : scale; // Marsaglia, George. Choosing a Point from the Surface of a + // Sphere. Ann. Math. Statist. 43 (1972), no. 2, 645--646. + // http://projecteuclid.org/euclid.aoms/1177692644; + + var v1, v2, v3, v4; + var s1, s2; + + do { + v1 = RANDOM() * 2 - 1; + v2 = RANDOM() * 2 - 1; + s1 = v1 * v1 + v2 * v2; + } while (s1 >= 1); + + do { + v3 = RANDOM() * 2 - 1; + v4 = RANDOM() * 2 - 1; + s2 = v3 * v3 + v4 * v4; + } while (s2 >= 1); + + var d = Math.sqrt((1 - s1) / s2); + out[0] = scale * v1; + out[1] = scale * v2; + out[2] = scale * v3 * d; + out[3] = scale * v4 * d; + return out; + } + /** + * Transforms the vec4 with a mat4. + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with + * @returns {vec4} out + */ + + function transformMat4$1(out, a, m) { + var x = a[0], + y = a[1], + z = a[2], + w = a[3]; + out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; + out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; + out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; + out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; + return out; + } + /** + * Transforms the vec4 with a quat + * + * @param {vec4} out the receiving vector + * @param {ReadonlyVec4} a the vector to transform + * @param {ReadonlyQuat} q quaternion to transform with + * @returns {vec4} out + */ + + function transformQuat(out, a, q) { + var x = a[0], + y = a[1], + z = a[2]; + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3]; // calculate quat * vec + + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + + out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; + out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; + out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; + out[3] = a[3]; + return out; + } + /** + * Set the components of a vec4 to zero + * + * @param {vec4} out the receiving vector + * @returns {vec4} out + */ + + function zero$1(out) { + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + return out; + } + /** + * Returns a string representation of a vector + * + * @param {ReadonlyVec4} a vector to represent as a string + * @returns {String} string representation of the vector + */ + + function str$3(a) { + return "vec4(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; + } + /** + * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function exactEquals$3(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {ReadonlyVec4} a The first vector. + * @param {ReadonlyVec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function equals$3(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)); + } + /** + * Alias for {@link vec4.subtract} + * @function + */ + + var sub$1 = subtract$1; + /** + * Alias for {@link vec4.multiply} + * @function + */ + + var mul$3 = multiply$3; + /** + * Alias for {@link vec4.divide} + * @function + */ + + var div$1 = divide$1; + /** + * Alias for {@link vec4.distance} + * @function + */ + + var dist$1 = distance$1; + /** + * Alias for {@link vec4.squaredDistance} + * @function + */ + + var sqrDist$1 = squaredDistance$1; + /** + * Alias for {@link vec4.length} + * @function + */ + + var len$3 = length$3; + /** + * Alias for {@link vec4.squaredLength} + * @function + */ + + var sqrLen$3 = squaredLength$3; + /** + * Perform some operation over an array of vec4s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach$1 = function () { + var vec = create$3(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 4; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + vec[3] = a[i + 3]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + a[i + 3] = vec[3]; + } + + return a; + }; + }(); + + var vec4 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$3, + clone: clone$3, + fromValues: fromValues$3, + copy: copy$3, + set: set$3, + add: add$3, + subtract: subtract$1, + multiply: multiply$3, + divide: divide$1, + ceil: ceil$1, + floor: floor$1, + min: min$1, + max: max$1, + round: round$1, + scale: scale$3, + scaleAndAdd: scaleAndAdd$1, + distance: distance$1, + squaredDistance: squaredDistance$1, + length: length$3, + squaredLength: squaredLength$3, + negate: negate$1, + inverse: inverse$1, + normalize: normalize$3, + dot: dot$3, + cross: cross$1, + lerp: lerp$3, + random: random$2, + transformMat4: transformMat4$1, + transformQuat: transformQuat, + zero: zero$1, + str: str$3, + exactEquals: exactEquals$3, + equals: equals$3, + sub: sub$1, + mul: mul$3, + div: div$1, + dist: dist$1, + sqrDist: sqrDist$1, + len: len$3, + sqrLen: sqrLen$3, + forEach: forEach$1 + }); + + /** + * Quaternion in the format XYZW + * @module quat + */ + + /** + * Creates a new identity quat + * + * @returns {quat} a new quaternion + */ + + function create$2() { + var out = new ARRAY_TYPE(4); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } + + out[3] = 1; + return out; + } + /** + * Set a quat to the identity quaternion + * + * @param {quat} out the receiving quaternion + * @returns {quat} out + */ + + function identity$1(out) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } + /** + * Sets a quat from the given angle and rotation axis, + * then returns it. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyVec3} axis the axis around which to rotate + * @param {Number} rad the angle in radians + * @returns {quat} out + **/ + + function setAxisAngle(out, axis, rad) { + rad = rad * 0.5; + var s = Math.sin(rad); + out[0] = s * axis[0]; + out[1] = s * axis[1]; + out[2] = s * axis[2]; + out[3] = Math.cos(rad); + return out; + } + /** + * Gets the rotation axis and angle for a given + * quaternion. If a quaternion is created with + * setAxisAngle, this method will return the same + * values as providied in the original parameter list + * OR functionally equivalent values. + * Example: The quaternion formed by axis [0, 0, 1] and + * angle -90 is the same as the quaternion formed by + * [0, 0, 1] and 270. This method favors the latter. + * @param {vec3} out_axis Vector receiving the axis of rotation + * @param {ReadonlyQuat} q Quaternion to be decomposed + * @return {Number} Angle, in radians, of the rotation + */ + + function getAxisAngle(out_axis, q) { + var rad = Math.acos(q[3]) * 2.0; + var s = Math.sin(rad / 2.0); + + if (s > EPSILON) { + out_axis[0] = q[0] / s; + out_axis[1] = q[1] / s; + out_axis[2] = q[2] / s; + } else { + // If s is zero, return any axis (no rotation - axis does not matter) + out_axis[0] = 1; + out_axis[1] = 0; + out_axis[2] = 0; + } + + return rad; + } + /** + * Gets the angular distance between two unit quaternions + * + * @param {ReadonlyQuat} a Origin unit quaternion + * @param {ReadonlyQuat} b Destination unit quaternion + * @return {Number} Angle, in radians, between the two quaternions + */ + + function getAngle(a, b) { + var dotproduct = dot$2(a, b); + return Math.acos(2 * dotproduct * dotproduct - 1); + } + /** + * Multiplies two quat's + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @returns {quat} out + */ + + function multiply$2(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + out[0] = ax * bw + aw * bx + ay * bz - az * by; + out[1] = ay * bw + aw * by + az * bx - ax * bz; + out[2] = az * bw + aw * bz + ax * by - ay * bx; + out[3] = aw * bw - ax * bx - ay * by - az * bz; + return out; + } + /** + * Rotates a quaternion by the given angle about the X axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateX$1(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw + aw * bx; + out[1] = ay * bw + az * bx; + out[2] = az * bw - ay * bx; + out[3] = aw * bw - ax * bx; + return out; + } + /** + * Rotates a quaternion by the given angle about the Y axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateY$1(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var by = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw - az * by; + out[1] = ay * bw + aw * by; + out[2] = az * bw + ax * by; + out[3] = aw * bw - ay * by; + return out; + } + /** + * Rotates a quaternion by the given angle about the Z axis + * + * @param {quat} out quat receiving operation result + * @param {ReadonlyQuat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ + + function rotateZ$1(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bz = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw + ay * bz; + out[1] = ay * bw - ax * bz; + out[2] = az * bw + aw * bz; + out[3] = aw * bw - az * bz; + return out; + } + /** + * Calculates the W component of a quat from the X, Y, and Z components. + * Assumes that quaternion is 1 unit in length. + * Any existing W component will be ignored. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate W component of + * @returns {quat} out + */ + + function calculateW(out, a) { + var x = a[0], + y = a[1], + z = a[2]; + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z)); + return out; + } + /** + * Calculate the exponential of a unit quaternion. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate the exponential of + * @returns {quat} out + */ + + function exp(out, a) { + var x = a[0], + y = a[1], + z = a[2], + w = a[3]; + var r = Math.sqrt(x * x + y * y + z * z); + var et = Math.exp(w); + var s = r > 0 ? et * Math.sin(r) / r : 0; + out[0] = x * s; + out[1] = y * s; + out[2] = z * s; + out[3] = et * Math.cos(r); + return out; + } + /** + * Calculate the natural logarithm of a unit quaternion. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate the exponential of + * @returns {quat} out + */ + + function ln(out, a) { + var x = a[0], + y = a[1], + z = a[2], + w = a[3]; + var r = Math.sqrt(x * x + y * y + z * z); + var t = r > 0 ? Math.atan2(r, w) / r : 0; + out[0] = x * t; + out[1] = y * t; + out[2] = z * t; + out[3] = 0.5 * Math.log(x * x + y * y + z * z + w * w); + return out; + } + /** + * Calculate the scalar power of a unit quaternion. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate the exponential of + * @param {Number} b amount to scale the quaternion by + * @returns {quat} out + */ + + function pow(out, a, b) { + ln(out, a); + scale$2(out, out, b); + exp(out, out); + return out; + } + /** + * Performs a spherical linear interpolation between two quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + function slerp(out, a, b, t) { + // benchmarks: + // http://jsperf.com/quaternion-slerp-implementations + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + var omega, cosom, sinom, scale0, scale1; // calc cosine + + cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) + + if (cosom < 0.0) { + cosom = -cosom; + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + } // calculate coefficients + + + if (1.0 - cosom > EPSILON) { + // standard case (slerp) + omega = Math.acos(cosom); + sinom = Math.sin(omega); + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } else { + // "from" and "to" quaternions are very close + // ... so we can do a linear interpolation + scale0 = 1.0 - t; + scale1 = t; + } // calculate final values + + + out[0] = scale0 * ax + scale1 * bx; + out[1] = scale0 * ay + scale1 * by; + out[2] = scale0 * az + scale1 * bz; + out[3] = scale0 * aw + scale1 * bw; + return out; + } + /** + * Generates a random unit quaternion + * + * @param {quat} out the receiving quaternion + * @returns {quat} out + */ + + function random$1(out) { + // Implementation of http://planning.cs.uiuc.edu/node198.html + // TODO: Calling random 3 times is probably not the fastest solution + var u1 = RANDOM(); + var u2 = RANDOM(); + var u3 = RANDOM(); + var sqrt1MinusU1 = Math.sqrt(1 - u1); + var sqrtU1 = Math.sqrt(u1); + out[0] = sqrt1MinusU1 * Math.sin(2.0 * Math.PI * u2); + out[1] = sqrt1MinusU1 * Math.cos(2.0 * Math.PI * u2); + out[2] = sqrtU1 * Math.sin(2.0 * Math.PI * u3); + out[3] = sqrtU1 * Math.cos(2.0 * Math.PI * u3); + return out; + } + /** + * Calculates the inverse of a quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate inverse of + * @returns {quat} out + */ + + function invert$1(out, a) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3; + var invDot = dot ? 1.0 / dot : 0; // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0 + + out[0] = -a0 * invDot; + out[1] = -a1 * invDot; + out[2] = -a2 * invDot; + out[3] = a3 * invDot; + return out; + } + /** + * Calculates the conjugate of a quat + * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quat to calculate conjugate of + * @returns {quat} out + */ + + function conjugate$1(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + out[2] = -a[2]; + out[3] = a[3]; + return out; + } + /** + * Creates a quaternion from the given 3x3 rotation matrix. + * + * NOTE: The resultant quaternion is not normalized, so you should be sure + * to renormalize the quaternion yourself where necessary. + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyMat3} m rotation matrix + * @returns {quat} out + * @function + */ + + function fromMat3(out, m) { + // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes + // article "Quaternion Calculus and Fast Animation". + var fTrace = m[0] + m[4] + m[8]; + var fRoot; + + if (fTrace > 0.0) { + // |w| > 1/2, may as well choose w > 1/2 + fRoot = Math.sqrt(fTrace + 1.0); // 2w + + out[3] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; // 1/(4w) + + out[0] = (m[5] - m[7]) * fRoot; + out[1] = (m[6] - m[2]) * fRoot; + out[2] = (m[1] - m[3]) * fRoot; + } else { + // |w| <= 1/2 + var i = 0; + if (m[4] > m[0]) i = 1; + if (m[8] > m[i * 3 + i]) i = 2; + var j = (i + 1) % 3; + var k = (i + 2) % 3; + fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0); + out[i] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; + out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot; + out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot; + out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot; + } + + return out; + } + /** + * Creates a quaternion from the given euler angle x, y, z using the provided intrinsic order for the conversion. + * + * @param {quat} out the receiving quaternion + * @param {x} x Angle to rotate around X axis in degrees. + * @param {y} y Angle to rotate around Y axis in degrees. + * @param {z} z Angle to rotate around Z axis in degrees. + * @param {'zyx'|'xyz'|'yxz'|'yzx'|'zxy'|'zyx'} order Intrinsic order for conversion, default is zyx. + * @returns {quat} out + * @function + */ + + function fromEuler(out, x, y, z) { + var order = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : ANGLE_ORDER; + var halfToRad = Math.PI / 360; + x *= halfToRad; + z *= halfToRad; + y *= halfToRad; + var sx = Math.sin(x); + var cx = Math.cos(x); + var sy = Math.sin(y); + var cy = Math.cos(y); + var sz = Math.sin(z); + var cz = Math.cos(z); + + switch (order) { + case "xyz": + out[0] = sx * cy * cz + cx * sy * sz; + out[1] = cx * sy * cz - sx * cy * sz; + out[2] = cx * cy * sz + sx * sy * cz; + out[3] = cx * cy * cz - sx * sy * sz; + break; + + case "xzy": + out[0] = sx * cy * cz - cx * sy * sz; + out[1] = cx * sy * cz - sx * cy * sz; + out[2] = cx * cy * sz + sx * sy * cz; + out[3] = cx * cy * cz + sx * sy * sz; + break; + + case "yxz": + out[0] = sx * cy * cz + cx * sy * sz; + out[1] = cx * sy * cz - sx * cy * sz; + out[2] = cx * cy * sz - sx * sy * cz; + out[3] = cx * cy * cz + sx * sy * sz; + break; + + case "yzx": + out[0] = sx * cy * cz + cx * sy * sz; + out[1] = cx * sy * cz + sx * cy * sz; + out[2] = cx * cy * sz - sx * sy * cz; + out[3] = cx * cy * cz - sx * sy * sz; + break; + + case "zxy": + out[0] = sx * cy * cz - cx * sy * sz; + out[1] = cx * sy * cz + sx * cy * sz; + out[2] = cx * cy * sz + sx * sy * cz; + out[3] = cx * cy * cz - sx * sy * sz; + break; + + case "zyx": + out[0] = sx * cy * cz - cx * sy * sz; + out[1] = cx * sy * cz + sx * cy * sz; + out[2] = cx * cy * sz - sx * sy * cz; + out[3] = cx * cy * cz + sx * sy * sz; + break; + + default: + throw new Error('Unknown angle order ' + order); + } + + return out; + } + /** + * Returns a string representation of a quaternion + * + * @param {ReadonlyQuat} a vector to represent as a string + * @returns {String} string representation of the vector + */ + + function str$2(a) { + return "quat(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ")"; + } + /** + * Creates a new quat initialized with values from an existing quaternion + * + * @param {ReadonlyQuat} a quaternion to clone + * @returns {quat} a new quaternion + * @function + */ + + var clone$2 = clone$3; + /** + * Creates a new quat initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} a new quaternion + * @function + */ + + var fromValues$2 = fromValues$3; + /** + * Copy the values from one quat to another + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the source quaternion + * @returns {quat} out + * @function + */ + + var copy$2 = copy$3; + /** + * Set the components of a quat to the given values + * + * @param {quat} out the receiving quaternion + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} out + * @function + */ + + var set$2 = set$3; + /** + * Adds two quat's + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @returns {quat} out + * @function + */ + + var add$2 = add$3; + /** + * Alias for {@link quat.multiply} + * @function + */ + + var mul$2 = multiply$2; + /** + * Scales a quat by a scalar number + * + * @param {quat} out the receiving vector + * @param {ReadonlyQuat} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {quat} out + * @function + */ + + var scale$2 = scale$3; + /** + * Calculates the dot product of two quat's + * + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @returns {Number} dot product of a and b + * @function + */ + + var dot$2 = dot$3; + /** + * Performs a linear interpolation between two quat's + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + * @function + */ + + var lerp$2 = lerp$3; + /** + * Calculates the length of a quat + * + * @param {ReadonlyQuat} a vector to calculate length of + * @returns {Number} length of a + */ + + var length$2 = length$3; + /** + * Alias for {@link quat.length} + * @function + */ + + var len$2 = length$2; + /** + * Calculates the squared length of a quat + * + * @param {ReadonlyQuat} a vector to calculate squared length of + * @returns {Number} squared length of a + * @function + */ + + var squaredLength$2 = squaredLength$3; + /** + * Alias for {@link quat.squaredLength} + * @function + */ + + var sqrLen$2 = squaredLength$2; + /** + * Normalize a quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quaternion to normalize + * @returns {quat} out + * @function + */ + + var normalize$2 = normalize$3; + /** + * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyQuat} a The first quaternion. + * @param {ReadonlyQuat} b The second quaternion. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + var exactEquals$2 = exactEquals$3; + /** + * Returns whether or not the quaternions point approximately to the same direction. + * + * Both quaternions are assumed to be unit length. + * + * @param {ReadonlyQuat} a The first unit quaternion. + * @param {ReadonlyQuat} b The second unit quaternion. + * @returns {Boolean} True if the quaternions are equal, false otherwise. + */ + + function equals$2(a, b) { + return Math.abs(dot$3(a, b)) >= 1 - EPSILON; + } + /** + * Sets a quaternion to represent the shortest rotation from one + * vector to another. + * + * Both vectors are assumed to be unit length. + * + * @param {quat} out the receiving quaternion. + * @param {ReadonlyVec3} a the initial vector + * @param {ReadonlyVec3} b the destination vector + * @returns {quat} out + */ + + var rotationTo = function () { + var tmpvec3 = create$4(); + var xUnitVec3 = fromValues$4(1, 0, 0); + var yUnitVec3 = fromValues$4(0, 1, 0); + return function (out, a, b) { + var dot = dot$4(a, b); + + if (dot < -0.999999) { + cross$2(tmpvec3, xUnitVec3, a); + if (len$4(tmpvec3) < 0.000001) cross$2(tmpvec3, yUnitVec3, a); + normalize$4(tmpvec3, tmpvec3); + setAxisAngle(out, tmpvec3, Math.PI); + return out; + } else if (dot > 0.999999) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } else { + cross$2(tmpvec3, a, b); + out[0] = tmpvec3[0]; + out[1] = tmpvec3[1]; + out[2] = tmpvec3[2]; + out[3] = 1 + dot; + return normalize$2(out, out); + } + }; + }(); + /** + * Performs a spherical linear interpolation with two control points + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a the first operand + * @param {ReadonlyQuat} b the second operand + * @param {ReadonlyQuat} c the third operand + * @param {ReadonlyQuat} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ + + var sqlerp = function () { + var temp1 = create$2(); + var temp2 = create$2(); + return function (out, a, b, c, d, t) { + slerp(temp1, a, d, t); + slerp(temp2, b, c, t); + slerp(out, temp1, temp2, 2 * t * (1 - t)); + return out; + }; + }(); + /** + * Sets the specified quaternion with values corresponding to the given + * axes. Each axis is a vec3 and is expected to be unit length and + * perpendicular to all other specified axes. + * + * @param {ReadonlyVec3} view the vector representing the viewing direction + * @param {ReadonlyVec3} right the vector representing the local "right" direction + * @param {ReadonlyVec3} up the vector representing the local "up" direction + * @returns {quat} out + */ + + var setAxes = function () { + var matr = create$6(); + return function (out, view, right, up) { + matr[0] = right[0]; + matr[3] = right[1]; + matr[6] = right[2]; + matr[1] = up[0]; + matr[4] = up[1]; + matr[7] = up[2]; + matr[2] = -view[0]; + matr[5] = -view[1]; + matr[8] = -view[2]; + return normalize$2(out, fromMat3(out, matr)); + }; + }(); + + var quat = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$2, + identity: identity$1, + setAxisAngle: setAxisAngle, + getAxisAngle: getAxisAngle, + getAngle: getAngle, + multiply: multiply$2, + rotateX: rotateX$1, + rotateY: rotateY$1, + rotateZ: rotateZ$1, + calculateW: calculateW, + exp: exp, + ln: ln, + pow: pow, + slerp: slerp, + random: random$1, + invert: invert$1, + conjugate: conjugate$1, + fromMat3: fromMat3, + fromEuler: fromEuler, + str: str$2, + clone: clone$2, + fromValues: fromValues$2, + copy: copy$2, + set: set$2, + add: add$2, + mul: mul$2, + scale: scale$2, + dot: dot$2, + lerp: lerp$2, + length: length$2, + len: len$2, + squaredLength: squaredLength$2, + sqrLen: sqrLen$2, + normalize: normalize$2, + exactEquals: exactEquals$2, + equals: equals$2, + rotationTo: rotationTo, + sqlerp: sqlerp, + setAxes: setAxes + }); + + /** + * Dual Quaternion
+ * Format: [real, dual]
+ * Quaternion format: XYZW
+ * Make sure to have normalized dual quaternions, otherwise the functions may not work as intended.
+ * @module quat2 + */ + + /** + * Creates a new identity dual quat + * + * @returns {quat2} a new dual quaternion [real -> rotation, dual -> translation] + */ + + function create$1() { + var dq = new ARRAY_TYPE(8); + + if (ARRAY_TYPE != Float32Array) { + dq[0] = 0; + dq[1] = 0; + dq[2] = 0; + dq[4] = 0; + dq[5] = 0; + dq[6] = 0; + dq[7] = 0; + } + + dq[3] = 1; + return dq; + } + /** + * Creates a new quat initialized with values from an existing quaternion + * + * @param {ReadonlyQuat2} a dual quaternion to clone + * @returns {quat2} new dual quaternion + * @function + */ + + function clone$1(a) { + var dq = new ARRAY_TYPE(8); + dq[0] = a[0]; + dq[1] = a[1]; + dq[2] = a[2]; + dq[3] = a[3]; + dq[4] = a[4]; + dq[5] = a[5]; + dq[6] = a[6]; + dq[7] = a[7]; + return dq; + } + /** + * Creates a new dual quat initialized with the given values + * + * @param {Number} x1 X component + * @param {Number} y1 Y component + * @param {Number} z1 Z component + * @param {Number} w1 W component + * @param {Number} x2 X component + * @param {Number} y2 Y component + * @param {Number} z2 Z component + * @param {Number} w2 W component + * @returns {quat2} new dual quaternion + * @function + */ + + function fromValues$1(x1, y1, z1, w1, x2, y2, z2, w2) { + var dq = new ARRAY_TYPE(8); + dq[0] = x1; + dq[1] = y1; + dq[2] = z1; + dq[3] = w1; + dq[4] = x2; + dq[5] = y2; + dq[6] = z2; + dq[7] = w2; + return dq; + } + /** + * Creates a new dual quat from the given values (quat and translation) + * + * @param {Number} x1 X component + * @param {Number} y1 Y component + * @param {Number} z1 Z component + * @param {Number} w1 W component + * @param {Number} x2 X component (translation) + * @param {Number} y2 Y component (translation) + * @param {Number} z2 Z component (translation) + * @returns {quat2} new dual quaternion + * @function + */ + + function fromRotationTranslationValues(x1, y1, z1, w1, x2, y2, z2) { + var dq = new ARRAY_TYPE(8); + dq[0] = x1; + dq[1] = y1; + dq[2] = z1; + dq[3] = w1; + var ax = x2 * 0.5, + ay = y2 * 0.5, + az = z2 * 0.5; + dq[4] = ax * w1 + ay * z1 - az * y1; + dq[5] = ay * w1 + az * x1 - ax * z1; + dq[6] = az * w1 + ax * y1 - ay * x1; + dq[7] = -ax * x1 - ay * y1 - az * z1; + return dq; + } + /** + * Creates a dual quat from a quaternion and a translation + * + * @param {ReadonlyQuat2} dual quaternion receiving operation result + * @param {ReadonlyQuat} q a normalized quaternion + * @param {ReadonlyVec3} t translation vector + * @returns {quat2} dual quaternion receiving operation result + * @function + */ + + function fromRotationTranslation(out, q, t) { + var ax = t[0] * 0.5, + ay = t[1] * 0.5, + az = t[2] * 0.5, + bx = q[0], + by = q[1], + bz = q[2], + bw = q[3]; + out[0] = bx; + out[1] = by; + out[2] = bz; + out[3] = bw; + out[4] = ax * bw + ay * bz - az * by; + out[5] = ay * bw + az * bx - ax * bz; + out[6] = az * bw + ax * by - ay * bx; + out[7] = -ax * bx - ay * by - az * bz; + return out; + } + /** + * Creates a dual quat from a translation + * + * @param {ReadonlyQuat2} dual quaternion receiving operation result + * @param {ReadonlyVec3} t translation vector + * @returns {quat2} dual quaternion receiving operation result + * @function + */ + + function fromTranslation(out, t) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = t[0] * 0.5; + out[5] = t[1] * 0.5; + out[6] = t[2] * 0.5; + out[7] = 0; + return out; + } + /** + * Creates a dual quat from a quaternion + * + * @param {ReadonlyQuat2} dual quaternion receiving operation result + * @param {ReadonlyQuat} q the quaternion + * @returns {quat2} dual quaternion receiving operation result + * @function + */ + + function fromRotation(out, q) { + out[0] = q[0]; + out[1] = q[1]; + out[2] = q[2]; + out[3] = q[3]; + out[4] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + return out; + } + /** + * Creates a new dual quat from a matrix (4x4) + * + * @param {quat2} out the dual quaternion + * @param {ReadonlyMat4} a the matrix + * @returns {quat2} dual quat receiving operation result + * @function + */ + + function fromMat4(out, a) { + //TODO Optimize this + var outer = create$2(); + getRotation(outer, a); + var t = new ARRAY_TYPE(3); + getTranslation$1(t, a); + fromRotationTranslation(out, outer, t); + return out; + } + /** + * Copy the values from one dual quat to another + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the source dual quaternion + * @returns {quat2} out + * @function + */ + + function copy$1(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + return out; + } + /** + * Set a dual quat to the identity dual quaternion + * + * @param {quat2} out the receiving quaternion + * @returns {quat2} out + */ + + function identity(out) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + return out; + } + /** + * Set the components of a dual quat to the given values + * + * @param {quat2} out the receiving quaternion + * @param {Number} x1 X component + * @param {Number} y1 Y component + * @param {Number} z1 Z component + * @param {Number} w1 W component + * @param {Number} x2 X component + * @param {Number} y2 Y component + * @param {Number} z2 Z component + * @param {Number} w2 W component + * @returns {quat2} out + * @function + */ + + function set$1(out, x1, y1, z1, w1, x2, y2, z2, w2) { + out[0] = x1; + out[1] = y1; + out[2] = z1; + out[3] = w1; + out[4] = x2; + out[5] = y2; + out[6] = z2; + out[7] = w2; + return out; + } + /** + * Gets the real part of a dual quat + * @param {quat} out real part + * @param {ReadonlyQuat2} a Dual Quaternion + * @return {quat} real part + */ + + var getReal = copy$2; + /** + * Gets the dual part of a dual quat + * @param {quat} out dual part + * @param {ReadonlyQuat2} a Dual Quaternion + * @return {quat} dual part + */ + + function getDual(out, a) { + out[0] = a[4]; + out[1] = a[5]; + out[2] = a[6]; + out[3] = a[7]; + return out; + } + /** + * Set the real component of a dual quat to the given quaternion + * + * @param {quat2} out the receiving quaternion + * @param {ReadonlyQuat} q a quaternion representing the real part + * @returns {quat2} out + * @function + */ + + var setReal = copy$2; + /** + * Set the dual component of a dual quat to the given quaternion + * + * @param {quat2} out the receiving quaternion + * @param {ReadonlyQuat} q a quaternion representing the dual part + * @returns {quat2} out + * @function + */ + + function setDual(out, q) { + out[4] = q[0]; + out[5] = q[1]; + out[6] = q[2]; + out[7] = q[3]; + return out; + } + /** + * Gets the translation of a normalized dual quat + * @param {vec3} out translation + * @param {ReadonlyQuat2} a Dual Quaternion to be decomposed + * @return {vec3} translation + */ + + function getTranslation(out, a) { + var ax = a[4], + ay = a[5], + az = a[6], + aw = a[7], + bx = -a[0], + by = -a[1], + bz = -a[2], + bw = a[3]; + out[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2; + out[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2; + out[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2; + return out; + } + /** + * Translates a dual quat by the given vector + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to translate + * @param {ReadonlyVec3} v vector to translate by + * @returns {quat2} out + */ + + function translate(out, a, v) { + var ax1 = a[0], + ay1 = a[1], + az1 = a[2], + aw1 = a[3], + bx1 = v[0] * 0.5, + by1 = v[1] * 0.5, + bz1 = v[2] * 0.5, + ax2 = a[4], + ay2 = a[5], + az2 = a[6], + aw2 = a[7]; + out[0] = ax1; + out[1] = ay1; + out[2] = az1; + out[3] = aw1; + out[4] = aw1 * bx1 + ay1 * bz1 - az1 * by1 + ax2; + out[5] = aw1 * by1 + az1 * bx1 - ax1 * bz1 + ay2; + out[6] = aw1 * bz1 + ax1 * by1 - ay1 * bx1 + az2; + out[7] = -ax1 * bx1 - ay1 * by1 - az1 * bz1 + aw2; + return out; + } + /** + * Rotates a dual quat around the X axis + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {number} rad how far should the rotation be + * @returns {quat2} out + */ + + function rotateX(out, a, rad) { + var bx = -a[0], + by = -a[1], + bz = -a[2], + bw = a[3], + ax = a[4], + ay = a[5], + az = a[6], + aw = a[7], + ax1 = ax * bw + aw * bx + ay * bz - az * by, + ay1 = ay * bw + aw * by + az * bx - ax * bz, + az1 = az * bw + aw * bz + ax * by - ay * bx, + aw1 = aw * bw - ax * bx - ay * by - az * bz; + rotateX$1(out, a, rad); + bx = out[0]; + by = out[1]; + bz = out[2]; + bw = out[3]; + out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; + out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; + out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; + out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; + return out; + } + /** + * Rotates a dual quat around the Y axis + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {number} rad how far should the rotation be + * @returns {quat2} out + */ + + function rotateY(out, a, rad) { + var bx = -a[0], + by = -a[1], + bz = -a[2], + bw = a[3], + ax = a[4], + ay = a[5], + az = a[6], + aw = a[7], + ax1 = ax * bw + aw * bx + ay * bz - az * by, + ay1 = ay * bw + aw * by + az * bx - ax * bz, + az1 = az * bw + aw * bz + ax * by - ay * bx, + aw1 = aw * bw - ax * bx - ay * by - az * bz; + rotateY$1(out, a, rad); + bx = out[0]; + by = out[1]; + bz = out[2]; + bw = out[3]; + out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; + out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; + out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; + out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; + return out; + } + /** + * Rotates a dual quat around the Z axis + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {number} rad how far should the rotation be + * @returns {quat2} out + */ + + function rotateZ(out, a, rad) { + var bx = -a[0], + by = -a[1], + bz = -a[2], + bw = a[3], + ax = a[4], + ay = a[5], + az = a[6], + aw = a[7], + ax1 = ax * bw + aw * bx + ay * bz - az * by, + ay1 = ay * bw + aw * by + az * bx - ax * bz, + az1 = az * bw + aw * bz + ax * by - ay * bx, + aw1 = aw * bw - ax * bx - ay * by - az * bz; + rotateZ$1(out, a, rad); + bx = out[0]; + by = out[1]; + bz = out[2]; + bw = out[3]; + out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; + out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; + out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; + out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; + return out; + } + /** + * Rotates a dual quat by a given quaternion (a * q) + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {ReadonlyQuat} q quaternion to rotate by + * @returns {quat2} out + */ + + function rotateByQuatAppend(out, a, q) { + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3], + ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + out[0] = ax * qw + aw * qx + ay * qz - az * qy; + out[1] = ay * qw + aw * qy + az * qx - ax * qz; + out[2] = az * qw + aw * qz + ax * qy - ay * qx; + out[3] = aw * qw - ax * qx - ay * qy - az * qz; + ax = a[4]; + ay = a[5]; + az = a[6]; + aw = a[7]; + out[4] = ax * qw + aw * qx + ay * qz - az * qy; + out[5] = ay * qw + aw * qy + az * qx - ax * qz; + out[6] = az * qw + aw * qz + ax * qy - ay * qx; + out[7] = aw * qw - ax * qx - ay * qy - az * qz; + return out; + } + /** + * Rotates a dual quat by a given quaternion (q * a) + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat} q quaternion to rotate by + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @returns {quat2} out + */ + + function rotateByQuatPrepend(out, q, a) { + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3], + bx = a[0], + by = a[1], + bz = a[2], + bw = a[3]; + out[0] = qx * bw + qw * bx + qy * bz - qz * by; + out[1] = qy * bw + qw * by + qz * bx - qx * bz; + out[2] = qz * bw + qw * bz + qx * by - qy * bx; + out[3] = qw * bw - qx * bx - qy * by - qz * bz; + bx = a[4]; + by = a[5]; + bz = a[6]; + bw = a[7]; + out[4] = qx * bw + qw * bx + qy * bz - qz * by; + out[5] = qy * bw + qw * by + qz * bx - qx * bz; + out[6] = qz * bw + qw * bz + qx * by - qy * bx; + out[7] = qw * bw - qx * bx - qy * by - qz * bz; + return out; + } + /** + * Rotates a dual quat around a given axis. Does the normalisation automatically + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the dual quaternion to rotate + * @param {ReadonlyVec3} axis the axis to rotate around + * @param {Number} rad how far the rotation should be + * @returns {quat2} out + */ + + function rotateAroundAxis(out, a, axis, rad) { + //Special case for rad = 0 + if (Math.abs(rad) < EPSILON) { + return copy$1(out, a); + } + + var axisLength = Math.hypot(axis[0], axis[1], axis[2]); + rad = rad * 0.5; + var s = Math.sin(rad); + var bx = s * axis[0] / axisLength; + var by = s * axis[1] / axisLength; + var bz = s * axis[2] / axisLength; + var bw = Math.cos(rad); + var ax1 = a[0], + ay1 = a[1], + az1 = a[2], + aw1 = a[3]; + out[0] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by; + out[1] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz; + out[2] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx; + out[3] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz; + var ax = a[4], + ay = a[5], + az = a[6], + aw = a[7]; + out[4] = ax * bw + aw * bx + ay * bz - az * by; + out[5] = ay * bw + aw * by + az * bx - ax * bz; + out[6] = az * bw + aw * bz + ax * by - ay * bx; + out[7] = aw * bw - ax * bx - ay * by - az * bz; + return out; + } + /** + * Adds two dual quat's + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand + * @returns {quat2} out + * @function + */ + + function add$1(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; + out[7] = a[7] + b[7]; + return out; + } + /** + * Multiplies two dual quat's + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand + * @returns {quat2} out + */ + + function multiply$1(out, a, b) { + var ax0 = a[0], + ay0 = a[1], + az0 = a[2], + aw0 = a[3], + bx1 = b[4], + by1 = b[5], + bz1 = b[6], + bw1 = b[7], + ax1 = a[4], + ay1 = a[5], + az1 = a[6], + aw1 = a[7], + bx0 = b[0], + by0 = b[1], + bz0 = b[2], + bw0 = b[3]; + out[0] = ax0 * bw0 + aw0 * bx0 + ay0 * bz0 - az0 * by0; + out[1] = ay0 * bw0 + aw0 * by0 + az0 * bx0 - ax0 * bz0; + out[2] = az0 * bw0 + aw0 * bz0 + ax0 * by0 - ay0 * bx0; + out[3] = aw0 * bw0 - ax0 * bx0 - ay0 * by0 - az0 * bz0; + out[4] = ax0 * bw1 + aw0 * bx1 + ay0 * bz1 - az0 * by1 + ax1 * bw0 + aw1 * bx0 + ay1 * bz0 - az1 * by0; + out[5] = ay0 * bw1 + aw0 * by1 + az0 * bx1 - ax0 * bz1 + ay1 * bw0 + aw1 * by0 + az1 * bx0 - ax1 * bz0; + out[6] = az0 * bw1 + aw0 * bz1 + ax0 * by1 - ay0 * bx1 + az1 * bw0 + aw1 * bz0 + ax1 * by0 - ay1 * bx0; + out[7] = aw0 * bw1 - ax0 * bx1 - ay0 * by1 - az0 * bz1 + aw1 * bw0 - ax1 * bx0 - ay1 * by0 - az1 * bz0; + return out; + } + /** + * Alias for {@link quat2.multiply} + * @function + */ + + var mul$1 = multiply$1; + /** + * Scales a dual quat by a scalar number + * + * @param {quat2} out the receiving dual quat + * @param {ReadonlyQuat2} a the dual quat to scale + * @param {Number} b amount to scale the dual quat by + * @returns {quat2} out + * @function + */ + + function scale$1(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + out[4] = a[4] * b; + out[5] = a[5] * b; + out[6] = a[6] * b; + out[7] = a[7] * b; + return out; + } + /** + * Calculates the dot product of two dual quat's (The dot product of the real parts) + * + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand + * @returns {Number} dot product of a and b + * @function + */ + + var dot$1 = dot$2; + /** + * Performs a linear interpolation between two dual quats's + * NOTE: The resulting dual quaternions won't always be normalized (The error is most noticeable when t = 0.5) + * + * @param {quat2} out the receiving dual quat + * @param {ReadonlyQuat2} a the first operand + * @param {ReadonlyQuat2} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat2} out + */ + + function lerp$1(out, a, b, t) { + var mt = 1 - t; + if (dot$1(a, b) < 0) t = -t; + out[0] = a[0] * mt + b[0] * t; + out[1] = a[1] * mt + b[1] * t; + out[2] = a[2] * mt + b[2] * t; + out[3] = a[3] * mt + b[3] * t; + out[4] = a[4] * mt + b[4] * t; + out[5] = a[5] * mt + b[5] * t; + out[6] = a[6] * mt + b[6] * t; + out[7] = a[7] * mt + b[7] * t; + return out; + } + /** + * Calculates the inverse of a dual quat. If they are normalized, conjugate is cheaper + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a dual quat to calculate inverse of + * @returns {quat2} out + */ + + function invert(out, a) { + var sqlen = squaredLength$1(a); + out[0] = -a[0] / sqlen; + out[1] = -a[1] / sqlen; + out[2] = -a[2] / sqlen; + out[3] = a[3] / sqlen; + out[4] = -a[4] / sqlen; + out[5] = -a[5] / sqlen; + out[6] = -a[6] / sqlen; + out[7] = a[7] / sqlen; + return out; + } + /** + * Calculates the conjugate of a dual quat + * If the dual quaternion is normalized, this function is faster than quat2.inverse and produces the same result. + * + * @param {quat2} out the receiving quaternion + * @param {ReadonlyQuat2} a quat to calculate conjugate of + * @returns {quat2} out + */ + + function conjugate(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + out[2] = -a[2]; + out[3] = a[3]; + out[4] = -a[4]; + out[5] = -a[5]; + out[6] = -a[6]; + out[7] = a[7]; + return out; + } + /** + * Calculates the length of a dual quat + * + * @param {ReadonlyQuat2} a dual quat to calculate length of + * @returns {Number} length of a + * @function + */ + + var length$1 = length$2; + /** + * Alias for {@link quat2.length} + * @function + */ + + var len$1 = length$1; + /** + * Calculates the squared length of a dual quat + * + * @param {ReadonlyQuat2} a dual quat to calculate squared length of + * @returns {Number} squared length of a + * @function + */ + + var squaredLength$1 = squaredLength$2; + /** + * Alias for {@link quat2.squaredLength} + * @function + */ + + var sqrLen$1 = squaredLength$1; + /** + * Normalize a dual quat + * + * @param {quat2} out the receiving dual quaternion + * @param {ReadonlyQuat2} a dual quaternion to normalize + * @returns {quat2} out + * @function + */ + + function normalize$1(out, a) { + var magnitude = squaredLength$1(a); + + if (magnitude > 0) { + magnitude = Math.sqrt(magnitude); + var a0 = a[0] / magnitude; + var a1 = a[1] / magnitude; + var a2 = a[2] / magnitude; + var a3 = a[3] / magnitude; + var b0 = a[4]; + var b1 = a[5]; + var b2 = a[6]; + var b3 = a[7]; + var a_dot_b = a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3; + out[0] = a0; + out[1] = a1; + out[2] = a2; + out[3] = a3; + out[4] = (b0 - a0 * a_dot_b) / magnitude; + out[5] = (b1 - a1 * a_dot_b) / magnitude; + out[6] = (b2 - a2 * a_dot_b) / magnitude; + out[7] = (b3 - a3 * a_dot_b) / magnitude; + } + + return out; + } + /** + * Returns a string representation of a dual quaternion + * + * @param {ReadonlyQuat2} a dual quaternion to represent as a string + * @returns {String} string representation of the dual quat + */ + + function str$1(a) { + return "quat2(" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ")"; + } + /** + * Returns whether or not the dual quaternions have exactly the same elements in the same position (when compared with ===) + * + * @param {ReadonlyQuat2} a the first dual quaternion. + * @param {ReadonlyQuat2} b the second dual quaternion. + * @returns {Boolean} true if the dual quaternions are equal, false otherwise. + */ + + function exactEquals$1(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7]; + } + /** + * Returns whether or not the dual quaternions have approximately the same elements in the same position. + * + * @param {ReadonlyQuat2} a the first dual quat. + * @param {ReadonlyQuat2} b the second dual quat. + * @returns {Boolean} true if the dual quats are equal, false otherwise. + */ + + function equals$1(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5], + a6 = a[6], + a7 = a[7]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)); + } + + var quat2 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$1, + clone: clone$1, + fromValues: fromValues$1, + fromRotationTranslationValues: fromRotationTranslationValues, + fromRotationTranslation: fromRotationTranslation, + fromTranslation: fromTranslation, + fromRotation: fromRotation, + fromMat4: fromMat4, + copy: copy$1, + identity: identity, + set: set$1, + getReal: getReal, + getDual: getDual, + setReal: setReal, + setDual: setDual, + getTranslation: getTranslation, + translate: translate, + rotateX: rotateX, + rotateY: rotateY, + rotateZ: rotateZ, + rotateByQuatAppend: rotateByQuatAppend, + rotateByQuatPrepend: rotateByQuatPrepend, + rotateAroundAxis: rotateAroundAxis, + add: add$1, + multiply: multiply$1, + mul: mul$1, + scale: scale$1, + dot: dot$1, + lerp: lerp$1, + invert: invert, + conjugate: conjugate, + length: length$1, + len: len$1, + squaredLength: squaredLength$1, + sqrLen: sqrLen$1, + normalize: normalize$1, + str: str$1, + exactEquals: exactEquals$1, + equals: equals$1 + }); + + /** + * 2 Dimensional Vector + * @module vec2 + */ + + /** + * Creates a new, empty vec2 + * + * @returns {vec2} a new 2D vector + */ + + function create() { + var out = new ARRAY_TYPE(2); + + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + } + + return out; + } + /** + * Creates a new vec2 initialized with values from an existing vector + * + * @param {ReadonlyVec2} a vector to clone + * @returns {vec2} a new 2D vector + */ + + function clone(a) { + var out = new ARRAY_TYPE(2); + out[0] = a[0]; + out[1] = a[1]; + return out; + } + /** + * Creates a new vec2 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @returns {vec2} a new 2D vector + */ + + function fromValues(x, y) { + var out = new ARRAY_TYPE(2); + out[0] = x; + out[1] = y; + return out; + } + /** + * Copy the values from one vec2 to another + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the source vector + * @returns {vec2} out + */ + + function copy(out, a) { + out[0] = a[0]; + out[1] = a[1]; + return out; + } + /** + * Set the components of a vec2 to the given values + * + * @param {vec2} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @returns {vec2} out + */ + + function set(out, x, y) { + out[0] = x; + out[1] = y; + return out; + } + /** + * Adds two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function add(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function subtract(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + return out; + } + /** + * Multiplies two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function multiply(out, a, b) { + out[0] = a[0] * b[0]; + out[1] = a[1] * b[1]; + return out; + } + /** + * Divides two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function divide(out, a, b) { + out[0] = a[0] / b[0]; + out[1] = a[1] / b[1]; + return out; + } + /** + * Math.ceil the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to ceil + * @returns {vec2} out + */ + + function ceil(out, a) { + out[0] = Math.ceil(a[0]); + out[1] = Math.ceil(a[1]); + return out; + } + /** + * Math.floor the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to floor + * @returns {vec2} out + */ + + function floor(out, a) { + out[0] = Math.floor(a[0]); + out[1] = Math.floor(a[1]); + return out; + } + /** + * Returns the minimum of two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function min(out, a, b) { + out[0] = Math.min(a[0], b[0]); + out[1] = Math.min(a[1], b[1]); + return out; + } + /** + * Returns the maximum of two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec2} out + */ + + function max(out, a, b) { + out[0] = Math.max(a[0], b[0]); + out[1] = Math.max(a[1], b[1]); + return out; + } + /** + * Math.round the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to round + * @returns {vec2} out + */ + + function round(out, a) { + out[0] = Math.round(a[0]); + out[1] = Math.round(a[1]); + return out; + } + /** + * Scales a vec2 by a scalar number + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec2} out + */ + + function scale(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + return out; + } + /** + * Adds two vec2's after scaling the second operand by a scalar value + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @param {Number} scale the amount to scale b by before adding + * @returns {vec2} out + */ + + function scaleAndAdd(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + return out; + } + /** + * Calculates the euclidian distance between two vec2's + * + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {Number} distance between a and b + */ + + function distance(a, b) { + var x = b[0] - a[0], + y = b[1] - a[1]; + return Math.hypot(x, y); + } + /** + * Calculates the squared euclidian distance between two vec2's + * + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {Number} squared distance between a and b + */ + + function squaredDistance(a, b) { + var x = b[0] - a[0], + y = b[1] - a[1]; + return x * x + y * y; + } + /** + * Calculates the length of a vec2 + * + * @param {ReadonlyVec2} a vector to calculate length of + * @returns {Number} length of a + */ + + function length(a) { + var x = a[0], + y = a[1]; + return Math.hypot(x, y); + } + /** + * Calculates the squared length of a vec2 + * + * @param {ReadonlyVec2} a vector to calculate squared length of + * @returns {Number} squared length of a + */ + + function squaredLength(a) { + var x = a[0], + y = a[1]; + return x * x + y * y; + } + /** + * Negates the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to negate + * @returns {vec2} out + */ + + function negate(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + return out; + } + /** + * Returns the inverse of the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to invert + * @returns {vec2} out + */ + + function inverse(out, a) { + out[0] = 1.0 / a[0]; + out[1] = 1.0 / a[1]; + return out; + } + /** + * Normalize a vec2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a vector to normalize + * @returns {vec2} out + */ + + function normalize(out, a) { + var x = a[0], + y = a[1]; + var len = x * x + y * y; + + if (len > 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } + + out[0] = a[0] * len; + out[1] = a[1] * len; + return out; + } + /** + * Calculates the dot product of two vec2's + * + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {Number} dot product of a and b + */ + + function dot(a, b) { + return a[0] * b[0] + a[1] * b[1]; + } + /** + * Computes the cross product of two vec2's + * Note that the cross product must by definition produce a 3D vector + * + * @param {vec3} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @returns {vec3} out + */ + + function cross(out, a, b) { + var z = a[0] * b[1] - a[1] * b[0]; + out[0] = out[1] = 0; + out[2] = z; + return out; + } + /** + * Performs a linear interpolation between two vec2's + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the first operand + * @param {ReadonlyVec2} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec2} out + */ + + function lerp(out, a, b, t) { + var ax = a[0], + ay = a[1]; + out[0] = ax + t * (b[0] - ax); + out[1] = ay + t * (b[1] - ay); + return out; + } + /** + * Generates a random vector with the given scale + * + * @param {vec2} out the receiving vector + * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned + * @returns {vec2} out + */ + + function random(out, scale) { + scale = scale === undefined ? 1.0 : scale; + var r = RANDOM() * 2.0 * Math.PI; + out[0] = Math.cos(r) * scale; + out[1] = Math.sin(r) * scale; + return out; + } + /** + * Transforms the vec2 with a mat2 + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat2} m matrix to transform with + * @returns {vec2} out + */ + + function transformMat2(out, a, m) { + var x = a[0], + y = a[1]; + out[0] = m[0] * x + m[2] * y; + out[1] = m[1] * x + m[3] * y; + return out; + } + /** + * Transforms the vec2 with a mat2d + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat2d} m matrix to transform with + * @returns {vec2} out + */ + + function transformMat2d(out, a, m) { + var x = a[0], + y = a[1]; + out[0] = m[0] * x + m[2] * y + m[4]; + out[1] = m[1] * x + m[3] * y + m[5]; + return out; + } + /** + * Transforms the vec2 with a mat3 + * 3rd vector component is implicitly '1' + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat3} m matrix to transform with + * @returns {vec2} out + */ + + function transformMat3(out, a, m) { + var x = a[0], + y = a[1]; + out[0] = m[0] * x + m[3] * y + m[6]; + out[1] = m[1] * x + m[4] * y + m[7]; + return out; + } + /** + * Transforms the vec2 with a mat4 + * 3rd vector component is implicitly '0' + * 4th vector component is implicitly '1' + * + * @param {vec2} out the receiving vector + * @param {ReadonlyVec2} a the vector to transform + * @param {ReadonlyMat4} m matrix to transform with + * @returns {vec2} out + */ + + function transformMat4(out, a, m) { + var x = a[0]; + var y = a[1]; + out[0] = m[0] * x + m[4] * y + m[12]; + out[1] = m[1] * x + m[5] * y + m[13]; + return out; + } + /** + * Rotate a 2D vector + * @param {vec2} out The receiving vec2 + * @param {ReadonlyVec2} a The vec2 point to rotate + * @param {ReadonlyVec2} b The origin of the rotation + * @param {Number} rad The angle of rotation in radians + * @returns {vec2} out + */ + + function rotate(out, a, b, rad) { + //Translate point to the origin + var p0 = a[0] - b[0], + p1 = a[1] - b[1], + sinC = Math.sin(rad), + cosC = Math.cos(rad); //perform rotation and translate to correct position + + out[0] = p0 * cosC - p1 * sinC + b[0]; + out[1] = p0 * sinC + p1 * cosC + b[1]; + return out; + } + /** + * Get the angle between two 2D vectors + * @param {ReadonlyVec2} a The first operand + * @param {ReadonlyVec2} b The second operand + * @returns {Number} The angle in radians + */ + + function angle(a, b) { + var x1 = a[0], + y1 = a[1], + x2 = b[0], + y2 = b[1], + // mag is the product of the magnitudes of a and b + mag = Math.sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2)), + // mag &&.. short circuits if mag == 0 + cosine = mag && (x1 * x2 + y1 * y2) / mag; // Math.min(Math.max(cosine, -1), 1) clamps the cosine between -1 and 1 + + return Math.acos(Math.min(Math.max(cosine, -1), 1)); + } + /** + * Set the components of a vec2 to zero + * + * @param {vec2} out the receiving vector + * @returns {vec2} out + */ + + function zero(out) { + out[0] = 0.0; + out[1] = 0.0; + return out; + } + /** + * Returns a string representation of a vector + * + * @param {ReadonlyVec2} a vector to represent as a string + * @returns {String} string representation of the vector + */ + + function str(a) { + return "vec2(" + a[0] + ", " + a[1] + ")"; + } + /** + * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) + * + * @param {ReadonlyVec2} a The first vector. + * @param {ReadonlyVec2} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function exactEquals(a, b) { + return a[0] === b[0] && a[1] === b[1]; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {ReadonlyVec2} a The first vector. + * @param {ReadonlyVec2} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ + + function equals(a, b) { + var a0 = a[0], + a1 = a[1]; + var b0 = b[0], + b1 = b[1]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)); + } + /** + * Alias for {@link vec2.length} + * @function + */ + + var len = length; + /** + * Alias for {@link vec2.subtract} + * @function + */ + + var sub = subtract; + /** + * Alias for {@link vec2.multiply} + * @function + */ + + var mul = multiply; + /** + * Alias for {@link vec2.divide} + * @function + */ + + var div = divide; + /** + * Alias for {@link vec2.distance} + * @function + */ + + var dist = distance; + /** + * Alias for {@link vec2.squaredDistance} + * @function + */ + + var sqrDist = squaredDistance; + /** + * Alias for {@link vec2.squaredLength} + * @function + */ + + var sqrLen = squaredLength; + /** + * Perform some operation over an array of vec2s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ + + var forEach = function () { + var vec = create(); + return function (a, stride, offset, count, fn, arg) { + var i, l; + + if (!stride) { + stride = 2; + } + + if (!offset) { + offset = 0; + } + + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } + + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + } + + return a; + }; + }(); + + var vec2 = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create, + clone: clone, + fromValues: fromValues, + copy: copy, + set: set, + add: add, + subtract: subtract, + multiply: multiply, + divide: divide, + ceil: ceil, + floor: floor, + min: min, + max: max, + round: round, + scale: scale, + scaleAndAdd: scaleAndAdd, + distance: distance, + squaredDistance: squaredDistance, + length: length, + squaredLength: squaredLength, + negate: negate, + inverse: inverse, + normalize: normalize, + dot: dot, + cross: cross, + lerp: lerp, + random: random, + transformMat2: transformMat2, + transformMat2d: transformMat2d, + transformMat3: transformMat3, + transformMat4: transformMat4, + rotate: rotate, + angle: angle, + zero: zero, + str: str, + exactEquals: exactEquals, + equals: equals, + len: len, + sub: sub, + mul: mul, + div: div, + dist: dist, + sqrDist: sqrDist, + sqrLen: sqrLen, + forEach: forEach + }); + + exports.glMatrix = common; + exports.mat2 = mat2; + exports.mat2d = mat2d; + exports.mat3 = mat3; + exports.mat4 = mat4; + exports.quat = quat; + exports.quat2 = quat2; + exports.vec2 = vec2; + exports.vec3 = vec3; + exports.vec4 = vec4; + + Object.defineProperty(exports, '__esModule', { value: true }); + + })); + \ No newline at end of file diff --git a/Übung_23112023/aufgabe2/common/initShaders.js b/Übung_23112023/aufgabe2/common/initShaders.js new file mode 100644 index 0000000..e972f6a --- /dev/null +++ b/Übung_23112023/aufgabe2/common/initShaders.js @@ -0,0 +1,48 @@ +"use strict" ; + +// +// initShaders.js +// + +function initShaders( gl, vertexShaderId, fragmentShaderId ) +{ + const compileShader = ( gl, gl_shaderType, shaderSource ) => { + // Create the shader + let shader = gl.createShader( gl_shaderType ); + + // Set the shader source code + gl.shaderSource( shader, shaderSource ); + + // Compile the shader to make it readable for the GPU + gl.compileShader( shader ); + var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + + if (!success) { + // Something went wrong during compilation; get the error + throw "could not compile shader:" + gl.getShaderInfoLog(shader); + } + else { + return shader; + } + } + + /* + * Setup shader program + */ + let vShaderSource = document.querySelector( '#' + vertexShaderId ).text; + let fShaderSource = document.querySelector( '#' + fragmentShaderId ).text; + + let vertexShader = compileShader( gl, gl.VERTEX_SHADER, vShaderSource ); + let fragmentShader = compileShader( gl, gl.FRAGMENT_SHADER, fShaderSource ); + + // Build the program + const program = gl.createProgram(); + + // Attach shaders to it + gl.attachShader( program, vertexShader ); + gl.attachShader( program, fragmentShader ); + + gl.linkProgram( program ); + + return program; +} \ No newline at end of file diff --git a/Übung_23112023/aufgabe2/index.html b/Übung_23112023/aufgabe2/index.html new file mode 100644 index 0000000..370e3b1 --- /dev/null +++ b/Übung_23112023/aufgabe2/index.html @@ -0,0 +1,56 @@ + + + + + WebGL Example + + + + + + + + +

Lorem Ipsum

+ + + If you see this, your browser doesn't support WebGL. + + + + + diff --git a/Übung_23112023/aufgabe2/main.js b/Übung_23112023/aufgabe2/main.js new file mode 100644 index 0000000..82dc80e --- /dev/null +++ b/Übung_23112023/aufgabe2/main.js @@ -0,0 +1,71 @@ +"use strict" ; + +let gl; +let viewLoc; +let program; +let objects = []; +let posLoc, + colorLoc; +let lastTimestamp; + +function main() { + + // Get canvas and setup WebGL context + const canvas = document.getElementById("gl-canvas"); + gl = canvas.getContext('webgl2'); + + // Configure viewport + gl.viewport(0,0,canvas.width,canvas.height); + gl.clearColor(1.0,1.0,1.0,1.0); + + gl.enable(gl.DEPTH_TEST); + + // Init shader program via additional function and bind it + program = initShaders(gl, "vertex-shader", "fragment-shader"); + gl.useProgram(program); + + // Get locations of shader variables + posLoc = gl.getAttribLocation(program, "vPosition"); + colorLoc = gl.getAttribLocation(program, "vColor"); + + // Create object instances + let island = new Island(); + objects.push(island); + + let river = new River(); + objects.push(river); + + // View Matrix + var mat = new Float32Array([ + 0.1767766922712326 , -0.0589255653321743 , -0.013334667310118675 , 0 , + 0 , 0.2357022613286972 , -0.006667333655059338 , 0 , + -0.1767766922712326 , -0.0589255653321743 , -0.013334667310118675 , 0 , + 0 , 0 , -0.8801880478858948 , 1 + ]); + viewLoc = gl.getUniformLocation(program,"viewMatrix"); + gl.uniformMatrix4fv(viewLoc,false,mat); + + window.requestAnimationFrame(render); +}; + +function render(timestamp) { + + // Only clear once + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + if (lastTimestamp == undefined) { + lastTimestamp = timestamp; + } + + const elapsed = timestamp - lastTimestamp; + + // Call render function of each scene object + // and don't mix up "of" and "in" up here, both keywords + // are valid but have different meanings + for(let object of objects) { + object.Render(); + }; + window.requestAnimationFrame(render); +} + +main(); diff --git a/Übung_23112023/uebung-woche6.pdf b/Übung_23112023/uebung-woche6.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0ac423dc181a3f734df8317e87f35daa5123f936 GIT binary patch literal 573919 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
@}FZrC4P7$0H*=&{!AZ&4) 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 z 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

Gif4^4+@n_{@sKEgo;c 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

fWgn#Ja)R*N`S-m( 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