diff --git a/0.834d1c5a.iframe.bundle.js b/0.834d1c5a.iframe.bundle.js new file mode 100644 index 00000000000..aa091a6dcfe --- /dev/null +++ b/0.834d1c5a.iframe.bundle.js @@ -0,0 +1,4153 @@ +(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{ + +/***/ 5180: +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* WEBPACK VAR INJECTION */(function(process, Buffer, global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Arcs", function() { return Arcs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Atmosphere", function() { return Atmosphere; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Background", function() { return Background; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Callout", function() { return Callout; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CalloutDefinition", function() { return CalloutDefinition; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CalloutManager", function() { return CalloutManager; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Camera", function() { return Camera; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DataStore", function() { return DataStore; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Drawable", function() { return Drawable; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GKUtils", function() { return GKUtils; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Geometry", function() { return Geometry; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GlobeKitView", function() { return GlobeKitView; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Icosphere", function() { return Icosphere; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IcosphereLookup", function() { return IcosphereLookup; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Lookup", function() { return Lookup; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Lowpoly", function() { return Lowpoly; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Points", function() { return Points; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QuadNormal", function() { return QuadNormal; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Renderer", function() { return Renderer; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Scene", function() { return Scene; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderMaterial", function() { return ShaderMaterial; }); +/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(17); +/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(694); +/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(695); +/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _babel_runtime_helpers_typeof__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(62); +/* harmony import */ var _babel_runtime_helpers_typeof__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_typeof__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_4__); +function _loadWasmModule(sync,src,imports){var buf=null;var isNode=typeof process!=='undefined'&&process.versions!=null&&process.versions.node!=null;if(isNode){buf=Buffer.from(src,'base64');}else{var raw=globalThis.atob(src);var rawLength=raw.length;buf=new Uint8Array(new ArrayBuffer(rawLength));for(var i=0;iarr.length)len=arr.length;for(var i=0,arr2=new Array(len);i0.00001){dst[0]=a[0]/len;dst[1]=a[1]/len;dst[2]=a[2]/len;}else{dst[0]=0;dst[1]=0;dst[2]=0;}return dst;}/** + * Multiplies a vector by another vector (component-wise); assumes a and + * b have the same length. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The vector of products of entries of a and + * b. + * @memberOf module:twgl/v3 + */function multiply(a,b,dst){dst=dst||new VecType(3);dst[0]=a[0]*b[0];dst[1]=a[1]*b[1];dst[2]=a[2]*b[2];return dst;}/* + * Copyright 2019 Gregg Tavares + * + * 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. + */ /** + * 4x4 Matrix math math functions. + * + * Almost all functions take an optional `dst` argument. If it is not passed in the + * functions will create a new matrix. In other words you can do this + * + * const mat = m4.translation([1, 2, 3]); // Creates a new translation matrix + * + * or + * + * const mat = m4.create(); + * m4.translation([1, 2, 3], mat); // Puts translation matrix in mat. + * + * The first style is often easier but depending on where it's used it generates garbage where + * as there is almost never allocation with the second style. + * + * It is always save to pass any matrix as the destination. So for example + * + * const mat = m4.identity(); + * const trans = m4.translation([1, 2, 3]); + * m4.multiply(mat, trans, mat); // Multiplies mat * trans and puts result in mat. + * + * @module twgl/m4 + */var MatType=Float32Array;/** + * A JavaScript array with 16 values or a Float32Array with 16 values. + * When created by the library will create the default type which is `Float32Array` + * but can be set by calling {@link module:twgl/m4.setDefaultType}. + * @typedef {(number[]|Float32Array)} Mat4 + * @memberOf module:twgl/m4 + */ /** + * Sets the type this library creates for a Mat4 + * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array` + * @return {constructor} previous constructor for Mat4 + * @memberOf module:twgl/m4 + */function setDefaultType$1(ctor){var oldType=MatType;MatType=ctor;return oldType;}/** + * Negates a matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} -m. + * @memberOf module:twgl/m4 + */function negate$1(m,dst){dst=dst||new MatType(16);dst[0]=-m[0];dst[1]=-m[1];dst[2]=-m[2];dst[3]=-m[3];dst[4]=-m[4];dst[5]=-m[5];dst[6]=-m[6];dst[7]=-m[7];dst[8]=-m[8];dst[9]=-m[9];dst[10]=-m[10];dst[11]=-m[11];dst[12]=-m[12];dst[13]=-m[13];dst[14]=-m[14];dst[15]=-m[15];return dst;}/** + * Copies a matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] The matrix. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} A copy of m. + * @memberOf module:twgl/m4 + */function copy$1(m,dst){dst=dst||new MatType(16);dst[0]=m[0];dst[1]=m[1];dst[2]=m[2];dst[3]=m[3];dst[4]=m[4];dst[5]=m[5];dst[6]=m[6];dst[7]=m[7];dst[8]=m[8];dst[9]=m[9];dst[10]=m[10];dst[11]=m[11];dst[12]=m[12];dst[13]=m[13];dst[14]=m[14];dst[15]=m[15];return dst;}/** + * Creates an n-by-n identity matrix. + * + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} An n-by-n identity matrix. + * @memberOf module:twgl/m4 + */function identity(dst){dst=dst||new MatType(16);dst[0]=1;dst[1]=0;dst[2]=0;dst[3]=0;dst[4]=0;dst[5]=1;dst[6]=0;dst[7]=0;dst[8]=0;dst[9]=0;dst[10]=1;dst[11]=0;dst[12]=0;dst[13]=0;dst[14]=0;dst[15]=1;return dst;}/** + * Takes the transpose of a matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The transpose of m. + * @memberOf module:twgl/m4 + */function transpose(m,dst){dst=dst||new MatType(16);if(dst===m){var t;t=m[1];m[1]=m[4];m[4]=t;t=m[2];m[2]=m[8];m[8]=t;t=m[3];m[3]=m[12];m[12]=t;t=m[6];m[6]=m[9];m[9]=t;t=m[7];m[7]=m[13];m[13]=t;t=m[11];m[11]=m[14];m[14]=t;return dst;}var m00=m[0*4+0];var m01=m[0*4+1];var m02=m[0*4+2];var m03=m[0*4+3];var m10=m[1*4+0];var m11=m[1*4+1];var m12=m[1*4+2];var m13=m[1*4+3];var m20=m[2*4+0];var m21=m[2*4+1];var m22=m[2*4+2];var m23=m[2*4+3];var m30=m[3*4+0];var m31=m[3*4+1];var m32=m[3*4+2];var m33=m[3*4+3];dst[0]=m00;dst[1]=m10;dst[2]=m20;dst[3]=m30;dst[4]=m01;dst[5]=m11;dst[6]=m21;dst[7]=m31;dst[8]=m02;dst[9]=m12;dst[10]=m22;dst[11]=m32;dst[12]=m03;dst[13]=m13;dst[14]=m23;dst[15]=m33;return dst;}/** + * Computes the inverse of a 4-by-4 matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The inverse of m. + * @memberOf module:twgl/m4 + */function inverse(m,dst){dst=dst||new MatType(16);var m00=m[0*4+0];var m01=m[0*4+1];var m02=m[0*4+2];var m03=m[0*4+3];var m10=m[1*4+0];var m11=m[1*4+1];var m12=m[1*4+2];var m13=m[1*4+3];var m20=m[2*4+0];var m21=m[2*4+1];var m22=m[2*4+2];var m23=m[2*4+3];var m30=m[3*4+0];var m31=m[3*4+1];var m32=m[3*4+2];var m33=m[3*4+3];var tmp_0=m22*m33;var tmp_1=m32*m23;var tmp_2=m12*m33;var tmp_3=m32*m13;var tmp_4=m12*m23;var tmp_5=m22*m13;var tmp_6=m02*m33;var tmp_7=m32*m03;var tmp_8=m02*m23;var tmp_9=m22*m03;var tmp_10=m02*m13;var tmp_11=m12*m03;var tmp_12=m20*m31;var tmp_13=m30*m21;var tmp_14=m10*m31;var tmp_15=m30*m11;var tmp_16=m10*m21;var tmp_17=m20*m11;var tmp_18=m00*m31;var tmp_19=m30*m01;var tmp_20=m00*m21;var tmp_21=m20*m01;var tmp_22=m00*m11;var tmp_23=m10*m01;var t0=tmp_0*m11+tmp_3*m21+tmp_4*m31-(tmp_1*m11+tmp_2*m21+tmp_5*m31);var t1=tmp_1*m01+tmp_6*m21+tmp_9*m31-(tmp_0*m01+tmp_7*m21+tmp_8*m31);var t2=tmp_2*m01+tmp_7*m11+tmp_10*m31-(tmp_3*m01+tmp_6*m11+tmp_11*m31);var t3=tmp_5*m01+tmp_8*m11+tmp_11*m21-(tmp_4*m01+tmp_9*m11+tmp_10*m21);var d=1.0/(m00*t0+m10*t1+m20*t2+m30*t3);dst[0]=d*t0;dst[1]=d*t1;dst[2]=d*t2;dst[3]=d*t3;dst[4]=d*(tmp_1*m10+tmp_2*m20+tmp_5*m30-(tmp_0*m10+tmp_3*m20+tmp_4*m30));dst[5]=d*(tmp_0*m00+tmp_7*m20+tmp_8*m30-(tmp_1*m00+tmp_6*m20+tmp_9*m30));dst[6]=d*(tmp_3*m00+tmp_6*m10+tmp_11*m30-(tmp_2*m00+tmp_7*m10+tmp_10*m30));dst[7]=d*(tmp_4*m00+tmp_9*m10+tmp_10*m20-(tmp_5*m00+tmp_8*m10+tmp_11*m20));dst[8]=d*(tmp_12*m13+tmp_15*m23+tmp_16*m33-(tmp_13*m13+tmp_14*m23+tmp_17*m33));dst[9]=d*(tmp_13*m03+tmp_18*m23+tmp_21*m33-(tmp_12*m03+tmp_19*m23+tmp_20*m33));dst[10]=d*(tmp_14*m03+tmp_19*m13+tmp_22*m33-(tmp_15*m03+tmp_18*m13+tmp_23*m33));dst[11]=d*(tmp_17*m03+tmp_20*m13+tmp_23*m23-(tmp_16*m03+tmp_21*m13+tmp_22*m23));dst[12]=d*(tmp_14*m22+tmp_17*m32+tmp_13*m12-(tmp_16*m32+tmp_12*m12+tmp_15*m22));dst[13]=d*(tmp_20*m32+tmp_12*m02+tmp_19*m22-(tmp_18*m22+tmp_21*m32+tmp_13*m02));dst[14]=d*(tmp_18*m12+tmp_23*m32+tmp_15*m02-(tmp_22*m32+tmp_14*m02+tmp_19*m12));dst[15]=d*(tmp_22*m22+tmp_16*m02+tmp_21*m12-(tmp_20*m12+tmp_23*m22+tmp_17*m02));return dst;}/** + * Multiplies two 4-by-4 matrices with a on the left and b on the right + * @param {module:twgl/m4.Mat4} a The matrix on the left. + * @param {module:twgl/m4.Mat4} b The matrix on the right. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The matrix product of a and b. + * @memberOf module:twgl/m4 + */function multiply$1(a,b,dst){dst=dst||new MatType(16);var a00=a[0];var a01=a[1];var a02=a[2];var a03=a[3];var a10=a[4+0];var a11=a[4+1];var a12=a[4+2];var a13=a[4+3];var a20=a[8+0];var a21=a[8+1];var a22=a[8+2];var a23=a[8+3];var a30=a[12+0];var a31=a[12+1];var a32=a[12+2];var a33=a[12+3];var b00=b[0];var b01=b[1];var b02=b[2];var b03=b[3];var b10=b[4+0];var b11=b[4+1];var b12=b[4+2];var b13=b[4+3];var b20=b[8+0];var b21=b[8+1];var b22=b[8+2];var b23=b[8+3];var b30=b[12+0];var b31=b[12+1];var b32=b[12+2];var b33=b[12+3];dst[0]=a00*b00+a10*b01+a20*b02+a30*b03;dst[1]=a01*b00+a11*b01+a21*b02+a31*b03;dst[2]=a02*b00+a12*b01+a22*b02+a32*b03;dst[3]=a03*b00+a13*b01+a23*b02+a33*b03;dst[4]=a00*b10+a10*b11+a20*b12+a30*b13;dst[5]=a01*b10+a11*b11+a21*b12+a31*b13;dst[6]=a02*b10+a12*b11+a22*b12+a32*b13;dst[7]=a03*b10+a13*b11+a23*b12+a33*b13;dst[8]=a00*b20+a10*b21+a20*b22+a30*b23;dst[9]=a01*b20+a11*b21+a21*b22+a31*b23;dst[10]=a02*b20+a12*b21+a22*b22+a32*b23;dst[11]=a03*b20+a13*b21+a23*b22+a33*b23;dst[12]=a00*b30+a10*b31+a20*b32+a30*b33;dst[13]=a01*b30+a11*b31+a21*b32+a31*b33;dst[14]=a02*b30+a12*b31+a22*b32+a32*b33;dst[15]=a03*b30+a13*b31+a23*b32+a33*b33;return dst;}/** + * Sets the translation component of a 4-by-4 matrix to the given + * vector. + * @param {module:twgl/m4.Mat4} a The matrix. + * @param {module:twgl/v3.Vec3} v The vector. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The matrix with translation set. + * @memberOf module:twgl/m4 + */function setTranslation(a,v,dst){dst=dst||identity();if(a!==dst){dst[0]=a[0];dst[1]=a[1];dst[2]=a[2];dst[3]=a[3];dst[4]=a[4];dst[5]=a[5];dst[6]=a[6];dst[7]=a[7];dst[8]=a[8];dst[9]=a[9];dst[10]=a[10];dst[11]=a[11];}dst[12]=v[0];dst[13]=v[1];dst[14]=v[2];dst[15]=1;return dst;}/** + * Returns the translation component of a 4-by-4 matrix as a vector with 3 + * entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The translation component of m. + * @memberOf module:twgl/m4 + */function getTranslation(m,dst){dst=dst||create();dst[0]=m[12];dst[1]=m[13];dst[2]=m[14];return dst;}/** + * Returns an axis of a 4x4 matrix as a vector with 3 entries + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} axis The axis 0 = x, 1 = y, 2 = z; + * @return {module:twgl/v3.Vec3} [dst] vector. + * @return {module:twgl/v3.Vec3} The axis component of m. + * @memberOf module:twgl/m4 + */function getAxis(m,axis,dst){dst=dst||create();var off=axis*4;dst[0]=m[off+0];dst[1]=m[off+1];dst[2]=m[off+2];return dst;}/** + * Sets an axis of a 4x4 matrix as a vector with 3 entries + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v the axis vector + * @param {number} axis The axis 0 = x, 1 = y, 2 = z; + * @param {module:twgl/m4.Mat4} [dst] The matrix to set. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The matrix with axis set. + * @memberOf module:twgl/m4 + */function setAxis(a,v,axis,dst){if(dst!==a){dst=copy$1(a,dst);}var off=axis*4;dst[off+0]=v[0];dst[off+1]=v[1];dst[off+2]=v[2];return dst;}/** + * Computes a 4-by-4 perspective transformation matrix given the angular height + * of the frustum, the aspect ratio, and the near and far clipping planes. The + * arguments define a frustum extending in the negative z direction. The given + * angle is the vertical angle of the frustum, and the horizontal angle is + * determined to produce the given aspect ratio. The arguments near and far are + * the distances to the near and far clipping planes. Note that near and far + * are not z coordinates, but rather they are distances along the negative + * z-axis. The matrix generated sends the viewing frustum to the unit box. + * We assume a unit box extending from -1 to 1 in the x and y dimensions and + * from 0 to 1 in the z dimension. + * @param {number} fieldOfViewYInRadians The camera angle from top to bottom (in radians). + * @param {number} aspect The aspect ratio width / height. + * @param {number} zNear The depth (negative z coordinate) + * of the near clipping plane. + * @param {number} zFar The depth (negative z coordinate) + * of the far clipping plane. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The perspective matrix. + * @memberOf module:twgl/m4 + */function perspective(fieldOfViewYInRadians,aspect,zNear,zFar,dst){dst=dst||new MatType(16);var f=Math.tan(Math.PI*0.5-0.5*fieldOfViewYInRadians);var rangeInv=1.0/(zNear-zFar);dst[0]=f/aspect;dst[1]=0;dst[2]=0;dst[3]=0;dst[4]=0;dst[5]=f;dst[6]=0;dst[7]=0;dst[8]=0;dst[9]=0;dst[10]=(zNear+zFar)*rangeInv;dst[11]=-1;dst[12]=0;dst[13]=0;dst[14]=zNear*zFar*rangeInv*2;dst[15]=0;return dst;}/** + * Computes a 4-by-4 orthogonal transformation matrix given the left, right, + * bottom, and top dimensions of the near clipping plane as well as the + * near and far clipping plane distances. + * @param {number} left Left side of the near clipping plane viewport. + * @param {number} right Right side of the near clipping plane viewport. + * @param {number} bottom Bottom of the near clipping plane viewport. + * @param {number} top Top of the near clipping plane viewport. + * @param {number} near The depth (negative z coordinate) + * of the near clipping plane. + * @param {number} far The depth (negative z coordinate) + * of the far clipping plane. + * @param {module:twgl/m4.Mat4} [dst] Output matrix. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The perspective matrix. + * @memberOf module:twgl/m4 + */function ortho(left,right,bottom,top,near,far,dst){dst=dst||new MatType(16);dst[0]=2/(right-left);dst[1]=0;dst[2]=0;dst[3]=0;dst[4]=0;dst[5]=2/(top-bottom);dst[6]=0;dst[7]=0;dst[8]=0;dst[9]=0;dst[10]=2/(near-far);dst[11]=0;dst[12]=(right+left)/(left-right);dst[13]=(top+bottom)/(bottom-top);dst[14]=(far+near)/(near-far);dst[15]=1;return dst;}/** + * Computes a 4-by-4 perspective transformation matrix given the left, right, + * top, bottom, near and far clipping planes. The arguments define a frustum + * extending in the negative z direction. The arguments near and far are the + * distances to the near and far clipping planes. Note that near and far are not + * z coordinates, but rather they are distances along the negative z-axis. The + * matrix generated sends the viewing frustum to the unit box. We assume a unit + * box extending from -1 to 1 in the x and y dimensions and from 0 to 1 in the z + * dimension. + * @param {number} left The x coordinate of the left plane of the box. + * @param {number} right The x coordinate of the right plane of the box. + * @param {number} bottom The y coordinate of the bottom plane of the box. + * @param {number} top The y coordinate of the right plane of the box. + * @param {number} near The negative z coordinate of the near plane of the box. + * @param {number} far The negative z coordinate of the far plane of the box. + * @param {module:twgl/m4.Mat4} [dst] Output matrix. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The perspective projection matrix. + * @memberOf module:twgl/m4 + */function frustum(left,right,bottom,top,near,far,dst){dst=dst||new MatType(16);var dx=right-left;var dy=top-bottom;var dz=near-far;dst[0]=2*near/dx;dst[1]=0;dst[2]=0;dst[3]=0;dst[4]=0;dst[5]=2*near/dy;dst[6]=0;dst[7]=0;dst[8]=(left+right)/dx;dst[9]=(top+bottom)/dy;dst[10]=far/dz;dst[11]=-1;dst[12]=0;dst[13]=0;dst[14]=near*far/dz;dst[15]=0;return dst;}var xAxis;var yAxis;var zAxis;/** + * Computes a 4-by-4 look-at transformation. + * + * This is a matrix which positions the camera itself. If you want + * a view matrix (a matrix which moves things in front of the camera) + * take the inverse of this. + * + * @param {module:twgl/v3.Vec3} eye The position of the eye. + * @param {module:twgl/v3.Vec3} target The position meant to be viewed. + * @param {module:twgl/v3.Vec3} up A vector pointing up. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The look-at matrix. + * @memberOf module:twgl/m4 + */function lookAt(eye,target,up,dst){dst=dst||new MatType(16);xAxis=xAxis||create();yAxis=yAxis||create();zAxis=zAxis||create();normalize(subtract(eye,target,zAxis),zAxis);normalize(cross(up,zAxis,xAxis),xAxis);normalize(cross(zAxis,xAxis,yAxis),yAxis);dst[0]=xAxis[0];dst[1]=xAxis[1];dst[2]=xAxis[2];dst[3]=0;dst[4]=yAxis[0];dst[5]=yAxis[1];dst[6]=yAxis[2];dst[7]=0;dst[8]=zAxis[0];dst[9]=zAxis[1];dst[10]=zAxis[2];dst[11]=0;dst[12]=eye[0];dst[13]=eye[1];dst[14]=eye[2];dst[15]=1;return dst;}/** + * Creates a 4-by-4 matrix which translates by the given vector v. + * @param {module:twgl/v3.Vec3} v The vector by + * which to translate. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The translation matrix. + * @memberOf module:twgl/m4 + */function translation(v,dst){dst=dst||new MatType(16);dst[0]=1;dst[1]=0;dst[2]=0;dst[3]=0;dst[4]=0;dst[5]=1;dst[6]=0;dst[7]=0;dst[8]=0;dst[9]=0;dst[10]=1;dst[11]=0;dst[12]=v[0];dst[13]=v[1];dst[14]=v[2];dst[15]=1;return dst;}/** + * Translates the given 4-by-4 matrix by the given vector v. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The vector by + * which to translate. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The translated matrix. + * @memberOf module:twgl/m4 + */function translate(m,v,dst){dst=dst||new MatType(16);var v0=v[0];var v1=v[1];var v2=v[2];var m00=m[0];var m01=m[1];var m02=m[2];var m03=m[3];var m10=m[1*4+0];var m11=m[1*4+1];var m12=m[1*4+2];var m13=m[1*4+3];var m20=m[2*4+0];var m21=m[2*4+1];var m22=m[2*4+2];var m23=m[2*4+3];var m30=m[3*4+0];var m31=m[3*4+1];var m32=m[3*4+2];var m33=m[3*4+3];if(m!==dst){dst[0]=m00;dst[1]=m01;dst[2]=m02;dst[3]=m03;dst[4]=m10;dst[5]=m11;dst[6]=m12;dst[7]=m13;dst[8]=m20;dst[9]=m21;dst[10]=m22;dst[11]=m23;}dst[12]=m00*v0+m10*v1+m20*v2+m30;dst[13]=m01*v0+m11*v1+m21*v2+m31;dst[14]=m02*v0+m12*v1+m22*v2+m32;dst[15]=m03*v0+m13*v1+m23*v2+m33;return dst;}/** + * Creates a 4-by-4 matrix which rotates around the x-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */function rotationX(angleInRadians,dst){dst=dst||new MatType(16);var c=Math.cos(angleInRadians);var s=Math.sin(angleInRadians);dst[0]=1;dst[1]=0;dst[2]=0;dst[3]=0;dst[4]=0;dst[5]=c;dst[6]=s;dst[7]=0;dst[8]=0;dst[9]=-s;dst[10]=c;dst[11]=0;dst[12]=0;dst[13]=0;dst[14]=0;dst[15]=1;return dst;}/** + * Rotates the given 4-by-4 matrix around the x-axis by the given + * angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */function rotateX(m,angleInRadians,dst){dst=dst||new MatType(16);var m10=m[4];var m11=m[5];var m12=m[6];var m13=m[7];var m20=m[8];var m21=m[9];var m22=m[10];var m23=m[11];var c=Math.cos(angleInRadians);var s=Math.sin(angleInRadians);dst[4]=c*m10+s*m20;dst[5]=c*m11+s*m21;dst[6]=c*m12+s*m22;dst[7]=c*m13+s*m23;dst[8]=c*m20-s*m10;dst[9]=c*m21-s*m11;dst[10]=c*m22-s*m12;dst[11]=c*m23-s*m13;if(m!==dst){dst[0]=m[0];dst[1]=m[1];dst[2]=m[2];dst[3]=m[3];dst[12]=m[12];dst[13]=m[13];dst[14]=m[14];dst[15]=m[15];}return dst;}/** + * Creates a 4-by-4 matrix which rotates around the y-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */function rotationY(angleInRadians,dst){dst=dst||new MatType(16);var c=Math.cos(angleInRadians);var s=Math.sin(angleInRadians);dst[0]=c;dst[1]=0;dst[2]=-s;dst[3]=0;dst[4]=0;dst[5]=1;dst[6]=0;dst[7]=0;dst[8]=s;dst[9]=0;dst[10]=c;dst[11]=0;dst[12]=0;dst[13]=0;dst[14]=0;dst[15]=1;return dst;}/** + * Rotates the given 4-by-4 matrix around the y-axis by the given + * angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */function rotateY(m,angleInRadians,dst){dst=dst||new MatType(16);var m00=m[0*4+0];var m01=m[0*4+1];var m02=m[0*4+2];var m03=m[0*4+3];var m20=m[2*4+0];var m21=m[2*4+1];var m22=m[2*4+2];var m23=m[2*4+3];var c=Math.cos(angleInRadians);var s=Math.sin(angleInRadians);dst[0]=c*m00-s*m20;dst[1]=c*m01-s*m21;dst[2]=c*m02-s*m22;dst[3]=c*m03-s*m23;dst[8]=c*m20+s*m00;dst[9]=c*m21+s*m01;dst[10]=c*m22+s*m02;dst[11]=c*m23+s*m03;if(m!==dst){dst[4]=m[4];dst[5]=m[5];dst[6]=m[6];dst[7]=m[7];dst[12]=m[12];dst[13]=m[13];dst[14]=m[14];dst[15]=m[15];}return dst;}/** + * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */function rotationZ(angleInRadians,dst){dst=dst||new MatType(16);var c=Math.cos(angleInRadians);var s=Math.sin(angleInRadians);dst[0]=c;dst[1]=s;dst[2]=0;dst[3]=0;dst[4]=-s;dst[5]=c;dst[6]=0;dst[7]=0;dst[8]=0;dst[9]=0;dst[10]=1;dst[11]=0;dst[12]=0;dst[13]=0;dst[14]=0;dst[15]=1;return dst;}/** + * Rotates the given 4-by-4 matrix around the z-axis by the given + * angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */function rotateZ(m,angleInRadians,dst){dst=dst||new MatType(16);var m00=m[0*4+0];var m01=m[0*4+1];var m02=m[0*4+2];var m03=m[0*4+3];var m10=m[1*4+0];var m11=m[1*4+1];var m12=m[1*4+2];var m13=m[1*4+3];var c=Math.cos(angleInRadians);var s=Math.sin(angleInRadians);dst[0]=c*m00+s*m10;dst[1]=c*m01+s*m11;dst[2]=c*m02+s*m12;dst[3]=c*m03+s*m13;dst[4]=c*m10-s*m00;dst[5]=c*m11-s*m01;dst[6]=c*m12-s*m02;dst[7]=c*m13-s*m03;if(m!==dst){dst[8]=m[8];dst[9]=m[9];dst[10]=m[10];dst[11]=m[11];dst[12]=m[12];dst[13]=m[13];dst[14]=m[14];dst[15]=m[15];}return dst;}/** + * Creates a 4-by-4 matrix which rotates around the given axis by the given + * angle. + * @param {module:twgl/v3.Vec3} axis The axis + * about which to rotate. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} A matrix which rotates angle radians + * around the axis. + * @memberOf module:twgl/m4 + */function axisRotation(axis,angleInRadians,dst){dst=dst||new MatType(16);var x=axis[0];var y=axis[1];var z=axis[2];var n=Math.sqrt(x*x+y*y+z*z);x/=n;y/=n;z/=n;var xx=x*x;var yy=y*y;var zz=z*z;var c=Math.cos(angleInRadians);var s=Math.sin(angleInRadians);var oneMinusCosine=1-c;dst[0]=xx+(1-xx)*c;dst[1]=x*y*oneMinusCosine+z*s;dst[2]=x*z*oneMinusCosine-y*s;dst[3]=0;dst[4]=x*y*oneMinusCosine-z*s;dst[5]=yy+(1-yy)*c;dst[6]=y*z*oneMinusCosine+x*s;dst[7]=0;dst[8]=x*z*oneMinusCosine+y*s;dst[9]=y*z*oneMinusCosine-x*s;dst[10]=zz+(1-zz)*c;dst[11]=0;dst[12]=0;dst[13]=0;dst[14]=0;dst[15]=1;return dst;}/** + * Rotates the given 4-by-4 matrix around the given axis by the + * given angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} axis The axis + * about which to rotate. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */function axisRotate(m,axis,angleInRadians,dst){dst=dst||new MatType(16);var x=axis[0];var y=axis[1];var z=axis[2];var n=Math.sqrt(x*x+y*y+z*z);x/=n;y/=n;z/=n;var xx=x*x;var yy=y*y;var zz=z*z;var c=Math.cos(angleInRadians);var s=Math.sin(angleInRadians);var oneMinusCosine=1-c;var r00=xx+(1-xx)*c;var r01=x*y*oneMinusCosine+z*s;var r02=x*z*oneMinusCosine-y*s;var r10=x*y*oneMinusCosine-z*s;var r11=yy+(1-yy)*c;var r12=y*z*oneMinusCosine+x*s;var r20=x*z*oneMinusCosine+y*s;var r21=y*z*oneMinusCosine-x*s;var r22=zz+(1-zz)*c;var m00=m[0];var m01=m[1];var m02=m[2];var m03=m[3];var m10=m[4];var m11=m[5];var m12=m[6];var m13=m[7];var m20=m[8];var m21=m[9];var m22=m[10];var m23=m[11];dst[0]=r00*m00+r01*m10+r02*m20;dst[1]=r00*m01+r01*m11+r02*m21;dst[2]=r00*m02+r01*m12+r02*m22;dst[3]=r00*m03+r01*m13+r02*m23;dst[4]=r10*m00+r11*m10+r12*m20;dst[5]=r10*m01+r11*m11+r12*m21;dst[6]=r10*m02+r11*m12+r12*m22;dst[7]=r10*m03+r11*m13+r12*m23;dst[8]=r20*m00+r21*m10+r22*m20;dst[9]=r20*m01+r21*m11+r22*m21;dst[10]=r20*m02+r21*m12+r22*m22;dst[11]=r20*m03+r21*m13+r22*m23;if(m!==dst){dst[12]=m[12];dst[13]=m[13];dst[14]=m[14];dst[15]=m[15];}return dst;}/** + * Creates a 4-by-4 matrix which scales in each dimension by an amount given by + * the corresponding entry in the given vector; assumes the vector has three + * entries. + * @param {module:twgl/v3.Vec3} v A vector of + * three entries specifying the factor by which to scale in each dimension. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The scaling matrix. + * @memberOf module:twgl/m4 + */function scaling(v,dst){dst=dst||new MatType(16);dst[0]=v[0];dst[1]=0;dst[2]=0;dst[3]=0;dst[4]=0;dst[5]=v[1];dst[6]=0;dst[7]=0;dst[8]=0;dst[9]=0;dst[10]=v[2];dst[11]=0;dst[12]=0;dst[13]=0;dst[14]=0;dst[15]=1;return dst;}/** + * Scales the given 4-by-4 matrix in each dimension by an amount + * given by the corresponding entry in the given vector; assumes the vector has + * three entries. + * @param {module:twgl/m4.Mat4} m The matrix to be modified. + * @param {module:twgl/v3.Vec3} v A vector of three entries specifying the + * factor by which to scale in each dimension. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The scaled matrix. + * @memberOf module:twgl/m4 + */function scale(m,v,dst){dst=dst||new MatType(16);var v0=v[0];var v1=v[1];var v2=v[2];dst[0]=v0*m[0*4+0];dst[1]=v0*m[0*4+1];dst[2]=v0*m[0*4+2];dst[3]=v0*m[0*4+3];dst[4]=v1*m[1*4+0];dst[5]=v1*m[1*4+1];dst[6]=v1*m[1*4+2];dst[7]=v1*m[1*4+3];dst[8]=v2*m[2*4+0];dst[9]=v2*m[2*4+1];dst[10]=v2*m[2*4+2];dst[11]=v2*m[2*4+3];if(m!==dst){dst[12]=m[12];dst[13]=m[13];dst[14]=m[14];dst[15]=m[15];}return dst;}/** + * Takes a 4-by-4 matrix and a vector with 3 entries, + * interprets the vector as a point, transforms that point by the matrix, and + * returns the result as a vector with 3 entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The point. + * @param {module:twgl/v3.Vec3} [dst] optional vec3 to store result. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The transformed point. + * @memberOf module:twgl/m4 + */function transformPoint(m,v,dst){dst=dst||create();var v0=v[0];var v1=v[1];var v2=v[2];var d=v0*m[0*4+3]+v1*m[1*4+3]+v2*m[2*4+3]+m[3*4+3];dst[0]=(v0*m[0*4+0]+v1*m[1*4+0]+v2*m[2*4+0]+m[3*4+0])/d;dst[1]=(v0*m[0*4+1]+v1*m[1*4+1]+v2*m[2*4+1]+m[3*4+1])/d;dst[2]=(v0*m[0*4+2]+v1*m[1*4+2]+v2*m[2*4+2]+m[3*4+2])/d;return dst;}/** + * Takes a 4-by-4 matrix and a vector with 3 entries, interprets the vector as a + * direction, transforms that direction by the matrix, and returns the result; + * assumes the transformation of 3-dimensional space represented by the matrix + * is parallel-preserving, i.e. any combination of rotation, scaling and + * translation, but not a perspective distortion. Returns a vector with 3 + * entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The direction. + * @param {module:twgl/v3.Vec3} [dst] optional Vec3 to store result. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The transformed direction. + * @memberOf module:twgl/m4 + */function transformDirection(m,v,dst){dst=dst||create();var v0=v[0];var v1=v[1];var v2=v[2];dst[0]=v0*m[0*4+0]+v1*m[1*4+0]+v2*m[2*4+0];dst[1]=v0*m[0*4+1]+v1*m[1*4+1]+v2*m[2*4+1];dst[2]=v0*m[0*4+2]+v1*m[1*4+2]+v2*m[2*4+2];return dst;}/** + * Takes a 4-by-4 matrix m and a vector v with 3 entries, interprets the vector + * as a normal to a surface, and computes a vector which is normal upon + * transforming that surface by the matrix. The effect of this function is the + * same as transforming v (as a direction) by the inverse-transpose of m. This + * function assumes the transformation of 3-dimensional space represented by the + * matrix is parallel-preserving, i.e. any combination of rotation, scaling and + * translation, but not a perspective distortion. Returns a vector with 3 + * entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The normal. + * @param {module:twgl/v3.Vec3} [dst] The direction. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The transformed normal. + * @memberOf module:twgl/m4 + */function transformNormal(m,v,dst){dst=dst||create();var mi=inverse(m);var v0=v[0];var v1=v[1];var v2=v[2];dst[0]=v0*mi[0*4+0]+v1*mi[0*4+1]+v2*mi[0*4+2];dst[1]=v0*mi[1*4+0]+v1*mi[1*4+1]+v2*mi[1*4+2];dst[2]=v0*mi[2*4+0]+v1*mi[2*4+1]+v2*mi[2*4+2];return dst;}var m4=/*#__PURE__*/Object.freeze({__proto__:null,axisRotate:axisRotate,axisRotation:axisRotation,copy:copy$1,frustum:frustum,getAxis:getAxis,getTranslation:getTranslation,identity:identity,inverse:inverse,lookAt:lookAt,multiply:multiply$1,negate:negate$1,ortho:ortho,perspective:perspective,rotateX:rotateX,rotateY:rotateY,rotateZ:rotateZ,rotationX:rotationX,rotationY:rotationY,rotationZ:rotationZ,scale:scale,scaling:scaling,setAxis:setAxis,setDefaultType:setDefaultType$1,setTranslation:setTranslation,transformDirection:transformDirection,transformNormal:transformNormal,transformPoint:transformPoint,translate:translate,translation:translation,transpose:transpose});/* + * Copyright 2019 Gregg Tavares + * + * 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. + */ /* DataType */var BYTE=0x1400;var UNSIGNED_BYTE=0x1401;var SHORT=0x1402;var UNSIGNED_SHORT=0x1403;var INT=0x1404;var UNSIGNED_INT=0x1405;var FLOAT=0x1406;var UNSIGNED_SHORT_4_4_4_4=0x8033;var UNSIGNED_SHORT_5_5_5_1=0x8034;var UNSIGNED_SHORT_5_6_5=0x8363;var HALF_FLOAT=0x140B;var UNSIGNED_INT_2_10_10_10_REV=0x8368;var UNSIGNED_INT_10F_11F_11F_REV=0x8C3B;var UNSIGNED_INT_5_9_9_9_REV=0x8C3E;var FLOAT_32_UNSIGNED_INT_24_8_REV=0x8DAD;var UNSIGNED_INT_24_8=0x84FA;var glTypeToTypedArray={};{var tt=glTypeToTypedArray;tt[BYTE]=Int8Array;tt[UNSIGNED_BYTE]=Uint8Array;tt[SHORT]=Int16Array;tt[UNSIGNED_SHORT]=Uint16Array;tt[INT]=Int32Array;tt[UNSIGNED_INT]=Uint32Array;tt[FLOAT]=Float32Array;tt[UNSIGNED_SHORT_4_4_4_4]=Uint16Array;tt[UNSIGNED_SHORT_5_5_5_1]=Uint16Array;tt[UNSIGNED_SHORT_5_6_5]=Uint16Array;tt[HALF_FLOAT]=Uint16Array;tt[UNSIGNED_INT_2_10_10_10_REV]=Uint32Array;tt[UNSIGNED_INT_10F_11F_11F_REV]=Uint32Array;tt[UNSIGNED_INT_5_9_9_9_REV]=Uint32Array;tt[FLOAT_32_UNSIGNED_INT_24_8_REV]=Uint32Array;tt[UNSIGNED_INT_24_8]=Uint32Array;}/** + * Get the GL type for a typedArray + * @param {ArrayBufferView} typedArray a typedArray + * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will + * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */function getGLTypeForTypedArray(typedArray){if(typedArray instanceof Int8Array){return BYTE;}// eslint-disable-line +if(typedArray instanceof Uint8Array){return UNSIGNED_BYTE;}// eslint-disable-line +if(typedArray instanceof Uint8ClampedArray){return UNSIGNED_BYTE;}// eslint-disable-line +if(typedArray instanceof Int16Array){return SHORT;}// eslint-disable-line +if(typedArray instanceof Uint16Array){return UNSIGNED_SHORT;}// eslint-disable-line +if(typedArray instanceof Int32Array){return INT;}// eslint-disable-line +if(typedArray instanceof Uint32Array){return UNSIGNED_INT;}// eslint-disable-line +if(typedArray instanceof Float32Array){return FLOAT;}// eslint-disable-line +throw new Error('unsupported typed array type');}/** + * Get the GL type for a typedArray type + * @param {ArrayBufferView} typedArrayType a typedArray constructor + * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will + * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */function getGLTypeForTypedArrayType(typedArrayType){if(typedArrayType===Int8Array){return BYTE;}// eslint-disable-line +if(typedArrayType===Uint8Array){return UNSIGNED_BYTE;}// eslint-disable-line +if(typedArrayType===Uint8ClampedArray){return UNSIGNED_BYTE;}// eslint-disable-line +if(typedArrayType===Int16Array){return SHORT;}// eslint-disable-line +if(typedArrayType===Uint16Array){return UNSIGNED_SHORT;}// eslint-disable-line +if(typedArrayType===Int32Array){return INT;}// eslint-disable-line +if(typedArrayType===Uint32Array){return UNSIGNED_INT;}// eslint-disable-line +if(typedArrayType===Float32Array){return FLOAT;}// eslint-disable-line +throw new Error('unsupported typed array type');}/** + * Get the typed array constructor for a given GL type + * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`) + * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`). + * @memberOf module:twgl/typedArray + */function getTypedArrayTypeForGLType(type){var CTOR=glTypeToTypedArray[type];if(!CTOR){throw new Error('unknown gl type');}return CTOR;}var isArrayBuffer=typeof SharedArrayBuffer!=='undefined'?function isArrayBufferOrSharedArrayBuffer(a){return a&&a.buffer&&(a.buffer instanceof ArrayBuffer||a.buffer instanceof SharedArrayBuffer);}:function isArrayBuffer(a){return a&&a.buffer&&a.buffer instanceof ArrayBuffer;};/* + * Copyright 2019 Gregg Tavares + * + * 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. + */ /* eslint no-console: "off" */ /** + * Copy named properties + * + * @param {string[]} names names of properties to copy + * @param {object} src object to copy properties from + * @param {object} dst object to copy properties to + * @private + */function copyNamedProperties(names,src,dst){names.forEach(function(name){var value=src[name];if(value!==undefined){dst[name]=value;}});}function error(){var _console;(_console=console).error.apply(_console,arguments);}function warn(){var _console2;(_console2=console).warn.apply(_console2,arguments);}function isBuffer(gl,t){return typeof WebGLBuffer!=='undefined'&&t instanceof WebGLBuffer;}function isShader(gl,t){return typeof WebGLShader!=='undefined'&&t instanceof WebGLShader;}function isTexture(gl,t){return typeof WebGLTexture!=='undefined'&&t instanceof WebGLTexture;}function isSampler(gl,t){return typeof WebGLSampler!=='undefined'&&t instanceof WebGLSampler;}/* + * Copyright 2019 Gregg Tavares + * + * 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. + */var STATIC_DRAW=0x88e4;var ARRAY_BUFFER=0x8892;var ELEMENT_ARRAY_BUFFER=0x8893;var BUFFER_SIZE=0x8764;var BYTE$1=0x1400;var UNSIGNED_BYTE$1=0x1401;var SHORT$1=0x1402;var UNSIGNED_SHORT$1=0x1403;var INT$1=0x1404;var UNSIGNED_INT$1=0x1405;var FLOAT$1=0x1406;var defaults={attribPrefix:""};function setBufferFromTypedArray(gl,type,buffer,array,drawType){gl.bindBuffer(type,buffer);gl.bufferData(type,array,drawType||STATIC_DRAW);}/** + * Given typed array creates a WebGLBuffer and copies the typed array + * into it. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken + * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`. + * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`. + * @return {WebGLBuffer} the created WebGLBuffer + * @memberOf module:twgl/attributes + */function createBufferFromTypedArray(gl,typedArray,type,drawType){if(isBuffer(gl,typedArray)){return typedArray;}type=type||ARRAY_BUFFER;var buffer=gl.createBuffer();setBufferFromTypedArray(gl,type,buffer,typedArray,drawType);return buffer;}function isIndices(name){return name==="indices";}// This is really just a guess. Though I can't really imagine using +// anything else? Maybe for some compression? +function getNormalizationForTypedArray(typedArray){if(typedArray instanceof Int8Array){return true;}// eslint-disable-line +if(typedArray instanceof Uint8Array){return true;}// eslint-disable-line +return false;}// This is really just a guess. Though I can't really imagine using +// anything else? Maybe for some compression? +function getNormalizationForTypedArrayType(typedArrayType){if(typedArrayType===Int8Array){return true;}// eslint-disable-line +if(typedArrayType===Uint8Array){return true;}// eslint-disable-line +return false;}function getArray(array){return array.length?array:array.data;}var texcoordRE=/coord|texture/i;var colorRE=/color|colour/i;function guessNumComponentsFromName(name,length){var numComponents;if(texcoordRE.test(name)){numComponents=2;}else if(colorRE.test(name)){numComponents=4;}else{numComponents=3;// position, normals, indices ... +}if(length%numComponents>0){throw new Error("Can not guess numComponents for attribute '".concat(name,"'. Tried ").concat(numComponents," but ").concat(length," values is not evenly divisible by ").concat(numComponents,". You should specify it."));}return numComponents;}function getNumComponents(array,arrayName){return array.numComponents||array.size||guessNumComponentsFromName(arrayName,getArray(array).length);}function makeTypedArray(array,name){if(isArrayBuffer(array)){return array;}if(isArrayBuffer(array.data)){return array.data;}if(Array.isArray(array)){array={data:array};}var Type=array.type;if(!Type){if(isIndices(name)){Type=Uint16Array;}else{Type=Float32Array;}}return new Type(array.data);}/** + * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer + * for the attribute. + * + * @typedef {Object} AttribInfo + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {number} [numComponents] the number of components for this attribute. + * @property {number} [size] synonym for `numComponents`. + * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT` + * @property {boolean} [normalize] whether or not to normalize the data. Default = false + * @property {number} [offset] offset into buffer in bytes. Default = 0 + * @property {number} [stride] the stride in bytes per element. Default = 0 + * @property {number} [divisor] the divisor in instances. Default = undefined. Note: undefined = don't call gl.vertexAttribDivisor + * where as anything else = do call it with this value + * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ /** + * Use this type of array spec when TWGL can't guess the type or number of components of an array + * @typedef {Object} FullArraySpec + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {(number|number[]|ArrayBufferView)} data The data of the array. A number alone becomes the number of elements of type. + * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array. + * If `coord` is in the name assumes `numComponents = 2`. + * If `color` is in the name assumes `numComponents = 4`. + * otherwise assumes `numComponents = 3` + * @property {constructor} [type] type. This is only used if `data` is a JavaScript array. It is the constructor for the typedarray. (eg. `Uint8Array`). + * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: Uint8Array, data: [255,0,255,255, ...], }`. + * @property {number} [size] synonym for `numComponents`. + * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false. + * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0 + * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0 + * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = undefined. Note: undefined = don't call gl.vertexAttribDivisor + * where as anything else = do call it with this value + * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix. + * @property {string} [name] synonym for `attrib`. + * @property {string} [attribName] synonym for `attrib`. + * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer + * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo` + * to provide this. Example: + * + * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, { + * position: [1, 2, 3, ... ], + * }); + * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, { + * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1 + * }); + * + * @memberOf module:twgl + */ /** + * An individual array in {@link module:twgl.Arrays} + * + * When passed to {@link module:twgl.createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView` + * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will + * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer. + * + * @typedef {(number|number[]|ArrayBufferView|module:twgl.FullArraySpec)} ArraySpec + * @memberOf module:twgl + */ /** + * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your + * attributes have a common prefix you can specify it by calling {@link module:twgl.setAttributePrefix}. + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * Objects with various fields. See {@link module:twgl.FullArraySpec}. + * + * var arrays = { + * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], }, + * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], }, + * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], }, + * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], }, + * }; + * + * @typedef {Object.} Arrays + * @memberOf module:twgl + */ /** + * Creates a set of attribute data and WebGLBuffers from set of arrays + * + * Given + * + * var arrays = { + * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], }, + * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], }, + * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], }, + * color: { numComponents: 4, data: [255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255], type: Uint8Array, }, + * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], }, + * }; + * + * returns something like + * + * var attribs = { + * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, }, + * }; + * + * notes: + * + * * Arrays can take various forms + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * @param {WebGLRenderingContext} gl The webgl rendering context. + * @param {module:twgl.Arrays} arrays The arrays + * @param {module:twgl.BufferInfo} [srcBufferInfo] a BufferInfo to copy from + * This lets you share buffers. Any arrays you supply will override + * the buffers from srcBufferInfo. + * @return {Object.} the attribs + * @memberOf module:twgl/attributes + */function createAttribsFromArrays(gl,arrays){var attribs={};Object.keys(arrays).forEach(function(arrayName){if(!isIndices(arrayName)){var array=arrays[arrayName];var attribName=array.attrib||array.name||array.attribName||defaults.attribPrefix+arrayName;if(array.value){if(!Array.isArray(array.value)&&!isArrayBuffer(array.value)){throw new Error('array.value is not array or typedarray');}attribs[attribName]={value:array.value};}else{var buffer;var type;var normalization;var numComponents;if(array.buffer&&array.buffer instanceof WebGLBuffer){buffer=array.buffer;numComponents=array.numComponents||array.size;type=array.type;normalization=array.normalize;}else if(typeof array==="number"||typeof array.data==="number"){var numValues=array.data||array;var arrayType=array.type||Float32Array;var numBytes=numValues*arrayType.BYTES_PER_ELEMENT;type=getGLTypeForTypedArrayType(arrayType);normalization=array.normalize!==undefined?array.normalize:getNormalizationForTypedArrayType(arrayType);numComponents=array.numComponents||array.size||guessNumComponentsFromName(arrayName,numValues);buffer=gl.createBuffer();gl.bindBuffer(ARRAY_BUFFER,buffer);gl.bufferData(ARRAY_BUFFER,numBytes,array.drawType||STATIC_DRAW);}else{var typedArray=makeTypedArray(array,arrayName);buffer=createBufferFromTypedArray(gl,typedArray,undefined,array.drawType);type=getGLTypeForTypedArray(typedArray);normalization=array.normalize!==undefined?array.normalize:getNormalizationForTypedArray(typedArray);numComponents=getNumComponents(array,arrayName);}attribs[attribName]={buffer:buffer,numComponents:numComponents,type:type,normalize:normalization,stride:array.stride||0,offset:array.offset||0,divisor:array.divisor===undefined?undefined:array.divisor,drawType:array.drawType};}}});gl.bindBuffer(ARRAY_BUFFER,null);return attribs;}/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * var arrays = { + * position: new Float32Array([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]), + * texcoord: new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]), + * normal: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]), + * indices: new Uint16Array([0, 1, 2, 1, 2, 3]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */function setAttribInfoBufferFromArray(gl,attribInfo,array,offset){array=makeTypedArray(array);if(offset!==undefined){gl.bindBuffer(ARRAY_BUFFER,attribInfo.buffer);gl.bufferSubData(ARRAY_BUFFER,offset,array);}else{setBufferFromTypedArray(gl,ARRAY_BUFFER,attribInfo.buffer,array,attribInfo.drawType);}}function getBytesPerValueForGLType(gl,type){if(type===BYTE$1)return 1;// eslint-disable-line +if(type===UNSIGNED_BYTE$1)return 1;// eslint-disable-line +if(type===SHORT$1)return 2;// eslint-disable-line +if(type===UNSIGNED_SHORT$1)return 2;// eslint-disable-line +if(type===INT$1)return 4;// eslint-disable-line +if(type===UNSIGNED_INT$1)return 4;// eslint-disable-line +if(type===FLOAT$1)return 4;// eslint-disable-line +return 0;}// Tries to get the number of elements from a set of arrays. +var positionKeys=['position','positions','a_position'];function getNumElementsFromNonIndexedArrays(arrays){var key;var ii;for(ii=0;ii0){throw new Error("numComponents ".concat(numComponents," not correct for length ").concat(length));}return numElements;}function getNumElementsFromAttributes(gl,attribs){var key;var ii;for(ii=0;ii} [attribs] The attribs appropriate to call `setAttributes` + * @memberOf module:twgl + */ /** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl:drawBufferInfo}. + * + * Given an object like + * + * var arrays = { + * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], }, + * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], }, + * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], }, + * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], }, + * }; + * + * Creates an BufferInfo like this + * + * bufferInfo = { + * numElements: 4, // or whatever the number of elements is + * indices: WebGLBuffer, // this property will not exist if there are no indices + * attribs: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * texcoord: { buffer: WebGLBuffer, numComponents: 2, }, + * }, + * }; + * + * The properties of arrays can be JavaScript arrays in which case the number of components + * will be guessed. + * + * var arrays = { + * position: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], + * texcoord: [0, 0, 0, 1, 1, 0, 1, 1], + * normal: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], + * indices: [0, 1, 2, 1, 2, 3], + * }; + * + * They can also be TypedArrays + * + * var arrays = { + * position: new Float32Array([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]), + * texcoord: new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]), + * normal: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]), + * indices: new Uint16Array([0, 1, 2, 1, 2, 3]), + * }; + * + * Or AugmentedTypedArrays + * + * var positions = createAugmentedTypedArray(3, 4); + * var texcoords = createAugmentedTypedArray(2, 4); + * var normals = createAugmentedTypedArray(3, 4); + * var indices = createAugmentedTypedArray(3, 2, Uint16Array); + * + * positions.push([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]); + * texcoords.push([0, 0, 0, 1, 1, 0, 1, 1]); + * normals.push([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]); + * indices.push([0, 1, 2, 1, 2, 3]); + * + * var arrays = { + * position: positions, + * texcoord: texcoords, + * normal: normals, + * indices: indices, + * }; + * + * For the last example it is equivalent to + * + * var bufferInfo = { + * attribs: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.normal.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.normal, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferInfo.indices); + * gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, arrays.indices, gl.STATIC_DRAW); + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.Arrays} arrays Your data + * @param {module:twgl.BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {module:twgl.BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */function createBufferInfoFromArrays(gl,arrays,srcBufferInfo){var newAttribs=createAttribsFromArrays(gl,arrays);var bufferInfo=Object.assign({},srcBufferInfo?srcBufferInfo:{});bufferInfo.attribs=Object.assign({},srcBufferInfo?srcBufferInfo.attribs:{},newAttribs);var indices=arrays.indices;if(indices){var newIndices=makeTypedArray(indices,"indices");bufferInfo.indices=createBufferFromTypedArray(gl,newIndices,ELEMENT_ARRAY_BUFFER);bufferInfo.numElements=newIndices.length;bufferInfo.elementType=getGLTypeForTypedArray(newIndices);}else if(!bufferInfo.numElements){bufferInfo.numElements=getNumElementsFromAttributes(gl,bufferInfo.attribs);}return bufferInfo;}/** + * Creates a buffer from an array, typed array, or array spec + * + * Given something like this + * + * [1, 2, 3], + * + * or + * + * new Uint16Array([1,2,3]); + * + * or + * + * { + * data: [1, 2, 3], + * type: Uint8Array, + * } + * + * returns a WebGLBuffer that contains the given data. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {module:twgl.ArraySpec} array an array, typed array, or array spec. + * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise. + * @return {WebGLBuffer} a WebGLBuffer containing the data in array. + * @memberOf module:twgl/attributes + */function createBufferFromArray(gl,array,arrayName){var type=arrayName==="indices"?ELEMENT_ARRAY_BUFFER:ARRAY_BUFFER;var typedArray=makeTypedArray(array,arrayName);return createBufferFromTypedArray(gl,typedArray,type);}/** + * Creates buffers from arrays or typed arrays + * + * Given something like this + * + * var arrays = { + * positions: [1, 2, 3], + * normals: [0, 0, 1], + * } + * + * returns something like + * + * buffers = { + * positions: WebGLBuffer, + * normals: WebGLBuffer, + * } + * + * If the buffer is named 'indices' it will be made an ELEMENT_ARRAY_BUFFER. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {module:twgl.Arrays} arrays + * @return {Object} returns an object with one WebGLBuffer per array + * @memberOf module:twgl/attributes + */function createBuffersFromArrays(gl,arrays){var buffers={};Object.keys(arrays).forEach(function(key){buffers[key]=createBufferFromArray(gl,arrays[key],key);});// Ugh! +if(arrays.indices){buffers.numElements=arrays.indices.length;buffers.elementType=getGLTypeForTypedArray(makeTypedArray(arrays.indices));}else{buffers.numElements=getNumElementsFromNonIndexedArrays(arrays);}return buffers;}/* + * Copyright 2019 Gregg Tavares + * + * 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. + */var getArray$1=getArray;// eslint-disable-line +var getNumComponents$1=getNumComponents;// eslint-disable-line +/** + * @typedef {(Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array)} TypedArray + */ /** + * Add `push` to a typed array. It just keeps a 'cursor' + * and allows use to `push` values into the array so we + * don't have to manually compute offsets + * @param {TypedArray} typedArray TypedArray to augment + * @param {number} numComponents number of components. + * @private + */function augmentTypedArray(typedArray,numComponents){var cursor=0;typedArray.push=function(){for(var ii=0;ii} vertices The indexed vertices to deindex + * @return {Object.} The deindexed vertices + * @memberOf module:twgl/primitives + */function deindexVertices(vertices){var indices=vertices.indices;var newVertices={};var numElements=indices.length;function expandToUnindexed(channel){var srcBuffer=vertices[channel];var numComponents=srcBuffer.numComponents;var dstBuffer=createAugmentedTypedArray(numComponents,numElements,srcBuffer.constructor);for(var ii=0;ii} vertices The deindexed vertices who's normals to flatten + * @return {Object.} The flattened vertices (same as was passed in) + * @memberOf module:twgl/primitives + */function flattenNormals(vertices){if(vertices.indices){throw new Error('can not flatten normals of indexed vertices. deindex them first');}var normals=vertices.normal;var numNormals=normals.length;for(var ii=0;ii} arrays The vertices to reorient + * @param {module:twgl/m4.Mat4} matrix matrix to reorient by. + * @return {Object.} same arrays that were passed in. + * @memberOf module:twgl/primitives + */function reorientVertices(arrays,matrix){Object.keys(arrays).forEach(function(name){var array=arrays[name];if(name.indexOf("pos")>=0){reorientPositions(array,matrix);}else if(name.indexOf("tan")>=0||name.indexOf("binorm")>=0){reorientDirections(array,matrix);}else if(name.indexOf("norm")>=0){reorientNormals(array,matrix);}});return arrays;}/** + * Creates XY quad BufferInfo + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {Object.} the created XY Quad BufferInfo + * @memberOf module:twgl/primitives + * @function createXYQuadBuffers + */ /** + * Creates XY quad Buffers + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {module:twgl.BufferInfo} the created XY Quad buffers + * @memberOf module:twgl/primitives + * @function createXYQuadBufferInfo + */ /** + * Creates XY quad vertices + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadVertices(1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadVertices(1, 0, 0.5); + * + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {Object.} the created XY Quad vertices + * @memberOf module:twgl/primitives + */function createXYQuadVertices(size,xOffset,yOffset){size=size||2;xOffset=xOffset||0;yOffset=yOffset||0;size*=0.5;return{position:{numComponents:2,data:[xOffset+-1*size,yOffset+-1*size,xOffset+1*size,yOffset+-1*size,xOffset+-1*size,yOffset+1*size,xOffset+1*size,yOffset+1*size]},normal:[0,0,1,0,0,1,0,0,1,0,0,1],texcoord:[0,0,1,0,0,1,1,1],indices:[0,1,2,2,1,3]};}/** + * Creates XZ plane BufferInfo. + * + * The created plane has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {module:twgl.BufferInfo} The created plane BufferInfo. + * @memberOf module:twgl/primitives + * @function createPlaneBufferInfo + */ /** + * Creates XZ plane buffers. + * + * The created plane has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {Object.} The created plane buffers. + * @memberOf module:twgl/primitives + * @function createPlaneBuffers + */ /** + * Creates XZ plane vertices. + * + * The created plane has position, normal, and texcoord data + * + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {Object.} The created plane vertices. + * @memberOf module:twgl/primitives + */function createPlaneVertices(width,depth,subdivisionsWidth,subdivisionsDepth,matrix){width=width||1;depth=depth||1;subdivisionsWidth=subdivisionsWidth||1;subdivisionsDepth=subdivisionsDepth||1;matrix=matrix||identity();var numVertices=(subdivisionsWidth+1)*(subdivisionsDepth+1);var positions=createAugmentedTypedArray(3,numVertices);var normals=createAugmentedTypedArray(3,numVertices);var texcoords=createAugmentedTypedArray(2,numVertices);for(var z=0;z<=subdivisionsDepth;z++){for(var x=0;x<=subdivisionsWidth;x++){var u=x/subdivisionsWidth;var v=z/subdivisionsDepth;positions.push(width*u-width*0.5,0,depth*v-depth*0.5);normals.push(0,1,0);texcoords.push(u,v);}}var numVertsAcross=subdivisionsWidth+1;var indices=createAugmentedTypedArray(3,subdivisionsWidth*subdivisionsDepth*2,Uint16Array);for(var _z=0;_z} The created sphere buffers. + * @memberOf module:twgl/primitives + * @function createSphereBuffers + */ /** + * Creates sphere vertices. + * + * The created sphere has position, normal, and texcoord data + * + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {number} [opt_startLatitudeInRadians] where to start the + * top of the sphere. Default = 0. + * @param {number} [opt_endLatitudeInRadians] Where to end the + * bottom of the sphere. Default = Math.PI. + * @param {number} [opt_startLongitudeInRadians] where to start + * wrapping the sphere. Default = 0. + * @param {number} [opt_endLongitudeInRadians] where to end + * wrapping the sphere. Default = 2 * Math.PI. + * @return {Object.} The created sphere vertices. + * @memberOf module:twgl/primitives + */function createSphereVertices(radius,subdivisionsAxis,subdivisionsHeight,opt_startLatitudeInRadians,opt_endLatitudeInRadians,opt_startLongitudeInRadians,opt_endLongitudeInRadians){if(subdivisionsAxis<=0||subdivisionsHeight<=0){throw new Error('subdivisionAxis and subdivisionHeight must be > 0');}opt_startLatitudeInRadians=opt_startLatitudeInRadians||0;opt_endLatitudeInRadians=opt_endLatitudeInRadians||Math.PI;opt_startLongitudeInRadians=opt_startLongitudeInRadians||0;opt_endLongitudeInRadians=opt_endLongitudeInRadians||Math.PI*2;var latRange=opt_endLatitudeInRadians-opt_startLatitudeInRadians;var longRange=opt_endLongitudeInRadians-opt_startLongitudeInRadians;// We are going to generate our sphere by iterating through its +// spherical coordinates and generating 2 triangles for each quad on a +// ring of the sphere. +var numVertices=(subdivisionsAxis+1)*(subdivisionsHeight+1);var positions=createAugmentedTypedArray(3,numVertices);var normals=createAugmentedTypedArray(3,numVertices);var texcoords=createAugmentedTypedArray(2,numVertices);// Generate the individual vertices in our vertex buffer. +for(var y=0;y<=subdivisionsHeight;y++){for(var x=0;x<=subdivisionsAxis;x++){// Generate a vertex based on its spherical coordinates +var u=x/subdivisionsAxis;var v=y/subdivisionsHeight;var theta=longRange*u+opt_startLongitudeInRadians;var phi=latRange*v+opt_startLatitudeInRadians;var sinTheta=Math.sin(theta);var cosTheta=Math.cos(theta);var sinPhi=Math.sin(phi);var cosPhi=Math.cos(phi);var ux=cosTheta*sinPhi;var uy=cosPhi;var uz=sinTheta*sinPhi;positions.push(radius*ux,radius*uy,radius*uz);normals.push(ux,uy,uz);texcoords.push(1-u,v);}}var numVertsAround=subdivisionsAxis+1;var indices=createAugmentedTypedArray(3,subdivisionsAxis*subdivisionsHeight*2,Uint16Array);for(var _x2=0;_x2} + * @private + */var CUBE_FACE_INDICES=[[3,7,5,1],// right +[6,2,0,4],// left +[6,7,3,2],// ?? +[0,1,5,4],// ?? +[7,6,4,5],// front +[2,3,1,0]// back +];/** + * Creates a BufferInfo for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] width, height and depth of the cube. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCubeBufferInfo + */ /** + * Creates the buffers and indices for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] width, height and depth of the cube. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCubeBuffers + */ /** + * Creates the vertices and indices for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {number} [size] width, height and depth of the cube. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */function createCubeVertices(size){size=size||1;var k=size/2;var cornerVertices=[[-k,-k,-k],[+k,-k,-k],[-k,+k,-k],[+k,+k,-k],[-k,-k,+k],[+k,-k,+k],[-k,+k,+k],[+k,+k,+k]];var faceNormals=[[+1,+0,+0],[-1,+0,+0],[+0,+1,+0],[+0,-1,+0],[+0,+0,+1],[+0,+0,-1]];var uvCoords=[[1,0],[0,0],[0,1],[1,1]];var numVertices=6*4;var positions=createAugmentedTypedArray(3,numVertices);var normals=createAugmentedTypedArray(3,numVertices);var texcoords=createAugmentedTypedArray(2,numVertices);var indices=createAugmentedTypedArray(3,6*2,Uint16Array);for(var f=0;f<6;++f){var faceIndices=CUBE_FACE_INDICES[f];for(var v=0;v<4;++v){var position=cornerVertices[faceIndices[v]];var normal=faceNormals[f];var uv=uvCoords[v];// Each face needs all four vertices because the normals and texture +// coordinates are not all the same. +positions.push(position);normals.push(normal);texcoords.push(uv);}// Two triangles make a square face. +var offset=4*f;indices.push(offset+0,offset+1,offset+2);indices.push(offset+0,offset+2,offset+3);}return{position:positions,normal:normals,texcoord:texcoords,indices:indices};}/** + * Creates a BufferInfo for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {module:twgl.BufferInfo} The created cone BufferInfo. + * @memberOf module:twgl/primitives + * @function createTruncatedConeBufferInfo + */ /** + * Creates buffers for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created cone buffers. + * @memberOf module:twgl/primitives + * @function createTruncatedConeBuffers + */ /** + * Creates vertices for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. . + * + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created cone vertices. + * @memberOf module:twgl/primitives + */function createTruncatedConeVertices(bottomRadius,topRadius,height,radialSubdivisions,verticalSubdivisions,opt_topCap,opt_bottomCap){if(radialSubdivisions<3){throw new Error('radialSubdivisions must be 3 or greater');}if(verticalSubdivisions<1){throw new Error('verticalSubdivisions must be 1 or greater');}var topCap=opt_topCap===undefined?true:opt_topCap;var bottomCap=opt_bottomCap===undefined?true:opt_bottomCap;var extra=(topCap?2:0)+(bottomCap?2:0);var numVertices=(radialSubdivisions+1)*(verticalSubdivisions+1+extra);var positions=createAugmentedTypedArray(3,numVertices);var normals=createAugmentedTypedArray(3,numVertices);var texcoords=createAugmentedTypedArray(2,numVertices);var indices=createAugmentedTypedArray(3,radialSubdivisions*(verticalSubdivisions+extra/2)*2,Uint16Array);var vertsAroundEdge=radialSubdivisions+1;// The slant of the cone is constant across its surface +var slant=Math.atan2(bottomRadius-topRadius,height);var cosSlant=Math.cos(slant);var sinSlant=Math.sin(slant);var start=topCap?-2:0;var end=verticalSubdivisions+(bottomCap?2:0);for(var yy=start;yy<=end;++yy){var v=yy/verticalSubdivisions;var y=height*v;var ringRadius=void 0;if(yy<0){y=0;v=1;ringRadius=bottomRadius;}else if(yy>verticalSubdivisions){y=height;v=1;ringRadius=topRadius;}else{ringRadius=bottomRadius+(topRadius-bottomRadius)*(yy/verticalSubdivisions);}if(yy===-2||yy===verticalSubdivisions+2){ringRadius=0;v=0;}y-=height/2;for(var ii=0;iiverticalSubdivisions){normals.push(0,1,0);}else if(ringRadius===0.0){normals.push(0,0,0);}else{normals.push(sin*cosSlant,sinSlant,cos*cosSlant);}texcoords.push(ii/radialSubdivisions,1-v);}}for(var _yy=0;_yy} The created buffers. + * @memberOf module:twgl/primitives + * @function create3DFBuffers + */ /** + * Creates 3D 'F' vertices. + * An 'F' is useful because you can easily tell which way it is oriented. + * The created 'F' has position, normal, texcoord, and color arrays. + * + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */function create3DFVertices(){var positions=[// left column front +0,0,0,0,150,0,30,0,0,0,150,0,30,150,0,30,0,0,// top rung front +30,0,0,30,30,0,100,0,0,30,30,0,100,30,0,100,0,0,// middle rung front +30,60,0,30,90,0,67,60,0,30,90,0,67,90,0,67,60,0,// left column back +0,0,30,30,0,30,0,150,30,0,150,30,30,0,30,30,150,30,// top rung back +30,0,30,100,0,30,30,30,30,30,30,30,100,0,30,100,30,30,// middle rung back +30,60,30,67,60,30,30,90,30,30,90,30,67,60,30,67,90,30,// top +0,0,0,100,0,0,100,0,30,0,0,0,100,0,30,0,0,30,// top rung front +100,0,0,100,30,0,100,30,30,100,0,0,100,30,30,100,0,30,// under top rung +30,30,0,30,30,30,100,30,30,30,30,0,100,30,30,100,30,0,// between top rung and middle +30,30,0,30,60,30,30,30,30,30,30,0,30,60,0,30,60,30,// top of middle rung +30,60,0,67,60,30,30,60,30,30,60,0,67,60,0,67,60,30,// front of middle rung +67,60,0,67,90,30,67,60,30,67,60,0,67,90,0,67,90,30,// bottom of middle rung. +30,90,0,30,90,30,67,90,30,30,90,0,67,90,30,67,90,0,// front of bottom +30,90,0,30,150,30,30,90,30,30,90,0,30,150,0,30,150,30,// bottom +0,150,0,0,150,30,30,150,30,0,150,0,30,150,30,30,150,0,// left side +0,0,0,0,0,30,0,150,30,0,0,0,0,150,30,0,150,0];var texcoords=[// left column front +0.22,0.19,0.22,0.79,0.34,0.19,0.22,0.79,0.34,0.79,0.34,0.19,// top rung front +0.34,0.19,0.34,0.31,0.62,0.19,0.34,0.31,0.62,0.31,0.62,0.19,// middle rung front +0.34,0.43,0.34,0.55,0.49,0.43,0.34,0.55,0.49,0.55,0.49,0.43,// left column back +0,0,1,0,0,1,0,1,1,0,1,1,// top rung back +0,0,1,0,0,1,0,1,1,0,1,1,// middle rung back +0,0,1,0,0,1,0,1,1,0,1,1,// top +0,0,1,0,1,1,0,0,1,1,0,1,// top rung front +0,0,1,0,1,1,0,0,1,1,0,1,// under top rung +0,0,0,1,1,1,0,0,1,1,1,0,// between top rung and middle +0,0,1,1,0,1,0,0,1,0,1,1,// top of middle rung +0,0,1,1,0,1,0,0,1,0,1,1,// front of middle rung +0,0,1,1,0,1,0,0,1,0,1,1,// bottom of middle rung. +0,0,0,1,1,1,0,0,1,1,1,0,// front of bottom +0,0,1,1,0,1,0,0,1,0,1,1,// bottom +0,0,0,1,1,1,0,0,1,1,1,0,// left side +0,0,0,1,1,1,0,0,1,1,1,0];var normals=expandRLEData([// left column front +// top rung front +// middle rung front +18,0,0,1,// left column back +// top rung back +// middle rung back +18,0,0,-1,// top +6,0,1,0,// top rung front +6,1,0,0,// under top rung +6,0,-1,0,// between top rung and middle +6,1,0,0,// top of middle rung +6,0,1,0,// front of middle rung +6,1,0,0,// bottom of middle rung. +6,0,-1,0,// front of bottom +6,1,0,0,// bottom +6,0,-1,0,// left side +6,-1,0,0]);var colors=expandRLEData([// left column front +// top rung front +// middle rung front +18,200,70,120,// left column back +// top rung back +// middle rung back +18,80,70,200,// top +6,70,200,210,// top rung front +6,200,200,70,// under top rung +6,210,100,70,// between top rung and middle +6,210,160,70,// top of middle rung +6,70,180,210,// front of middle rung +6,100,70,210,// bottom of middle rung. +6,76,210,100,// front of bottom +6,140,210,80,// bottom +6,90,130,110,// left side +6,160,160,220],[255]);var numVerts=positions.length/3;var arrays={position:createAugmentedTypedArray(3,numVerts),texcoord:createAugmentedTypedArray(2,numVerts),normal:createAugmentedTypedArray(3,numVerts),color:createAugmentedTypedArray(4,numVerts,Uint8Array),indices:createAugmentedTypedArray(3,numVerts/3,Uint16Array)};arrays.position.push(positions);arrays.texcoord.push(texcoords);arrays.normal.push(normals);arrays.color.push(colors);for(var ii=0;ii} The created buffers. + * @memberOf module:twgl/primitives + * @function createCresentBuffers + */ /** + * Creates crescent vertices. + * + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + * @function createCresentBuffers + */ /** + * Creates crescent BufferInfo. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCrescentBufferInfo + */ /** + * Creates crescent buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCrescentBuffers + */ /** + * Creates crescent vertices. + * + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */function createCrescentVertices(verticalRadius,outerRadius,innerRadius,thickness,subdivisionsDown,startOffset,endOffset){if(subdivisionsDown<=0){throw new Error('subdivisionDown must be > 0');}startOffset=startOffset||0;endOffset=endOffset||1;var subdivisionsThick=2;var offsetRange=endOffset-startOffset;var numVertices=(subdivisionsDown+1)*2*(2+subdivisionsThick);var positions=createAugmentedTypedArray(3,numVertices);var normals=createAugmentedTypedArray(3,numVertices);var texcoords=createAugmentedTypedArray(2,numVertices);function lerp(a,b,s){return a+(b-a)*s;}function createArc(arcRadius,x,normalMult,normalAdd,uMult,uAdd){for(var z=0;z<=subdivisionsDown;z++){var uBack=x/(subdivisionsThick-1);var v=z/subdivisionsDown;var xBack=(uBack-0.5)*2;var angle=(startOffset+v*offsetRange)*Math.PI;var s=Math.sin(angle);var c=Math.cos(angle);var radius=lerp(verticalRadius,arcRadius,s);var px=xBack*thickness;var py=c*verticalRadius;var pz=s*radius;positions.push(px,py,pz);var n=add(multiply([0,s,c],normalMult),normalAdd);normals.push(n);texcoords.push(uBack*uMult+uAdd,v);}}// Generate the individual vertices in our vertex buffer. +for(var x=0;x} The created buffers. + * @memberOf module:twgl/primitives + * @function createCylinderBuffers + */ /** + * Creates cylinder vertices. The cylinder will be created around the origin + * along the y-axis. + * + * @param {number} radius Radius of cylinder. + * @param {number} height Height of cylinder. + * @param {number} radialSubdivisions The number of subdivisions around the cylinder. + * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. + * @param {boolean} [topCap] Create top cap. Default = true. + * @param {boolean} [bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */function createCylinderVertices(radius,height,radialSubdivisions,verticalSubdivisions,topCap,bottomCap){return createTruncatedConeVertices(radius,radius,height,radialSubdivisions,verticalSubdivisions,topCap,bottomCap);}/** + * Creates BufferInfo for a torus + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createTorusBufferInfo + */ /** + * Creates buffers for a torus + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createTorusBuffers + */ /** + * Creates vertices for a torus + * + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */function createTorusVertices(radius,thickness,radialSubdivisions,bodySubdivisions,startAngle,endAngle){if(radialSubdivisions<3){throw new Error('radialSubdivisions must be 3 or greater');}if(bodySubdivisions<3){throw new Error('verticalSubdivisions must be 3 or greater');}startAngle=startAngle||0;endAngle=endAngle||Math.PI*2;var range=endAngle-startAngle;var radialParts=radialSubdivisions+1;var bodyParts=bodySubdivisions+1;var numVertices=radialParts*bodyParts;var positions=createAugmentedTypedArray(3,numVertices);var normals=createAugmentedTypedArray(3,numVertices);var texcoords=createAugmentedTypedArray(2,numVertices);var indices=createAugmentedTypedArray(3,radialSubdivisions*bodySubdivisions*2,Uint16Array);for(var slice=0;slice 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createDiscBufferInfo + */ /** + * Creates disc buffers. The disc will be in the xz plane, centered at + * the origin. When creating, at least 3 divisions, or pie + * pieces, need to be specified, otherwise the triangles making + * up the disc will be degenerate. You can also specify the + * number of radial pieces `stacks`. A value of 1 for + * stacks will give you a simple disc of pie pieces. If you + * want to create an annulus you can set `innerRadius` to a + * value > 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createDiscBuffers + */ /** + * Creates disc vertices. The disc will be in the xz plane, centered at + * the origin. When creating, at least 3 divisions, or pie + * pieces, need to be specified, otherwise the triangles making + * up the disc will be degenerate. You can also specify the + * number of radial pieces `stacks`. A value of 1 for + * stacks will give you a simple disc of pie pieces. If you + * want to create an annulus you can set `innerRadius` to a + * value > 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */function createDiscVertices(radius,divisions,stacks,innerRadius,stackPower){if(divisions<3){throw new Error('divisions must be at least 3');}stacks=stacks?stacks:1;stackPower=stackPower?stackPower:1;innerRadius=innerRadius?innerRadius:0;// Note: We don't share the center vertex because that would +// mess up texture coordinates. +var numVertices=(divisions+1)*(stacks+1);var positions=createAugmentedTypedArray(3,numVertices);var normals=createAugmentedTypedArray(3,numVertices);var texcoords=createAugmentedTypedArray(2,numVertices);var indices=createAugmentedTypedArray(3,stacks*divisions*2,Uint16Array);var firstIndex=0;var radiusSpan=radius-innerRadius;var pointsPerStack=divisions+1;// Build the disk one stack at a time. +for(var stack=0;stack<=stacks;++stack){var stackRadius=innerRadius+radiusSpan*Math.pow(stack/stacks,stackPower);for(var i=0;i<=divisions;++i){var theta=2.0*Math.PI*i/divisions;var x=stackRadius*Math.cos(theta);var z=stackRadius*Math.sin(theta);positions.push(x,0,z);normals.push(0,1,0);texcoords.push(1-i/divisions,stack/stacks);if(stack>0&&i!==divisions){// a, b, c and d are the indices of the vertices of a quad. unless +// the current stack is the one closest to the center, in which case +// the vertices a and b connect to the center vertex. +var a=firstIndex+(i+1);var b=firstIndex+i;var c=firstIndex+i-pointsPerStack;var d=firstIndex+(i+1)-pointsPerStack;// Make a quad of the vertices a, b, c, d. +indices.push(a,b,c);indices.push(a,c,d);}}firstIndex+=divisions+1;}return{position:positions,normal:normals,texcoord:texcoords,indices:indices};}/** + * creates a random integer between 0 and range - 1 inclusive. + * @param {number} range + * @return {number} random value between 0 and range - 1 inclusive. + * @private + */function randInt(range){return Math.random()*range|0;}/** + * Used to supply random colors + * @callback RandomColorFunc + * @param {number} ndx index of triangle/quad if unindexed or index of vertex if indexed + * @param {number} channel 0 = red, 1 = green, 2 = blue, 3 = alpha + * @return {number} a number from 0 to 255 + * @memberOf module:twgl/primitives + */ /** + * @typedef {Object} RandomVerticesOptions + * @property {number} [vertsPerColor] Defaults to 3 for non-indexed vertices + * @property {module:twgl/primitives.RandomColorFunc} [rand] A function to generate random numbers + * @memberOf module:twgl/primitives + */ /** + * Creates an augmentedTypedArray of random vertex colors. + * If the vertices are indexed (have an indices array) then will + * just make random colors. Otherwise assumes they are triangles + * and makes one random color for every 3 vertices. + * @param {Object.} vertices Vertices as returned from one of the createXXXVertices functions. + * @param {module:twgl/primitives.RandomVerticesOptions} [options] options. + * @return {Object.} same vertices as passed in with `color` added. + * @memberOf module:twgl/primitives + */function makeRandomVertexColors(vertices,options){options=options||{};var numElements=vertices.position.numElements;var vColors=createAugmentedTypedArray(4,numElements,Uint8Array);var rand=options.rand||function(ndx,channel){return channel<3?randInt(256):255;};vertices.color=vColors;if(vertices.indices){// just make random colors if index +for(var ii=0;ii 0.0; // because as of 2016/5 Edge returns 0.96 +// This might also be the correct check but I'm assuming it's slow-ish +// return gl instanceof WebGLRenderingContext; +return!gl.texStorage2D;}/** + * Gets a string for WebGL enum + * + * Note: Several enums are the same. Without more + * context (which function) it's impossible to always + * give the correct enum. As it is, for matching values + * it gives all enums. Checking the WebGL2RenderingContext + * that means + * + * 0 = ZERO | POINT | NONE | NO_ERROR + * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT + * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB + * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING + * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING + * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING + * + * It's also not useful for bits really unless you pass in individual bits. + * In other words + * + * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT; + * twgl.glEnumToString(gl, bits); // not going to work + * + * Note that some enums only exist on extensions. If you + * want them to show up you need to pass the extension at least + * once. For example + * + * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc'); + * if (ext) { + * twgl.glEnumToString(ext, 0); // just prime the function + * + * ..later.. + * + * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT; + * console.log(twgl.glEnumToString(gl, internalFormat)); + * + * Notice I didn't have to pass the extension the second time. This means + * you can have place that generically gets an enum for texture formats for example. + * and as long as you primed the function with the extensions + * + * If you're using `twgl.addExtensionsToContext` to enable your extensions + * then twgl will automatically get the extension's enums. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object + * @param {number} value the value of the enum you want to look up. + * @return {string} enum string or hex value + * @memberOf module:twgl + * @function glEnumToString + */var glEnumToString=function(){var haveEnumsForType={};var enums={};function addEnums(gl){var type=gl.constructor.name;if(!haveEnumsForType[type]){for(var key in gl){if(typeof gl[key]==='number'){var existing=enums[gl[key]];enums[gl[key]]=existing?"".concat(existing," | ").concat(key):key;}}haveEnumsForType[type]=true;}}return function glEnumToString(gl,value){addEnums(gl);return enums[value]||"0x"+value.toString(16);};}();/* + * Copyright 2019 Gregg Tavares + * + * 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. + */var defaults$1={textureColor:new Uint8Array([128,192,255,255]),textureOptions:{},crossOrigin:undefined};var isArrayBuffer$1=isArrayBuffer;// Should we make this on demand? +var s_ctx;function getShared2DContext(){s_ctx=s_ctx||(typeof document!=='undefined'&&document.createElement?document.createElement("canvas").getContext("2d"):null);return s_ctx;}// NOTE: Chrome supports 2D canvas in a Worker (behind flag as of v64 but +// not only does Firefox NOT support it but Firefox freezes immediately +// if you try to create one instead of just returning null and continuing. +// : (global.OffscreenCanvas && (new global.OffscreenCanvas(1, 1)).getContext("2d")); // OffscreenCanvas may not support 2d +// NOTE: We can maybe remove some of the need for the 2d canvas. In WebGL2 +// we can use the various unpack settings. Otherwise we could try using +// the ability of an ImageBitmap to be cut. Unfortunately cutting an ImageBitmap +// is async and the current TWGL code expects a non-Async result though that +// might not be a problem. ImageBitmap though is not available in Edge or Safari +// as of 2018-01-02 +/* PixelFormat */var ALPHA=0x1906;var RGB=0x1907;var RGBA=0x1908;var LUMINANCE=0x1909;var LUMINANCE_ALPHA=0x190A;var DEPTH_COMPONENT=0x1902;var DEPTH_STENCIL=0x84F9;/* TextureWrapMode */ // const REPEAT = 0x2901; +// const MIRRORED_REPEAT = 0x8370; +var CLAMP_TO_EDGE=0x812f;/* TextureMagFilter */var NEAREST=0x2600;var LINEAR=0x2601;/* TextureMinFilter */ // const NEAREST_MIPMAP_NEAREST = 0x2700; +// const LINEAR_MIPMAP_NEAREST = 0x2701; +// const NEAREST_MIPMAP_LINEAR = 0x2702; +// const LINEAR_MIPMAP_LINEAR = 0x2703; +/* Texture Target */var TEXTURE_2D=0x0de1;var TEXTURE_CUBE_MAP=0x8513;var TEXTURE_3D=0x806f;var TEXTURE_2D_ARRAY=0x8c1a;/* Cubemap Targets */var TEXTURE_CUBE_MAP_POSITIVE_X=0x8515;var TEXTURE_CUBE_MAP_NEGATIVE_X=0x8516;var TEXTURE_CUBE_MAP_POSITIVE_Y=0x8517;var TEXTURE_CUBE_MAP_NEGATIVE_Y=0x8518;var TEXTURE_CUBE_MAP_POSITIVE_Z=0x8519;var TEXTURE_CUBE_MAP_NEGATIVE_Z=0x851a;/* Texture Parameters */var TEXTURE_MIN_FILTER=0x2801;var TEXTURE_MAG_FILTER=0x2800;var TEXTURE_WRAP_S=0x2802;var TEXTURE_WRAP_T=0x2803;var TEXTURE_WRAP_R=0x8072;var TEXTURE_MIN_LOD=0x813a;var TEXTURE_MAX_LOD=0x813b;var TEXTURE_BASE_LEVEL=0x813c;var TEXTURE_MAX_LEVEL=0x813d;/* Pixel store */var UNPACK_ALIGNMENT=0x0cf5;var UNPACK_ROW_LENGTH=0x0cf2;var UNPACK_IMAGE_HEIGHT=0x806e;var UNPACK_SKIP_PIXELS=0x0cf4;var UNPACK_SKIP_ROWS=0x0cf3;var UNPACK_SKIP_IMAGES=0x806d;var UNPACK_COLORSPACE_CONVERSION_WEBGL=0x9243;var UNPACK_PREMULTIPLY_ALPHA_WEBGL=0x9241;var UNPACK_FLIP_Y_WEBGL=0x9240;var R8=0x8229;var R8_SNORM=0x8F94;var R16F=0x822D;var R32F=0x822E;var R8UI=0x8232;var R8I=0x8231;var RG16UI=0x823A;var RG16I=0x8239;var RG32UI=0x823C;var RG32I=0x823B;var RG8=0x822B;var RG8_SNORM=0x8F95;var RG16F=0x822F;var RG32F=0x8230;var RG8UI=0x8238;var RG8I=0x8237;var R16UI=0x8234;var R16I=0x8233;var R32UI=0x8236;var R32I=0x8235;var RGB8=0x8051;var SRGB8=0x8C41;var RGB565=0x8D62;var RGB8_SNORM=0x8F96;var R11F_G11F_B10F=0x8C3A;var RGB9_E5=0x8C3D;var RGB16F=0x881B;var RGB32F=0x8815;var RGB8UI=0x8D7D;var RGB8I=0x8D8F;var RGB16UI=0x8D77;var RGB16I=0x8D89;var RGB32UI=0x8D71;var RGB32I=0x8D83;var RGBA8=0x8058;var SRGB8_ALPHA8=0x8C43;var RGBA8_SNORM=0x8F97;var RGB5_A1=0x8057;var RGBA4=0x8056;var RGB10_A2=0x8059;var RGBA16F=0x881A;var RGBA32F=0x8814;var RGBA8UI=0x8D7C;var RGBA8I=0x8D8E;var RGB10_A2UI=0x906F;var RGBA16UI=0x8D76;var RGBA16I=0x8D88;var RGBA32I=0x8D82;var RGBA32UI=0x8D70;var DEPTH_COMPONENT16=0x81A5;var DEPTH_COMPONENT24=0x81A6;var DEPTH_COMPONENT32F=0x8CAC;var DEPTH32F_STENCIL8=0x8CAD;var DEPTH24_STENCIL8=0x88F0;/* DataType */var BYTE$2=0x1400;var UNSIGNED_BYTE$2=0x1401;var SHORT$2=0x1402;var UNSIGNED_SHORT$2=0x1403;var INT$2=0x1404;var UNSIGNED_INT$2=0x1405;var FLOAT$2=0x1406;var UNSIGNED_SHORT_4_4_4_4$1=0x8033;var UNSIGNED_SHORT_5_5_5_1$1=0x8034;var UNSIGNED_SHORT_5_6_5$1=0x8363;var HALF_FLOAT$1=0x140B;var HALF_FLOAT_OES=0x8D61;// Thanks Khronos for making this different >:( +var UNSIGNED_INT_2_10_10_10_REV$1=0x8368;var UNSIGNED_INT_10F_11F_11F_REV$1=0x8C3B;var UNSIGNED_INT_5_9_9_9_REV$1=0x8C3E;var FLOAT_32_UNSIGNED_INT_24_8_REV$1=0x8DAD;var UNSIGNED_INT_24_8$1=0x84FA;var RG=0x8227;var RG_INTEGER=0x8228;var RED=0x1903;var RED_INTEGER=0x8D94;var RGB_INTEGER=0x8D98;var RGBA_INTEGER=0x8D99;var formatInfo={};{// NOTE: this is named `numColorComponents` vs `numComponents` so we can let Uglify mangle +// the name. +var f=formatInfo;f[ALPHA]={numColorComponents:1};f[LUMINANCE]={numColorComponents:1};f[LUMINANCE_ALPHA]={numColorComponents:2};f[RGB]={numColorComponents:3};f[RGBA]={numColorComponents:4};f[RED]={numColorComponents:1};f[RED_INTEGER]={numColorComponents:1};f[RG]={numColorComponents:2};f[RG_INTEGER]={numColorComponents:2};f[RGB]={numColorComponents:3};f[RGB_INTEGER]={numColorComponents:3};f[RGBA]={numColorComponents:4};f[RGBA_INTEGER]={numColorComponents:4};f[DEPTH_COMPONENT]={numColorComponents:1};f[DEPTH_STENCIL]={numColorComponents:2};}/** + * @typedef {Object} TextureFormatDetails + * @property {number} textureFormat format to pass texImage2D and similar functions. + * @property {boolean} colorRenderable true if you can render to this format of texture. + * @property {boolean} textureFilterable true if you can filter the texture, false if you can ony use `NEAREST`. + * @property {number[]} type Array of possible types you can pass to texImage2D and similar function + * @property {Object.} bytesPerElementMap A map of types to bytes per element + * @private + */var s_textureInternalFormatInfo;function getTextureInternalFormatInfo(internalFormat){if(!s_textureInternalFormatInfo){// NOTE: these properties need unique names so we can let Uglify mangle the name. +var t={};// unsized formats +t[ALPHA]={textureFormat:ALPHA,colorRenderable:true,textureFilterable:true,bytesPerElement:[1,2,2,4],type:[UNSIGNED_BYTE$2,HALF_FLOAT$1,HALF_FLOAT_OES,FLOAT$2]};t[LUMINANCE]={textureFormat:LUMINANCE,colorRenderable:true,textureFilterable:true,bytesPerElement:[1,2,2,4],type:[UNSIGNED_BYTE$2,HALF_FLOAT$1,HALF_FLOAT_OES,FLOAT$2]};t[LUMINANCE_ALPHA]={textureFormat:LUMINANCE_ALPHA,colorRenderable:true,textureFilterable:true,bytesPerElement:[2,4,4,8],type:[UNSIGNED_BYTE$2,HALF_FLOAT$1,HALF_FLOAT_OES,FLOAT$2]};t[RGB]={textureFormat:RGB,colorRenderable:true,textureFilterable:true,bytesPerElement:[3,6,6,12,2],type:[UNSIGNED_BYTE$2,HALF_FLOAT$1,HALF_FLOAT_OES,FLOAT$2,UNSIGNED_SHORT_5_6_5$1]};t[RGBA]={textureFormat:RGBA,colorRenderable:true,textureFilterable:true,bytesPerElement:[4,8,8,16,2,2],type:[UNSIGNED_BYTE$2,HALF_FLOAT$1,HALF_FLOAT_OES,FLOAT$2,UNSIGNED_SHORT_4_4_4_4$1,UNSIGNED_SHORT_5_5_5_1$1]};// sized formats +t[R8]={textureFormat:RED,colorRenderable:true,textureFilterable:true,bytesPerElement:[1],type:[UNSIGNED_BYTE$2]};t[R8_SNORM]={textureFormat:RED,colorRenderable:false,textureFilterable:true,bytesPerElement:[1],type:[BYTE$2]};t[R16F]={textureFormat:RED,colorRenderable:false,textureFilterable:true,bytesPerElement:[4,2],type:[FLOAT$2,HALF_FLOAT$1]};t[R32F]={textureFormat:RED,colorRenderable:false,textureFilterable:false,bytesPerElement:[4],type:[FLOAT$2]};t[R8UI]={textureFormat:RED_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[1],type:[UNSIGNED_BYTE$2]};t[R8I]={textureFormat:RED_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[1],type:[BYTE$2]};t[R16UI]={textureFormat:RED_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[2],type:[UNSIGNED_SHORT$2]};t[R16I]={textureFormat:RED_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[2],type:[SHORT$2]};t[R32UI]={textureFormat:RED_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[4],type:[UNSIGNED_INT$2]};t[R32I]={textureFormat:RED_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[4],type:[INT$2]};t[RG8]={textureFormat:RG,colorRenderable:true,textureFilterable:true,bytesPerElement:[2],type:[UNSIGNED_BYTE$2]};t[RG8_SNORM]={textureFormat:RG,colorRenderable:false,textureFilterable:true,bytesPerElement:[2],type:[BYTE$2]};t[RG16F]={textureFormat:RG,colorRenderable:false,textureFilterable:true,bytesPerElement:[8,4],type:[FLOAT$2,HALF_FLOAT$1]};t[RG32F]={textureFormat:RG,colorRenderable:false,textureFilterable:false,bytesPerElement:[8],type:[FLOAT$2]};t[RG8UI]={textureFormat:RG_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[2],type:[UNSIGNED_BYTE$2]};t[RG8I]={textureFormat:RG_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[2],type:[BYTE$2]};t[RG16UI]={textureFormat:RG_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[4],type:[UNSIGNED_SHORT$2]};t[RG16I]={textureFormat:RG_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[4],type:[SHORT$2]};t[RG32UI]={textureFormat:RG_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[8],type:[UNSIGNED_INT$2]};t[RG32I]={textureFormat:RG_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[8],type:[INT$2]};t[RGB8]={textureFormat:RGB,colorRenderable:true,textureFilterable:true,bytesPerElement:[3],type:[UNSIGNED_BYTE$2]};t[SRGB8]={textureFormat:RGB,colorRenderable:false,textureFilterable:true,bytesPerElement:[3],type:[UNSIGNED_BYTE$2]};t[RGB565]={textureFormat:RGB,colorRenderable:true,textureFilterable:true,bytesPerElement:[3,2],type:[UNSIGNED_BYTE$2,UNSIGNED_SHORT_5_6_5$1]};t[RGB8_SNORM]={textureFormat:RGB,colorRenderable:false,textureFilterable:true,bytesPerElement:[3],type:[BYTE$2]};t[R11F_G11F_B10F]={textureFormat:RGB,colorRenderable:false,textureFilterable:true,bytesPerElement:[12,6,4],type:[FLOAT$2,HALF_FLOAT$1,UNSIGNED_INT_10F_11F_11F_REV$1]};t[RGB9_E5]={textureFormat:RGB,colorRenderable:false,textureFilterable:true,bytesPerElement:[12,6,4],type:[FLOAT$2,HALF_FLOAT$1,UNSIGNED_INT_5_9_9_9_REV$1]};t[RGB16F]={textureFormat:RGB,colorRenderable:false,textureFilterable:true,bytesPerElement:[12,6],type:[FLOAT$2,HALF_FLOAT$1]};t[RGB32F]={textureFormat:RGB,colorRenderable:false,textureFilterable:false,bytesPerElement:[12],type:[FLOAT$2]};t[RGB8UI]={textureFormat:RGB_INTEGER,colorRenderable:false,textureFilterable:false,bytesPerElement:[3],type:[UNSIGNED_BYTE$2]};t[RGB8I]={textureFormat:RGB_INTEGER,colorRenderable:false,textureFilterable:false,bytesPerElement:[3],type:[BYTE$2]};t[RGB16UI]={textureFormat:RGB_INTEGER,colorRenderable:false,textureFilterable:false,bytesPerElement:[6],type:[UNSIGNED_SHORT$2]};t[RGB16I]={textureFormat:RGB_INTEGER,colorRenderable:false,textureFilterable:false,bytesPerElement:[6],type:[SHORT$2]};t[RGB32UI]={textureFormat:RGB_INTEGER,colorRenderable:false,textureFilterable:false,bytesPerElement:[12],type:[UNSIGNED_INT$2]};t[RGB32I]={textureFormat:RGB_INTEGER,colorRenderable:false,textureFilterable:false,bytesPerElement:[12],type:[INT$2]};t[RGBA8]={textureFormat:RGBA,colorRenderable:true,textureFilterable:true,bytesPerElement:[4],type:[UNSIGNED_BYTE$2]};t[SRGB8_ALPHA8]={textureFormat:RGBA,colorRenderable:true,textureFilterable:true,bytesPerElement:[4],type:[UNSIGNED_BYTE$2]};t[RGBA8_SNORM]={textureFormat:RGBA,colorRenderable:false,textureFilterable:true,bytesPerElement:[4],type:[BYTE$2]};t[RGB5_A1]={textureFormat:RGBA,colorRenderable:true,textureFilterable:true,bytesPerElement:[4,2,4],type:[UNSIGNED_BYTE$2,UNSIGNED_SHORT_5_5_5_1$1,UNSIGNED_INT_2_10_10_10_REV$1]};t[RGBA4]={textureFormat:RGBA,colorRenderable:true,textureFilterable:true,bytesPerElement:[4,2],type:[UNSIGNED_BYTE$2,UNSIGNED_SHORT_4_4_4_4$1]};t[RGB10_A2]={textureFormat:RGBA,colorRenderable:true,textureFilterable:true,bytesPerElement:[4],type:[UNSIGNED_INT_2_10_10_10_REV$1]};t[RGBA16F]={textureFormat:RGBA,colorRenderable:false,textureFilterable:true,bytesPerElement:[16,8],type:[FLOAT$2,HALF_FLOAT$1]};t[RGBA32F]={textureFormat:RGBA,colorRenderable:false,textureFilterable:false,bytesPerElement:[16],type:[FLOAT$2]};t[RGBA8UI]={textureFormat:RGBA_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[4],type:[UNSIGNED_BYTE$2]};t[RGBA8I]={textureFormat:RGBA_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[4],type:[BYTE$2]};t[RGB10_A2UI]={textureFormat:RGBA_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[4],type:[UNSIGNED_INT_2_10_10_10_REV$1]};t[RGBA16UI]={textureFormat:RGBA_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[8],type:[UNSIGNED_SHORT$2]};t[RGBA16I]={textureFormat:RGBA_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[8],type:[SHORT$2]};t[RGBA32I]={textureFormat:RGBA_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[16],type:[INT$2]};t[RGBA32UI]={textureFormat:RGBA_INTEGER,colorRenderable:true,textureFilterable:false,bytesPerElement:[16],type:[UNSIGNED_INT$2]};// Sized Internal +t[DEPTH_COMPONENT16]={textureFormat:DEPTH_COMPONENT,colorRenderable:true,textureFilterable:false,bytesPerElement:[2,4],type:[UNSIGNED_SHORT$2,UNSIGNED_INT$2]};t[DEPTH_COMPONENT24]={textureFormat:DEPTH_COMPONENT,colorRenderable:true,textureFilterable:false,bytesPerElement:[4],type:[UNSIGNED_INT$2]};t[DEPTH_COMPONENT32F]={textureFormat:DEPTH_COMPONENT,colorRenderable:true,textureFilterable:false,bytesPerElement:[4],type:[FLOAT$2]};t[DEPTH24_STENCIL8]={textureFormat:DEPTH_STENCIL,colorRenderable:true,textureFilterable:false,bytesPerElement:[4],type:[UNSIGNED_INT_24_8$1]};t[DEPTH32F_STENCIL8]={textureFormat:DEPTH_STENCIL,colorRenderable:true,textureFilterable:false,bytesPerElement:[4],type:[FLOAT_32_UNSIGNED_INT_24_8_REV$1]};Object.keys(t).forEach(function(internalFormat){var info=t[internalFormat];info.bytesPerElementMap={};info.bytesPerElement.forEach(function(bytesPerElement,ndx){var type=info.type[ndx];info.bytesPerElementMap[type]=bytesPerElement;});});s_textureInternalFormatInfo=t;}return s_textureInternalFormatInfo[internalFormat];}/** + * Gets the number of bytes per element for a given internalFormat / type + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @param {number} type The type parameter for texImage2D etc.. + * @return {number} the number of bytes per element for the given internalFormat, type combo + * @memberOf module:twgl/textures + */function getBytesPerElementForInternalFormat(internalFormat,type){var info=getTextureInternalFormatInfo(internalFormat);if(!info){throw"unknown internal format";}var bytesPerElement=info.bytesPerElementMap[type];if(bytesPerElement===undefined){throw"unknown internal format";}return bytesPerElement;}/** + * Info related to a specific texture internalFormat as returned + * from {@link module:twgl/textures.getFormatAndTypeForInternalFormat}. + * + * @typedef {Object} TextureFormatInfo + * @property {number} format Format to pass to texImage2D and related functions + * @property {number} type Type to pass to texImage2D and related functions + * @memberOf module:twgl/textures + */ /** + * Gets the format and type for a given internalFormat + * + * @param {number} internalFormat The internal format + * @return {module:twgl/textures.TextureFormatInfo} the corresponding format and type, + * @memberOf module:twgl/textures + */function getFormatAndTypeForInternalFormat(internalFormat){var info=getTextureInternalFormatInfo(internalFormat);if(!info){throw"unknown internal format";}return{format:info.textureFormat,type:info.type[0]};}/** + * Returns true if value is power of 2 + * @param {number} value number to check. + * @return true if value is power of 2 + * @private + */function isPowerOf2(value){return(value&value-1)===0;}/** + * Gets whether or not we can generate mips for the given + * internal format. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number} width The width parameter from texImage2D etc.. + * @param {number} height The height parameter from texImage2D etc.. + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */function canGenerateMipmap(gl,width,height,internalFormat){if(!isWebGL2(gl)){return isPowerOf2(width)&&isPowerOf2(height);}var info=getTextureInternalFormatInfo(internalFormat);if(!info){throw"unknown internal format";}return info.colorRenderable&&info.textureFilterable;}/** + * Gets whether or not we can generate mips for the given format + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */function canFilter(internalFormat){var info=getTextureInternalFormatInfo(internalFormat);if(!info){throw"unknown internal format";}return info.textureFilterable;}/** + * Gets the texture type for a given array type. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @return {number} the gl texture type + * @private + */function getTextureTypeForArrayType(gl,src,defaultType){if(isArrayBuffer$1(src)){return getGLTypeForTypedArray(src);}return defaultType||UNSIGNED_BYTE$2;}function guessDimensions(gl,target,width,height,numElements){if(numElements%1!==0){throw"can't guess dimensions";}if(!width&&!height){var size=Math.sqrt(numElements/(target===TEXTURE_CUBE_MAP?6:1));if(size%1===0){width=size;height=size;}else{width=numElements;height=1;}}else if(!height){height=numElements/width;if(height%1){throw"can't guess dimensions";}}else if(!width){width=numElements/height;if(width%1){throw"can't guess dimensions";}}return{width:width,height:height};}/** + * A function to generate the source for a texture. + * @callback TextureFunc + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.TextureOptions} options the texture options + * @return {*} Returns any of the things documented for `src` for {@link module:twgl.TextureOptions}. + * @memberOf module:twgl + */ /** + * Texture options passed to most texture functions. Each function will use whatever options + * are appropriate for its needs. This lets you pass the same options to all functions. + * + * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`, + * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`. + * + * @typedef {Object} TextureOptions + * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`. + * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true. + * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null. + * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null. + * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` . + * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR` + * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`. + * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR` + * @property {number} [minMag] both the min and mag filter settings. + * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA` + * @property {number} [format] format for texture. Defaults to `gl.RGBA`. + * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src` + * is ArrayBufferView defaults to type that matches ArrayBufferView type. + * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube + * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [minLod] TEXTURE_MIN_LOD setting + * @property {number} [maxLod] TEXTURE_MAX_LOD setting + * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting + * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting + * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1. + * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously. + * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults` + * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink + * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and + * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above + * then then `auto` is assumed to be `false` unless explicity set to `true`. + * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is + * + * [gl.TEXTURE_CUBE_MAP_POSITIVE_X, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_X, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Y, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Z, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] + * + * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|module:twgl.TextureFunc)} [src] source for texture + * + * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable + * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded. + * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3. + * The pieces will be uploaded in `cubeFaceOrder` + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map. + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture + * and will be scaled to the specified width and height OR to the size of the first image that loads. + * + * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`, + * `HTMLCanvasElement`, `HTMLVideoElement`. + * + * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is + * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents` + * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided + * by 6. Then + * + * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height + * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`. + * + * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`. + * + * If `number[]` will be converted to `type`. + * + * If `src` is a function it will be called with a `WebGLRenderingContext` and these options. + * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement` + * an array etc... + * + * If `src` is undefined then an empty texture will be created of size `width` by `height`. + * + * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded. + * default: undefined. Also see {@link module:twgl.setDefaults}. + * + * @memberOf module:twgl + */ // NOTE: While querying GL is considered slow it's not remotely as slow +// as uploading a texture. On top of that you're unlikely to call this in +// a perf critical loop. Even if upload a texture every frame that's unlikely +// to be more than 1 or 2 textures a frame. In other words, the benefits of +// making the API easy to use outweigh any supposed perf benefits +// +// Also note I get that having one global of these is bad practice. +// As long as it's used correctly it means no garbage which probably +// doesn't matter when dealing with textures but old habits die hard. +var lastPackState={};/** + * Saves any packing state that will be set based on the options. + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @private + */function savePackState(gl,options){if(options.colorspaceConversion!==undefined){lastPackState.colorspaceConversion=gl.getParameter(UNPACK_COLORSPACE_CONVERSION_WEBGL);gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL,options.colorspaceConversion);}if(options.premultiplyAlpha!==undefined){lastPackState.premultiplyAlpha=gl.getParameter(UNPACK_PREMULTIPLY_ALPHA_WEBGL);gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL,options.premultiplyAlpha);}if(options.flipY!==undefined){lastPackState.flipY=gl.getParameter(UNPACK_FLIP_Y_WEBGL);gl.pixelStorei(UNPACK_FLIP_Y_WEBGL,options.flipY);}}/** + * Restores any packing state that was set based on the options. + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @private + */function restorePackState(gl,options){if(options.colorspaceConversion!==undefined){gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL,lastPackState.colorspaceConversion);}if(options.premultiplyAlpha!==undefined){gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL,lastPackState.premultiplyAlpha);}if(options.flipY!==undefined){gl.pixelStorei(UNPACK_FLIP_Y_WEBGL,lastPackState.flipY);}}/** + * Saves state related to data size + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @private + */function saveSkipState(gl){lastPackState.unpackAlignment=gl.getParameter(UNPACK_ALIGNMENT);if(isWebGL2(gl)){lastPackState.unpackRowLength=gl.getParameter(UNPACK_ROW_LENGTH);lastPackState.unpackImageHeight=gl.getParameter(UNPACK_IMAGE_HEIGHT);lastPackState.unpackSkipPixels=gl.getParameter(UNPACK_SKIP_PIXELS);lastPackState.unpackSkipRows=gl.getParameter(UNPACK_SKIP_ROWS);lastPackState.unpackSkipImages=gl.getParameter(UNPACK_SKIP_IMAGES);}}/** + * Restores state related to data size + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @private + */function restoreSkipState(gl){gl.pixelStorei(UNPACK_ALIGNMENT,lastPackState.unpackAlignment);if(isWebGL2(gl)){gl.pixelStorei(UNPACK_ROW_LENGTH,lastPackState.unpackRowLength);gl.pixelStorei(UNPACK_IMAGE_HEIGHT,lastPackState.unpackImageHeight);gl.pixelStorei(UNPACK_SKIP_PIXELS,lastPackState.unpackSkipPixels);gl.pixelStorei(UNPACK_SKIP_ROWS,lastPackState.unpackSkipRows);gl.pixelStorei(UNPACK_SKIP_IMAGES,lastPackState.unpackSkipImages);}}/** + * Sets the parameters of a texture or sampler + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number|WebGLSampler} target texture target or sampler + * @param {function()} parameteriFn texParameteri or samplerParameteri fn + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @private + */function setTextureSamplerParameters(gl,target,parameteriFn,options){if(options.minMag){parameteriFn.call(gl,target,TEXTURE_MIN_FILTER,options.minMag);parameteriFn.call(gl,target,TEXTURE_MAG_FILTER,options.minMag);}if(options.min){parameteriFn.call(gl,target,TEXTURE_MIN_FILTER,options.min);}if(options.mag){parameteriFn.call(gl,target,TEXTURE_MAG_FILTER,options.mag);}if(options.wrap){parameteriFn.call(gl,target,TEXTURE_WRAP_S,options.wrap);parameteriFn.call(gl,target,TEXTURE_WRAP_T,options.wrap);if(target===TEXTURE_3D||isSampler(gl,target)){parameteriFn.call(gl,target,TEXTURE_WRAP_R,options.wrap);}}if(options.wrapR){parameteriFn.call(gl,target,TEXTURE_WRAP_R,options.wrapR);}if(options.wrapS){parameteriFn.call(gl,target,TEXTURE_WRAP_S,options.wrapS);}if(options.wrapT){parameteriFn.call(gl,target,TEXTURE_WRAP_T,options.wrapT);}if(options.minLod){parameteriFn.call(gl,target,TEXTURE_MIN_LOD,options.minLod);}if(options.maxLod){parameteriFn.call(gl,target,TEXTURE_MAX_LOD,options.maxLod);}if(options.baseLevel){parameteriFn.call(gl,target,TEXTURE_BASE_LEVEL,options.baseLevel);}if(options.maxLevel){parameteriFn.call(gl,target,TEXTURE_MAX_LEVEL,options.maxLevel);}}/** + * Sets the texture parameters of a texture. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */function setTextureParameters(gl,tex,options){var target=options.target||TEXTURE_2D;gl.bindTexture(target,tex);setTextureSamplerParameters(gl,target,gl.texParameteri,options);}/** + * Makes a 1x1 pixel + * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`. + * @param {(number[]|ArrayBufferView)} [color] The color using 0-1 values + * @return {Uint8Array} Unit8Array with color. + * @private + */function make1Pixel(color){color=color||defaults$1.textureColor;if(isArrayBuffer$1(color)){return color;}return new Uint8Array([color[0]*255,color[1]*255,color[2]*255,color[3]*255]);}/** + * Sets filtering or generates mips for texture based on width or height + * If width or height is not passed in uses `options.width` and//or `options.height` + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @param {number} [width] width of texture + * @param {number} [height] height of texture + * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc.. + * @memberOf module:twgl/textures + */function setTextureFilteringForSize(gl,tex,options,width,height,internalFormat){options=options||defaults$1.textureOptions;internalFormat=internalFormat||RGBA;var target=options.target||TEXTURE_2D;width=width||options.width;height=height||options.height;gl.bindTexture(target,tex);if(canGenerateMipmap(gl,width,height,internalFormat)){gl.generateMipmap(target);}else{var filtering=canFilter(internalFormat)?LINEAR:NEAREST;gl.texParameteri(target,TEXTURE_MIN_FILTER,filtering);gl.texParameteri(target,TEXTURE_MAG_FILTER,filtering);gl.texParameteri(target,TEXTURE_WRAP_S,CLAMP_TO_EDGE);gl.texParameteri(target,TEXTURE_WRAP_T,CLAMP_TO_EDGE);}}function shouldAutomaticallySetTextureFilteringForSize(options){return options.auto===true||options.auto===undefined&&options.level===undefined;}/** + * Gets an array of cubemap face enums + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @return {number[]} cubemap face enums + * @private + */function getCubeFaceOrder(gl,options){options=options||{};return options.cubeFaceOrder||[TEXTURE_CUBE_MAP_POSITIVE_X,TEXTURE_CUBE_MAP_NEGATIVE_X,TEXTURE_CUBE_MAP_POSITIVE_Y,TEXTURE_CUBE_MAP_NEGATIVE_Y,TEXTURE_CUBE_MAP_POSITIVE_Z,TEXTURE_CUBE_MAP_NEGATIVE_Z];}/** + * @typedef {Object} FaceInfo + * @property {number} face gl enum for texImage2D + * @property {number} ndx face index (0 - 5) into source data + * @ignore + */ /** + * Gets an array of FaceInfos + * There's a bug in some NVidia drivers that will crash the driver if + * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take + * the user's desired order from his faces to WebGL and make sure we + * do the faces in WebGL order + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundant but + * it's needed internally to sort the array of `ndx` properties by `face`. + * @private + */function getCubeFacesWithNdx(gl,options){var faces=getCubeFaceOrder(gl,options);// work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :( +var facesWithNdx=faces.map(function(face,ndx){return{face:face,ndx:ndx};});facesWithNdx.sort(function(a,b){return a.face-b.face;});return facesWithNdx;}/** + * Set a texture from the contents of an element. Will also set + * texture filtering or generate mips based on the dimensions of the element + * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will + * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {HTMLElement} element a canvas, img, or video element. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @kind function + */function setTextureFromElement(gl,tex,element,options){options=options||defaults$1.textureOptions;var target=options.target||TEXTURE_2D;var level=options.level||0;var width=element.width;var height=element.height;var internalFormat=options.internalFormat||options.format||RGBA;var formatType=getFormatAndTypeForInternalFormat(internalFormat);var format=options.format||formatType.format;var type=options.type||formatType.type;savePackState(gl,options);gl.bindTexture(target,tex);if(target===TEXTURE_CUBE_MAP){// guess the parts +var imgWidth=element.width;var imgHeight=element.height;var size;var slices;if(imgWidth/6===imgHeight){// It's 6x1 +size=imgHeight;slices=[0,0,1,0,2,0,3,0,4,0,5,0];}else if(imgHeight/6===imgWidth){// It's 1x6 +size=imgWidth;slices=[0,0,0,1,0,2,0,3,0,4,0,5];}else if(imgWidth/3===imgHeight/2){// It's 3x2 +size=imgWidth/3;slices=[0,0,1,0,2,0,0,1,1,1,2,1];}else if(imgWidth/2===imgHeight/3){// It's 2x3 +size=imgWidth/2;slices=[0,0,1,0,0,1,1,1,0,2,1,2];}else{throw"can't figure out cube map from element: "+(element.src?element.src:element.nodeName);}var ctx=getShared2DContext();if(ctx){ctx.canvas.width=size;ctx.canvas.height=size;width=size;height=size;getCubeFacesWithNdx(gl,options).forEach(function(f){var xOffset=slices[f.ndx*2+0]*size;var yOffset=slices[f.ndx*2+1]*size;ctx.drawImage(element,xOffset,yOffset,size,size,0,0,size,size);gl.texImage2D(f.face,level,internalFormat,format,type,ctx.canvas);});// Free up the canvas memory +ctx.canvas.width=1;ctx.canvas.height=1;}else if(typeof createImageBitmap!=='undefined'){// NOTE: It seems like we should prefer ImageBitmap because unlike canvas it's +// note lossy? (alpha is not premultiplied? although I'm not sure what +width=size;height=size;getCubeFacesWithNdx(gl,options).forEach(function(f){var xOffset=slices[f.ndx*2+0]*size;var yOffset=slices[f.ndx*2+1]*size;// We can't easily use a default texture color here as it would have to match +// the type across all faces where as with a 2D one there's only one face +// so we're replacing everything all at once. It also has to be the correct size. +// On the other hand we need all faces to be the same size so as one face loads +// the rest match else the texture will be un-renderable. +gl.texImage2D(f.face,level,internalFormat,size,size,0,format,type,null);createImageBitmap(element,xOffset,yOffset,size,size,{premultiplyAlpha:'none',colorSpaceConversion:'none'}).then(function(imageBitmap){savePackState(gl,options);gl.bindTexture(target,tex);gl.texImage2D(f.face,level,internalFormat,format,type,imageBitmap);restorePackState(gl,options);if(shouldAutomaticallySetTextureFilteringForSize(options)){setTextureFilteringForSize(gl,tex,options,width,height,internalFormat);}});});}}else if(target===TEXTURE_3D||target===TEXTURE_2D_ARRAY){var smallest=Math.min(element.width,element.height);var largest=Math.max(element.width,element.height);var depth=largest/smallest;if(depth%1!==0){throw"can not compute 3D dimensions of element";}var xMult=element.width===largest?1:0;var yMult=element.height===largest?1:0;saveSkipState(gl);gl.pixelStorei(UNPACK_ALIGNMENT,1);gl.pixelStorei(UNPACK_ROW_LENGTH,element.width);gl.pixelStorei(UNPACK_IMAGE_HEIGHT,0);gl.pixelStorei(UNPACK_SKIP_IMAGES,0);gl.texImage3D(target,level,internalFormat,smallest,smallest,smallest,0,format,type,null);for(var d=0;d} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}. + * @param {Object.} sources the image(s) used for the texture by name. + * @memberOf module:twgl + */ /** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback CubemapReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each face. + * @memberOf module:twgl + */ /** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback ThreeDReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each slice. + * @memberOf module:twgl + */ /** + * Loads a texture from an image from a Url as specified in `options.src` + * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is + * immediately useable. It will be updated with the contents of the image once the image has finished + * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will + * be non null if there was an error. + * @return {HTMLImageElement} the image being downloaded. + * @memberOf module:twgl/textures + */function loadTextureFromUrl(gl,tex,options,callback){callback=callback||noop;options=options||defaults$1.textureOptions;setTextureTo1PixelColor(gl,tex,options);// Because it's async we need to copy the options. +options=Object.assign({},options);var img=loadAndUseImage(options.src,options.crossOrigin,function(err,img){if(err){callback(err,tex,img);}else{setTextureFromElement(gl,tex,img,options);callback(null,tex,img);}});return img;}/** + * Loads a cubemap from 6 urls or TexImageSources as specified in `options.src`. Will set the cubemap to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + */function loadCubemapFromUrls(gl,tex,options,callback){callback=callback||noop;var urls=options.src;if(urls.length!==6){throw"there must be 6 urls for a cubemap";}var level=options.level||0;var internalFormat=options.internalFormat||options.format||RGBA;var formatType=getFormatAndTypeForInternalFormat(internalFormat);var format=options.format||formatType.format;var type=options.type||UNSIGNED_BYTE$2;var target=options.target||TEXTURE_2D;if(target!==TEXTURE_CUBE_MAP){throw"target must be TEXTURE_CUBE_MAP";}setTextureTo1PixelColor(gl,tex,options);// Because it's async we need to copy the options. +options=Object.assign({},options);var numToLoad=6;var errors=[];var faces=getCubeFaceOrder(gl,options);var imgs;// eslint-disable-line +function uploadImg(faceTarget){return function(err,img){--numToLoad;if(err){errors.push(err);}else{if(img.width!==img.height){errors.push("cubemap face img is not a square: "+img.src);}else{savePackState(gl,options);gl.bindTexture(target,tex);// So assuming this is the first image we now have one face that's img sized +// and 5 faces that are 1x1 pixel so size the other faces +if(numToLoad===5){// use the default order +getCubeFaceOrder().forEach(function(otherTarget){// Should we re-use the same face or a color? +gl.texImage2D(otherTarget,level,internalFormat,format,type,img);});}else{gl.texImage2D(faceTarget,level,internalFormat,format,type,img);}restorePackState(gl,options);if(shouldAutomaticallySetTextureFilteringForSize(options)){gl.generateMipmap(target);}}}if(numToLoad===0){callback(errors.length?errors:undefined,tex,imgs);}};}imgs=urls.map(function(url,ndx){return loadAndUseImage(url,options.crossOrigin,uploadImg(faces[ndx]));});}/** + * Loads a 2d array or 3d texture from urls OR TexImageSources as specified in `options.src`. + * Will set the texture to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * + * If the width and height is not specified the width and height of the first + * image loaded will be used. Note that since images are loaded async + * which image downloads first is unknown. + * + * If an image is not the same size as the width and height it will be scaled + * to that width and height. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.ThreeDReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + */function loadSlicesFromUrls(gl,tex,options,callback){callback=callback||noop;var urls=options.src;var internalFormat=options.internalFormat||options.format||RGBA;var formatType=getFormatAndTypeForInternalFormat(internalFormat);var format=options.format||formatType.format;var type=options.type||UNSIGNED_BYTE$2;var target=options.target||TEXTURE_2D_ARRAY;if(target!==TEXTURE_3D&&target!==TEXTURE_2D_ARRAY){throw"target must be TEXTURE_3D or TEXTURE_2D_ARRAY";}setTextureTo1PixelColor(gl,tex,options);// Because it's async we need to copy the options. +options=Object.assign({},options);var numToLoad=urls.length;var errors=[];var imgs;// eslint-disable-line +var level=options.level||0;var width=options.width;var height=options.height;var depth=urls.length;var firstImage=true;function uploadImg(slice){return function(err,img){--numToLoad;if(err){errors.push(err);}else{savePackState(gl,options);gl.bindTexture(target,tex);if(firstImage){firstImage=false;width=options.width||img.width;height=options.height||img.height;gl.texImage3D(target,level,internalFormat,width,height,depth,0,format,type,null);// put it in every slice otherwise some slices will be 0,0,0,0 +for(var s=0;s +// #version 300 es +// +// +// Has one line before it which is invalid according to GLSL ES 3.00 +// +var lineOffset=0;if(spaceRE.test(shaderSource)){lineOffset=1;shaderSource=shaderSource.replace(spaceRE,'');}// Load the shader source +gl.shaderSource(shader,shaderSource);// Compile the shader +gl.compileShader(shader);// Check the compile status +var compiled=gl.getShaderParameter(shader,COMPILE_STATUS);if(!compiled){// Something went wrong during compilation; get the error +var lastError=gl.getShaderInfoLog(shader);errFn(addLineNumbers(shaderSource,lineOffset)+"\n*** Error compiling shader: "+lastError);gl.deleteShader(shader);return null;}return shader;}/** + * @typedef {Object} ProgramOptions + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.} [attribLocations] a attribute name to location map + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @memberOf module:twgl + */ /** + * Gets the program options based on all these optional arguments + * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or an array of attribs names. Locations will be assigned by index if not passed in + * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations. + * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console + * on error. If you want something else pass an callback. It's passed an error message. + * @return {module:twgl.ProgramOptions} an instance of ProgramOptions based on the arguments passed in + * @private + */function getProgramOptions(opt_attribs,opt_locations,opt_errorCallback){var transformFeedbackVaryings;var transformFeedbackMode;if(typeof opt_locations==='function'){opt_errorCallback=opt_locations;opt_locations=undefined;}if(typeof opt_attribs==='function'){opt_errorCallback=opt_attribs;opt_attribs=undefined;}else if(opt_attribs&&!Array.isArray(opt_attribs)){// If we have an errorCallback we can just return this object +// Otherwise we need to construct one with default errorCallback +if(opt_attribs.errorCallback){return opt_attribs;}var opt=opt_attribs;opt_errorCallback=opt.errorCallback;opt_attribs=opt.attribLocations;transformFeedbackVaryings=opt.transformFeedbackVaryings;transformFeedbackMode=opt.transformFeedbackMode;}var options={errorCallback:opt_errorCallback||error$1,transformFeedbackVaryings:transformFeedbackVaryings,transformFeedbackMode:transformFeedbackMode};if(opt_attribs){var attribLocations={};if(Array.isArray(opt_attribs)){opt_attribs.forEach(function(attrib,ndx){attribLocations[attrib]=opt_locations?opt_locations[ndx]:ndx;});}else{attribLocations=opt_attribs;}options.attribLocations=attribLocations;}return options;}var defaultShaderType=["VERTEX_SHADER","FRAGMENT_SHADER"];function getShaderTypeFromScriptType(gl,scriptType){if(scriptType.indexOf("frag")>=0){return FRAGMENT_SHADER;}else if(scriptType.indexOf("vert")>=0){return VERTEX_SHADER;}return undefined;}function deleteShaders(gl,shaders){shaders.forEach(function(shader){gl.deleteShader(shader);});}/** + * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the + * program and calls useProgram. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgram(gl, [vs, fs], options); + * twgl.createProgram(gl, [vs, fs], opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]} [opt_locations|module:twgl.ErrorCallback] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console + * on error. If you want something else pass an callback. It's passed an error message. + * @return {WebGLProgram?} the created program or null if error. + * @memberOf module:twgl/programs + */function createProgram(gl,shaders,opt_attribs,opt_locations,opt_errorCallback){var progOptions=getProgramOptions(opt_attribs,opt_locations,opt_errorCallback);var realShaders=[];var newShaders=[];for(var ndx=0;ndx} an object with a setter by name for each uniform + * @memberOf module:twgl/programs + */function createUniformSetters(gl,program){var textureUnit=0;/** + * Creates a setter for a uniform of the given program with it's + * location embedded in the setter. + * @param {WebGLProgram} program + * @param {WebGLUniformInfo} uniformInfo + * @returns {function} the created setter. + */function createUniformSetter(program,uniformInfo,location){var isArray=uniformInfo.size>1&&uniformInfo.name.substr(-3)==="[0]";var type=uniformInfo.type;var typeInfo=typeMap[type];if(!typeInfo){throw new Error("unknown type: 0x".concat(type.toString(16)));// we should never get here. +}var setter;if(typeInfo.bindPoint){// it's a sampler +var unit=textureUnit;textureUnit+=uniformInfo.size;if(isArray){setter=typeInfo.arraySetter(gl,type,unit,location,uniformInfo.size);}else{setter=typeInfo.setter(gl,type,unit,location,uniformInfo.size);}}else{if(typeInfo.arraySetter&&isArray){setter=typeInfo.arraySetter(gl,location);}else{setter=typeInfo.setter(gl,location);}}setter.location=location;return setter;}var uniformSetters={};var numUniforms=gl.getProgramParameter(program,ACTIVE_UNIFORMS);for(var ii=0;ii} + * @memberOf module:twgl + */function createTransformFeedbackInfo(gl,program){var info={};var numVaryings=gl.getProgramParameter(program,TRANSFORM_FEEDBACK_VARYINGS);for(var ii=0;ii blockSpecs The BlockSpec for each block by block name + * @property {UniformData[]} uniformData An array of data for each uniform by uniform index. + * @memberOf module:twgl + */ /** + * Creates a UniformBlockSpec for the given program. + * + * A UniformBlockSpec represents the data needed to create and bind + * UniformBlockObjects + * + * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context + * @param {WebGLProgram} program A WebGLProgram for a successfully linked program + * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec + * @memberOf module:twgl/programs + */function createUniformBlockSpecFromProgram(gl,program){var numUniforms=gl.getProgramParameter(program,ACTIVE_UNIFORMS);var uniformData=[];var uniformIndices=[];for(var ii=0;ii)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * @memberOf module:twgl/programs + */function setUniforms(setters,values){// eslint-disable-line +var actualSetters=setters.uniformSetters||setters;var numArgs=arguments.length;for(var aNdx=1;aNdx} an object with a setter for each attribute by name. + * @memberOf module:twgl/programs + */function createAttributeSetters(gl,program){var attribSetters={};var numAttribs=gl.getProgramParameter(program,ACTIVE_ATTRIBUTES);for(var ii=0;ii} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} buffers AttribInfos mapped by attribute name. + * @memberOf module:twgl/programs + * @deprecated use {@link module:twgl.setBuffersAndAttributes} + */function setAttributes(setters,buffers){for(var name in buffers){var setter=setters[name];if(setter){setter(buffers[name]);}}}/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const arrays = { + * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], }, + * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent to + * + * gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + * gl.enableVertexAttribArray(a_positionLocation); + * gl.vertexAttribPointer(a_positionLocation, 3, gl.FLOAT, false, 0, 0); + * gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); + * gl.enableVertexAttribArray(a_texcoordLocation); + * gl.vertexAttribPointer(a_texcoordLocation, 4, gl.FLOAT, false, 0, 0); + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgramInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters} + * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo} + * @memberOf module:twgl/programs + */function setBuffersAndAttributes(gl,programInfo,buffers){if(buffers.vertexArrayObject){gl.bindVertexArray(buffers.vertexArrayObject);}else{setAttributes(programInfo.attribSetters||programInfo,buffers.attribs);if(buffers.indices){gl.bindBuffer(ELEMENT_ARRAY_BUFFER$1,buffers.indices);}}}/** + * @typedef {Object} ProgramInfo + * @property {WebGLProgram} program A shader program + * @property {Object} uniformSetters object of setters as returned from createUniformSetters, + * @property {Object} attribSetters object of setters as returned from createAttribSetters, + * @property {module:twgl.UniformBlockSpec} [uniformBlockSpace] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc.. + * @property {Object} [transformFeedbackInfo] info for transform feedbacks + * @memberOf module:twgl + */ /** + * Creates a ProgramInfo from an existing program. + * + * A ProgramInfo contains + * + * programInfo = { + * program: WebGLProgram, + * uniformSetters: object of setters as returned from createUniformSetters, + * attribSetters: object of setters as returned from createAttribSetters, + * } + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {WebGLProgram} program an existing WebGLProgram. + * @return {module:twgl.ProgramInfo} The created ProgramInfo. + * @memberOf module:twgl/programs + */function createProgramInfoFromProgram(gl,program){var uniformSetters=createUniformSetters(gl,program);var attribSetters=createAttributeSetters(gl,program);var programInfo={program:program,uniformSetters:uniformSetters,attribSetters:attribSetters};if(isWebGL2(gl)){programInfo.uniformBlockSpec=createUniformBlockSpecFromProgram(gl,program);programInfo.transformFeedbackInfo=createTransformFeedbackInfo(gl,program);}return programInfo;}/** + * Creates a ProgramInfo from 2 sources. + * + * A ProgramInfo contains + * + * programInfo = { + * program: WebGLProgram, + * uniformSetters: object of setters as returned from createUniformSetters, + * attribSetters: object of setters as returned from createAttribSetters, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]} [opt_locations|module:twgl.ErrorCallback] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console + * on error. If you want something else pass an callback. It's passed an error message. + * @return {module:twgl.ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */function createProgramInfo(gl,shaderSources,opt_attribs,opt_locations,opt_errorCallback){var progOptions=getProgramOptions(opt_attribs,opt_locations,opt_errorCallback);var good=true;shaderSources=shaderSources.map(function(source){// Lets assume if there is no \n it's an id +if(source.indexOf("\n")<0){var script=getElementById(source);if(!script){progOptions.errorCallback("no element with id: "+source);good=false;}else{source=script.text;}}return source;});if(!good){return null;}var program=createProgramFromSources(gl,shaderSources,progOptions);if(!program){return null;}return createProgramInfoFromProgram(gl,program);}/* + * Copyright 2019 Gregg Tavares + * + * 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. + */var defaults$2={addExtensionsToContext:true};var prefixRE=/^(.*?)_/;function addExtensionToContext(gl,extensionName){glEnumToString(gl,0);var ext=gl.getExtension(extensionName);if(ext){var enums={};var fnSuffix=prefixRE.exec(extensionName)[1];var enumSuffix='_'+fnSuffix;for(var key in ext){var value=ext[key];var isFunc=typeof value==='function';var suffix=isFunc?fnSuffix:enumSuffix;var name=key;// examples of where this is not true are WEBGL_compressed_texture_s3tc +// and WEBGL_compressed_texture_pvrtc +if(key.endsWith(suffix)){name=key.substring(0,key.length-suffix.length);}if(gl[name]!==undefined){if(!isFunc&&gl[name]!==value){warn(name,gl[name],value,key);}}else{if(isFunc){gl[name]=function(origFn){return function(){return origFn.apply(ext,arguments);};}(value);}else{gl[name]=value;enums[name]=value;}}}// pass the modified enums to glEnumToString +enums.constructor={name:ext.constructor.name};glEnumToString(enums,0);}return ext;}/* + * If you're wondering why the code doesn't just iterate + * over all extensions using `gl.getExtensions` is that it's possible + * some future extension is incompatible with this code. Rather than + * have thing suddenly break it seems better to manually add to this + * list. + * + */var supportedExtensions=['ANGLE_instanced_arrays','EXT_blend_minmax','EXT_color_buffer_float','EXT_color_buffer_half_float','EXT_disjoint_timer_query','EXT_disjoint_timer_query_webgl2','EXT_frag_depth','EXT_sRGB','EXT_shader_texture_lod','EXT_texture_filter_anisotropic','OES_element_index_uint','OES_standard_derivatives','OES_texture_float','OES_texture_float_linear','OES_texture_half_float','OES_texture_half_float_linear','OES_vertex_array_object','WEBGL_color_buffer_float','WEBGL_compressed_texture_atc','WEBGL_compressed_texture_etc1','WEBGL_compressed_texture_pvrtc','WEBGL_compressed_texture_s3tc','WEBGL_compressed_texture_s3tc_srgb','WEBGL_depth_texture','WEBGL_draw_buffers'];/** + * Attempts to enable all of the following extensions + * and add their functions and constants to the + * `WebGLRenderingContext` using their normal non-extension like names. + * + * ANGLE_instanced_arrays + * EXT_blend_minmax + * EXT_color_buffer_float + * EXT_color_buffer_half_float + * EXT_disjoint_timer_query + * EXT_disjoint_timer_query_webgl2 + * EXT_frag_depth + * EXT_sRGB + * EXT_shader_texture_lod + * EXT_texture_filter_anisotropic + * OES_element_index_uint + * OES_standard_derivatives + * OES_texture_float + * OES_texture_float_linear + * OES_texture_half_float + * OES_texture_half_float_linear + * OES_vertex_array_object + * WEBGL_color_buffer_float + * WEBGL_compressed_texture_atc + * WEBGL_compressed_texture_etc1 + * WEBGL_compressed_texture_pvrtc + * WEBGL_compressed_texture_s3tc + * WEBGL_compressed_texture_s3tc_srgb + * WEBGL_depth_texture + * WEBGL_draw_buffers + * + * For example if `ANGLE_instanced_arrays` exists then the functions + * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor` + * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the + * `WebGLRenderingContext`. + * + * Note that if you want to know if the extension exists you should + * probably call `gl.getExtension` for each extension. Alternatively + * you can check for the existence of the functions or constants that + * are expected to be added. For example + * + * if (gl.drawBuffers) { + * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2 + * .... + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @memberOf module:twgl + */function addExtensionsToContext(gl){for(var ii=0;iiFormat: 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$2(){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;}/** + * Set a mat4 to the identity matrix + * + * @param {mat4} out the receiving matrix + * @returns {mat4} out + */function identity$1(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$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],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(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;}/** + * 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$2(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;}/** + * Generates a perspective projection matrix with the given bounds. + * 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 perspective$1(out,fovy,aspect,near,far){var f=1.0/Math.tan(fovy/2),nf;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){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;}/** + * 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$1(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)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(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$1(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;}/** + * 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(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;}/** + * Alias for {@link vec3.length} + * @function + */var len=length$1;/** + * 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=function(){var vec=create$3();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;i0){len=1/Math.sqrt(len);}out[0]=x*len;out[1]=y*len;out[2]=z*len;out[3]=w*len;return out;}/** + * 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$4();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;iEPSILON){// 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;}/** + * 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;}/** + * Normalize a quat + * + * @param {quat} out the receiving quaternion + * @param {ReadonlyQuat} a quaternion to normalize + * @returns {quat} out + * @function + */var normalize$3=normalize$2;/** + * 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$3();var xUnitVec3=fromValues(1,0,0);var yUnitVec3=fromValues(0,1,0);return function(out,a,b){var dot$1=dot(a,b);if(dot$1<-0.999999){cross$1(tmpvec3,xUnitVec3,a);if(len(tmpvec3)<0.000001)cross$1(tmpvec3,yUnitVec3,a);normalize$1(tmpvec3,tmpvec3);setAxisAngle(out,tmpvec3,Math.PI);return out;}else if(dot$1>0.999999){out[0]=0;out[1]=0;out[2]=0;out[3]=1;return out;}else{cross$1(tmpvec3,a,b);out[0]=tmpvec3[0];out[1]=tmpvec3[1];out[2]=tmpvec3[2];out[3]=1+dot$1;return normalize$3(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$5();var temp2=create$5();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$1();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$3(out,fromMat3(out,matr));};}();/** + * 2 Dimensional Vector + * @module vec2 + */ /** + * Creates a new, empty vec2 + * + * @returns {vec2} a new 2D vector + */function create$6(){var out=new ARRAY_TYPE(2);if(ARRAY_TYPE!=Float32Array){out[0]=0;out[1]=0;}return out;}/** + * 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$2=function(){var vec=create$6();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 cameraspace) + * @memberof Camera# + * @member {Array} view + */ /** + * @description ViewProjection matrix (world -> ndc) + * @memberof Camera# + * @member {Array} viewProjection + */ /** + * @description World matrix for any transformation applied to world + * @memberof Camera# + * @member {Array} world + */ /** + * @description Creates an instance of the base Camera + * @param {number} width - width of canvas + * @param {number} height - height of canvas + * @returns {Camera} + */function Camera(_width,_height){var _this=this;_classCallCheck(this,Camera);_defineProperty(this,"fov",void 0);_defineProperty(this,"width",void 0);_defineProperty(this,"height",void 0);_defineProperty(this,"aspect",void 0);_defineProperty(this,"zNear",void 0);_defineProperty(this,"zFar",void 0);_defineProperty(this,"projection",void 0);_defineProperty(this,"eye",void 0);_defineProperty(this,"target",void 0);_defineProperty(this,"up",void 0);_defineProperty(this,"view",void 0);_defineProperty(this,"viewProjection",void 0);_defineProperty(this,"world",void 0);_defineProperty(this,"resize",function(width,height){_this.width=width;_this.height=height;_this.aspect=width/height;_this.projection=create$2();perspective$1(_this.projection,_this.fov,_this.aspect,_this.zNear,_this.zFar);});_defineProperty(this,"update",function(time){lookAt$1(_this.view,_this.eye,_this.target,_this.up);invert(_this.camera,_this.view);multiply$2(_this.viewProjection,_this.projection,_this.view);});_defineProperty(this,"setPosition",function(pos){_this.eye=pos;});_defineProperty(this,"getUniforms",function(time){var uniforms={};uniforms.u_viewInverse=_this.camera;uniforms.u_world=_this.world;uniforms.u_worldInverseTranspose=create$2();uniforms.u_view=_this.view;uniforms.u_resolution=[_this.width,_this.height];invert(uniforms.u_worldInverseTranspose,_this.world);transpose$1(uniforms.u_worldInverseTranspose,uniforms.u_worldInverseTranspose);uniforms.u_worldViewProjection=create$2();multiply$2(uniforms.u_worldViewProjection,_this.viewProjection,_this.world);uniforms.u_cameraPos=_this.eye;return uniforms;});_defineProperty(this,"getRayFromScreen",function(xNormalized,yNormalized){var x=xNormalized*2-1;var y=yNormalized*2-1;var near=_this.unproject([x,y,-1]);var far=_this.unproject([x,y,1]);var dir=create$3();subtract$1(dir,far,near);normalize$1(dir,dir);return{origin:near,direction:dir};});_defineProperty(this,"unproject",function(position){var inverseProjection=create$2();invert(inverseProjection,_this.viewProjection);var result=fromValues(position[0],position[1],position[2]);transformMat4(result,result,inverseProjection);return result;});_defineProperty(this,"project",function(position){var p=clone(position);transformMat4(p,p,_this.viewProjection);var x=(p[0]+1)/2;var y=(p[1]+1)/2;return[x,y];});this.fov=30*(Math.PI/180);this.width=_width;this.height=_height;this.aspect=_width/_height;this.zNear=0.01;this.zFar=100;this.projection=create$2();perspective$1(this.projection,this.fov,this.aspect,this.zNear,this.zFar);this.eye=[0,0,6];this.target=[0,0,0];this.up=[0,1,0];this.view=create$2();lookAt$1(this.view,this.eye,this.target,this.up);this.camera=create$2();invert(this.camera,this.view);this.viewProjection=create$2();multiply$2(this.viewProjection,this.projection,this.view);this.world=create$2();identity$1(this.world);}/** + * @description Resizes camera matrices + * @method + * @param {number} width - new width of canvas + * @param {number} height - new height of canvas + */;var Scene=/** + * @description Creates Scene object and creates camera + * @param {number} width - width of scene + * @param {number} height - height of scene + */function Scene(_width,_height){var _this=this;_classCallCheck(this,Scene);_defineProperty(this,"resize",function(width,height){_this.camera.resize(width,height);});_defineProperty(this,"update",function(time){_this.camera.update(time);});_defineProperty(this,"getUniforms",function(time){var uniforms=_this.camera.getUniforms(time);uniforms.time=time;return uniforms;});this.camera=new Camera(_width,_height);}/** + * @description Resizes scene camera + * @param {number} width - width of scene + * @param {number} height - height of scene + */;var ShaderMaterial=/*#__PURE__*/function(){/** + * @description Information to send to gpu + * @memberof ShaderMaterial# + * @member {ProgramInfo} programInfo + */ /** + * @description Object of WebglTextures + * @memberof ShaderMaterial# + * @member {Object} textures + */ /** + * @description Uniforms used in shader + * @memberof ShaderMaterial# + * @member {Object} uniforms + */ /** + * @description String representations of shaders {vertex: ~~, fragment: ~~} + * @memberof ShaderMaterial# + * @member {Object} shaderStrings + */ /** + * @description Has the ShaderMaterial been initialized in Webgl context + * @memberof ShaderMaterial# + * @member {boolean} isInit + */ /** + * @description Are the textures loaded onto the Webgl context + * @memberof ShaderMaterial# + * @member {boolean} texturesLoaded + */ /** + * @description Creates a ShaderMaterial object + * @param {Object} shaderStrings - String representations of shaders {vertex: ~~, fragment: ~~} + * @returns {ShaderMaterial} + */function ShaderMaterial(shaderStrings){var _this=this;_classCallCheck(this,ShaderMaterial);_defineProperty(this,"programInfo",null);_defineProperty(this,"textures",{});_defineProperty(this,"uniforms",null);_defineProperty(this,"shaderStrings",null);_defineProperty(this,"isInit",false);_defineProperty(this,"texturesLoaded",false);_defineProperty(this,"init",function(gl){_this.programInfo=createProgramInfo(gl,Object.values(_this.shaderStrings));_this.isInit=true;});_defineProperty(this,"loadTextures",function(gl,textures,onLoadCB){if(textures){var textureCount=Object.keys(textures).length;var texturesLoaded=0;Object.entries(textures).forEach(function(_ref){var _ref2=_slicedToArray(_ref,2),key=_ref2[0],texture=_ref2[1];_this.textures[key]=createTexture(gl,texture,function(){texturesLoaded+=1;if(texturesLoaded===textureCount){_this.texturesLoaded=true;if(onLoadCB){onLoadCB();}}});});}});_defineProperty(this,"updateUniforms",function(uniforms){Object.entries(uniforms).forEach(function(_ref3){var _ref4=_slicedToArray(_ref3,2),key=_ref4[0],value=_ref4[1];_this.uniforms[key]=value;});});this.shaderStrings=shaderStrings;}/** + * @description Gets isReady status + * @memberof ShaderMaterial# + * @member {boolean} isReady + */_createClass(ShaderMaterial,[{key:"isReady",get:function get(){return this.isInit&&this.texturesLoaded;}/** + * @description Initialize webgl program + * @method + * @param {WebglContext} gl - Webgl context + */}]);return ShaderMaterial;}();/* tslint:disable */ /* eslint-disable */var wasm;var heap=new Array(32).fill(undefined);heap.push(undefined,null,true,false);function getObject(idx){return heap[idx];}var WASM_VECTOR_LEN=0;var cachegetUint8Memory0=null;function getUint8Memory0(){if(cachegetUint8Memory0===null||cachegetUint8Memory0.buffer!==wasm.memory.buffer){cachegetUint8Memory0=new Uint8Array(wasm.memory.buffer);}return cachegetUint8Memory0;}var cachedTextEncoder=new TextEncoder('utf-8');var encodeString=typeof cachedTextEncoder.encodeInto==='function'?function(arg,view){return cachedTextEncoder.encodeInto(arg,view);}:function(arg,view){var buf=cachedTextEncoder.encode(arg);view.set(buf);return{read:arg.length,written:buf.length};};function passStringToWasm0(arg,malloc,realloc){if(realloc===undefined){var buf=cachedTextEncoder.encode(arg);var _ptr=malloc(buf.length);getUint8Memory0().subarray(_ptr,_ptr+buf.length).set(buf);WASM_VECTOR_LEN=buf.length;return _ptr;}var len=arg.length;var ptr=malloc(len);var mem=getUint8Memory0();var offset=0;for(;offset0x7F)break;mem[ptr+offset]=code;}if(offset!==len){if(offset!==0){arg=arg.slice(offset);}ptr=realloc(ptr,len,len=offset+arg.length*3);var view=getUint8Memory0().subarray(ptr+offset,ptr+len);var ret=encodeString(arg,view);offset+=ret.written;}WASM_VECTOR_LEN=offset;return ptr;}var cachegetInt32Memory0=null;function getInt32Memory0(){if(cachegetInt32Memory0===null||cachegetInt32Memory0.buffer!==wasm.memory.buffer){cachegetInt32Memory0=new Int32Array(wasm.memory.buffer);}return cachegetInt32Memory0;}var heap_next=heap.length;function dropObject(idx){if(idx<36)return;heap[idx]=heap_next;heap_next=idx;}function takeObject(idx){var ret=getObject(idx);dropObject(idx);return ret;}var cachedTextDecoder=new TextDecoder('utf-8',{ignoreBOM:true,fatal:true});cachedTextDecoder.decode();function getStringFromWasm0(ptr,len){return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr,ptr+len));}function addHeapObject(obj){if(heap_next===heap.length)heap.push(heap.length+1);var idx=heap_next;heap_next=heap[idx];heap[idx]=obj;return idx;}/** +*/function init_gkweb(){wasm.init_gkweb();}var cachegetFloat32Memory0=null;function getFloat32Memory0(){if(cachegetFloat32Memory0===null||cachegetFloat32Memory0.buffer!==wasm.memory.buffer){cachegetFloat32Memory0=new Float32Array(wasm.memory.buffer);}return cachegetFloat32Memory0;}function passArrayF32ToWasm0(arg,malloc){var ptr=malloc(arg.length*4);getFloat32Memory0().set(arg,ptr/4);WASM_VECTOR_LEN=arg.length;return ptr;}var cachegetUint32Memory0=null;function getUint32Memory0(){if(cachegetUint32Memory0===null||cachegetUint32Memory0.buffer!==wasm.memory.buffer){cachegetUint32Memory0=new Uint32Array(wasm.memory.buffer);}return cachegetUint32Memory0;}function passArray32ToWasm0(arg,malloc){var ptr=malloc(arg.length*4);getUint32Memory0().set(arg,ptr/4);WASM_VECTOR_LEN=arg.length;return ptr;}/** +*/var GKCollider=/*#__PURE__*/function(){function GKCollider(){_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1___default()(this,GKCollider);}_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2___default()(GKCollider,[{key:"free",value:function free(){var ptr=this.ptr;this.ptr=0;wasm.__wbg_gkcollider_free(ptr);}/** + * @param {Float32Array} points + * @param {Float32Array} uvs + * @param {Int32Array} indices + * @returns {GKCollisionGeo} + */}],[{key:"create_collision_geometry",value:function create_collision_geometry(points,uvs,indices){var ptr0=passArrayF32ToWasm0(points,wasm.__wbindgen_malloc);var len0=WASM_VECTOR_LEN;var ptr1=passArrayF32ToWasm0(uvs,wasm.__wbindgen_malloc);var len1=WASM_VECTOR_LEN;var ptr2=passArray32ToWasm0(indices,wasm.__wbindgen_malloc);var len2=WASM_VECTOR_LEN;var ret=wasm.gkcollider_create_collision_geometry(ptr0,len0,ptr1,len1,ptr2,len2);return GKCollisionGeo.__wrap(ret);}}]);return GKCollider;}();/** +*/var GKCollision=/*#__PURE__*/function(){function GKCollision(){_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1___default()(this,GKCollision);}_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2___default()(GKCollision,[{key:"free",value:function free(){var ptr=this.ptr;this.ptr=0;wasm.__wbg_gkcollision_free(ptr);}}]);return GKCollision;}();/** +*/var GKCollisionGeo=/*#__PURE__*/function(){function GKCollisionGeo(){_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1___default()(this,GKCollisionGeo);}_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_2___default()(GKCollisionGeo,[{key:"free",value:function free(){var ptr=this.ptr;this.ptr=0;wasm.__wbg_gkcollisiongeo_free(ptr);}/** + * @param {Float32Array} origin + * @param {Float32Array} direction + * @returns {any} + */},{key:"raycast",value:function raycast(origin,direction){var ptr0=passArrayF32ToWasm0(origin,wasm.__wbindgen_malloc);var len0=WASM_VECTOR_LEN;var ptr1=passArrayF32ToWasm0(direction,wasm.__wbindgen_malloc);var len1=WASM_VECTOR_LEN;var ret=wasm.gkcollisiongeo_raycast(this.ptr,ptr0,len0,ptr1,len1);return takeObject(ret);}/** + * @param {Float32Array} origin + * @param {Float32Array} direction + * @returns {boolean} + */},{key:"hitTest",value:function hitTest(origin,direction){var ptr0=passArrayF32ToWasm0(origin,wasm.__wbindgen_malloc);var len0=WASM_VECTOR_LEN;var ptr1=passArrayF32ToWasm0(direction,wasm.__wbindgen_malloc);var len1=WASM_VECTOR_LEN;var ret=wasm.gkcollisiongeo_hitTest(this.ptr,ptr0,len0,ptr1,len1);return ret!==0;}}],[{key:"__wrap",value:function __wrap(ptr){var obj=Object.create(GKCollisionGeo.prototype);obj.ptr=ptr;return obj;}}]);return GKCollisionGeo;}();function load(_x3,_x4){return _load.apply(this,arguments);}function _load(){_load=_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_0___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_4___default.a.mark(function _callee(module,imports){var bytes,instance;return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_4___default.a.wrap(function _callee$(_context){while(1){switch(_context.prev=_context.next){case 0:if(!(typeof Response==='function'&&module instanceof Response)){_context.next=23;break;}if(!(typeof WebAssembly.instantiateStreaming==='function')){_context.next=15;break;}_context.prev=2;_context.next=5;return WebAssembly.instantiateStreaming(module,imports);case 5:return _context.abrupt("return",_context.sent);case 8:_context.prev=8;_context.t0=_context["catch"](2);if(!(module.headers.get('Content-Type')!='application/wasm')){_context.next=14;break;}console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",_context.t0);_context.next=15;break;case 14:throw _context.t0;case 15:_context.next=17;return module.arrayBuffer();case 17:bytes=_context.sent;_context.next=20;return WebAssembly.instantiate(bytes,imports);case 20:return _context.abrupt("return",_context.sent);case 23:_context.next=25;return WebAssembly.instantiate(module,imports);case 25:instance=_context.sent;if(!(instance instanceof WebAssembly.Instance)){_context.next=30;break;}return _context.abrupt("return",{instance:instance,module:module});case 30:return _context.abrupt("return",instance);case 31:case"end":return _context.stop();}}},_callee,null,[[2,8]]);}));return _load.apply(this,arguments);}function init(_x5){return _init.apply(this,arguments);}function _init(){_init=_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_0___default()(/*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_4___default.a.mark(function _callee2(input){var imports,_yield$load,instance,module;return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_4___default.a.wrap(function _callee2$(_context2){while(1){switch(_context2.prev=_context2.next){case 0:if(typeof input==='undefined'){console.log('You must specify wasm location');}imports={};imports.wbg={};imports.wbg.__wbindgen_json_serialize=function(arg0,arg1){var obj=getObject(arg1);var ret=JSON.stringify(obj===undefined?null:obj);var ptr0=passStringToWasm0(ret,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);var len0=WASM_VECTOR_LEN;getInt32Memory0()[arg0/4+1]=len0;getInt32Memory0()[arg0/4+0]=ptr0;};imports.wbg.__wbindgen_object_drop_ref=function(arg0){takeObject(arg0);};imports.wbg.__wbindgen_json_parse=function(arg0,arg1){var ret=JSON.parse(getStringFromWasm0(arg0,arg1));return addHeapObject(ret);};imports.wbg.__wbindgen_string_new=function(arg0,arg1){var ret=getStringFromWasm0(arg0,arg1);return addHeapObject(ret);};imports.wbg.__wbg_new_59cb74e423758ede=function(){var ret=new Error();return addHeapObject(ret);};imports.wbg.__wbg_stack_558ba5917b466edd=function(arg0,arg1){var ret=getObject(arg1).stack;var ptr0=passStringToWasm0(ret,wasm.__wbindgen_malloc,wasm.__wbindgen_realloc);var len0=WASM_VECTOR_LEN;getInt32Memory0()[arg0/4+1]=len0;getInt32Memory0()[arg0/4+0]=ptr0;};imports.wbg.__wbg_error_4bb6c2a97407129a=function(arg0,arg1){try{console.error(getStringFromWasm0(arg0,arg1));}finally{wasm.__wbindgen_free(arg0,arg1);}};imports.wbg.__wbg_debug_7020dcb48edf105b=function(arg0){console.debug(getObject(arg0));};imports.wbg.__wbg_error_b23efba5bfb5cec5=function(arg0){console.error(getObject(arg0));};imports.wbg.__wbg_info_8ce99578d0b91a35=function(arg0){console.info(getObject(arg0));};imports.wbg.__wbg_log_c180b836187d3c94=function(arg0){console.log(getObject(arg0));};imports.wbg.__wbg_warn_942f927afebcc748=function(arg0){console.warn(getObject(arg0));};imports.wbg.__wbindgen_throw=function(arg0,arg1){throw new Error(getStringFromWasm0(arg0,arg1));};if(typeof input==='string'||typeof Request==='function'&&input instanceof Request||typeof URL==='function'&&input instanceof URL){input=fetch(input);}_context2.t0=load;_context2.next=20;return input;case 20:_context2.t1=_context2.sent;_context2.t2=imports;_context2.next=24;return(0,_context2.t0)(_context2.t1,_context2.t2);case 24:_yield$load=_context2.sent;instance=_yield$load.instance;module=_yield$load.module;wasm=instance.exports;init.__wbindgen_wasm_module=module;return _context2.abrupt("return",wasm);case 30:case"end":return _context2.stop();}}},_callee2);}));return _init.apply(this,arguments);}var Drawable=/*#__PURE__*/function(){/** + * @description Unique identification string + * @memberof Drawable# + * @member {String} id + */ /** + * @description Geometry + * @see Geometry + * @memberof Drawable# + * @member {Geometry} geometry + */ /** + * @description Geometry that is used for collision detection & raycasting + * @see GKCollisionGeo + * @memberof Drawable# + * @member {GKCollisionGeo} collisionGeometry + */ /** + * @description ShaderMaterial + * @see ShaderMaterial + * @memberof Drawable# + * @member {ShaderMaterial} material + */ /** + * @description Translation of the drawable [x,y,z] + * @private + * @memberof Drawable# + * @member {Array} _translation + */ /** + * @description Rotation of the drawable in radians [x, y, z] + * @private + * @memberof Drawable# + * @member {Array} _rotation + */ /** + * @description Scale of drawable [x, y, z] + * @private + * @memberof Drawable# + * @member {Array} _scale + */ /** + * @description Transform matrix of translation, rotation, scale + * @private + * @memberof Drawable# + * @member {Array} _modelMatrix + */ /** + * @description Does the modelMatrix need to be recalculated + * @private + * @memberof Drawable# + * @member {Array} _modelIsDirty + */ /** + * @description Is drawable able to be rayCast to? + * @memberof Drawable# + * @member {boolean} rayCast + */ /** + * @description Is drawable able to be interacted with? + * @memberof Drawable# + * @member {boolean} isInteractive + */ /** + * @description Is drawable able to be selected? + * @memberof Drawable# + * @member {boolean} isSelectable + */ /** + * @description Is drawable able to be hovered? + * @memberof Drawable# + * @member {boolean} isHoverable + */ /** + * @description Creates a drawable and initializes id + * @returns {Drawable} + */function Drawable(){var _this=this;_classCallCheck(this,Drawable);_defineProperty(this,"id",null);_defineProperty(this,"geometry",null);_defineProperty(this,"collisionGeometry",null);_defineProperty(this,"material",null);_defineProperty(this,"_translation",[0.0,0.0,0.0]);_defineProperty(this,"_rotation",[0.0,0.0,0.0]);_defineProperty(this,"_scale",[1.0,1.0,1.0]);_defineProperty(this,"_modelMatrix",null);_defineProperty(this,"_modelIsDirty",true);_defineProperty(this,"rayCast",true);_defineProperty(this,"isInteractive",false);_defineProperty(this,"isSelectable",false);_defineProperty(this,"isHoverable",false);_defineProperty(this,"shouldDraw",true);_defineProperty(this,"setInteractive",function(interactive,selectable,hoverable){_this.isInteractive=typeof interactive==='boolean'?interactive:false;_this.isSelectable=typeof selectable==='boolean'?selectable:false;_this.isHoverable=typeof hoverable==='boolean'?hoverable:false;});// Math.random should be unique because of its seeding algorithm. +// Convert it to base 36 (numbers + letters), and grab the first 9 characters +// after the decimal. +this.id='_'+Math.random().toString(36).substr(2,9);}/** + * @description Gets isReady status + * @memberof Drawable# + * @member {boolean} isReady: + */_createClass(Drawable,[{key:"update",/** + * @description Update shader material uniforms + * @method + * @param {Object} sceneProps - object of scene props as uniforms + */value:function update(sceneProps){var _this2=this;if(sceneProps){Object.entries(sceneProps).forEach(function(el){_this2.material.uniforms[el[0]]=el[1];});}}},{key:"isReady",get:function get(){if(this.geometry&&this.material){return this.geometry.isReady&&this.material.isReady;}return false;}/** + * @description [x,y,z] vector of translation + * @memberof Drawable# + * @member {Array} translation + */},{key:"translation",get:function get(){return this._translation;}/** + * @description Translation setter + * @private + */,set:function set(newTranslation){this._translation=newTranslation;this._modelIsDirty=true;}/** + * @description Rotation vector [x,y,z] + * @memberof Drawable# + * @member {Array} rotation + */},{key:"rotation",get:function get(){return this._rotation;}/** + * @description Rotation setter + * @private + */,set:function set(newRotation){this._rotation=newRotation;this._modelIsDirty=true;}/** + * @description Scale vector [x,y,z] + * @memberof Drawable# + * @member {Array} + */},{key:"scale",get:function get(){return this._scale;}/** + * @description Scale setter + * @private + */,set:function set(newScale){this._scale=newScale;this._modelIsDirty=true;}/** + * @description Sets interativity of the drawable + * @method + * @param {boolean} interactive - set interactive + * @param {boolean} selectable - set selection + * @param {boolean} hoverable - set hoverable + */},{key:"modelMatrix",/** + * @description Get modelmatrix, recalculating if needed + * @memberof Drawable# + * @member {Array} + */get:function get(){if(this._modelIsDirty){var mat0=m4.identity();var translationMatrix=m4.translation(this._translation,mat0);var scaleMatrix=m4.scaling(this._scale);this._modelMatrix=translationMatrix;m4.rotateX(translationMatrix,this._rotation[0],this._modelMatrix);m4.rotateY(translationMatrix,this._rotation[1],this._modelMatrix);m4.rotateZ(translationMatrix,this._rotation[2],this._modelMatrix);m4.multiply(this._modelMatrix,scaleMatrix,this._modelMatrix);this._modelIsDirty=false;}return this._modelMatrix;}}]);return Drawable;}();var Globe=/*#__PURE__*/function(_Drawable){_inherits(Globe,_Drawable);var _super=_createSuper(Globe);function Globe(){_classCallCheck(this,Globe);return _super.apply(this,arguments);}return Globe;}(Drawable);var side=128;var Geometry=/*#__PURE__*/function(){/** + * @description Init status of geometry + * @memberof Geometry# + * @member {boolean} isInit + */ /** + * @description Is this geometry in sync with its webgl context buffers + * @memberof Geometry# + * @member {boolean} isDirty + */ /** + * @description Webgl Buffer description + * @memberof Geometry# + * @member {BufferInfo} bufferInfo + */ /** + * @description Javascript description of vertex buffers + * @memberof Geometry# + * @member {Object} vertices + */ /** + * @description Creates a Geometry + * @param {String} type + */function Geometry(type){var _this=this;_classCallCheck(this,Geometry);_defineProperty(this,"isInit",false);_defineProperty(this,"isDirty",false);_defineProperty(this,"needsResize",false);_defineProperty(this,"newGeometry",[]);_defineProperty(this,"bufferInfo",void 0);_defineProperty(this,"vertices",void 0);_defineProperty(this,"init",function(gl){// Check for empty vertices object +if(Object.keys(_this.vertices).length===0&&_this.vertices.constructor===Object)return;_this.bufferInfo=createBufferInfoFromArrays(gl,_this.vertices);_this.isInit=true;_this.isDirty=false;});_defineProperty(this,"resizeVertices",function(length){});_defineProperty(this,"updateGeometry",function(newGeo,start,end){if(start===undefined||typeof start!=='number')start=0;console.log("Update geo",newGeo);Object.keys(newGeo).forEach(function(key){var _this$vertices$key$da;(_this$vertices$key$da=_this.vertices[key].data).splice.apply(_this$vertices$key$da,[start,newGeo[key].data.length].concat(_toConsumableArray(newGeo[key].data)));});_this.isDirty=true;});_defineProperty(this,"updateBuffers",function(gl){Object.keys(_this.bufferInfo.attribs).forEach(function(attr){setAttribInfoBufferFromArray(gl,_this.bufferInfo.attribs[attr],_this.vertices[attr]);});_this.isDirty=false;});_defineProperty(this,"reloadBuffers",function(gl){_this.deleteBuffers(gl);_this.bufferInfo=createBufferInfoFromArrays(gl,_this.vertices);_this.isDirty=false;_this.needsResize=false;});_defineProperty(this,"deleteBuffers",function(gl){Object.keys(_this.bufferInfo.attribs).forEach(function(attr){gl.deleteBuffer(attr.buffer);});gl.deleteBuffer(_this.bufferInfo.indices);_this.bufferInfo={};});if(type==='sphere'){this.vertices=primitives.createSphereVertices(1,side,side);}else{this.vertices={};}}/** + * @description Sends vertices to gpu and generates bufferInfo + * @param {WebglContext} gl + */_createClass(Geometry,[{key:"isReady",/** + * @description Status of geometry + * @memberof Geometry# + * @member {boolean} isReady + */get:function get(){return this.isInit;}}]);return Geometry;}();/** + * @class + */var GKUtils=/*#__PURE__*/function(){function GKUtils(){_classCallCheck(this,GKUtils);}_createClass(GKUtils,null,[{key:"radiansForPosition",/** + * @description Compute axis angles for positon + * @static + * @param {number} x - x position + * @param {number} z - z position + * @returns {number} + */value:function radiansForPosition(x,z){if(z>0){if(x>=0){return Math.atan(x/z);}return 2*Math.PI+Math.atan(x/z);}if(z<0){return Math.PI+Math.atan(x/z);}if(x>0){return Math.PI/2.0;}return 3*Math.PI/2.0;}/** + * @description Convert worldspace [x,y,z] to lat lon + * @static + * @param {Array} pos - worldspace coordinates [x,y,z] + * @returns {Object} + */},{key:"latLonFromWorld",value:function latLonFromWorld(pos){var normal=create$3();normalize$1(normal,pos);var latRad=Math.asin(normal[1]);var lonRad=this.radiansForPosition(normal[0],normal[2]);var latDeg=latRad*180.0/Math.PI;var lonDeg=lonRad*180.0/Math.PI;while(lonDeg>180.0){lonDeg-=360.0;}return{lat:latDeg,lon:lonDeg};}/** + * @description Computes great circle distance between 2 lat lon coords + * @static + * @param {Object} p0 - {lat: ~~, lon: ~~} + * @param {Object} p1 - {lat: ~~, lon: ~~} + * @returns + */},{key:"distanceBetweenPoints",value:function distanceBetweenPoints(p0,p1){var degreesToRadians=function degreesToRadians(degrees){return degrees*(Math.PI/180);};var R=6371;// km +var phi1=degreesToRadians(p0.lat);// phi, lambda in radians +var phi2=degreesToRadians(p1.lat);var deltaPhi=degreesToRadians(p1.lat-p0.lat);var deltaLambda=degreesToRadians(p1.lon-p0.lon);var a=Math.sin(deltaPhi/2)*Math.sin(deltaPhi/2)+Math.cos(phi1)*Math.cos(phi2)*Math.sin(deltaLambda/2)*Math.sin(deltaLambda/2);var c=2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a));var d=R*c;// in km +return d;}/** + * @description Convert lat lon alt to worldspace + * @static + * @param {number} lat - latitude in degrees + * @param {number} lon - longitude in degrees + * @param {number} alt - altitude from surface of globe in earth radius (surface = 0) + * @returns {Array} + */},{key:"worldFromLatLon",value:function worldFromLatLon(lat,lon,alt){var altitude=alt||0.0;var latRad=lat*Math.PI/180.0;var lngRad=lon*Math.PI/180.0;var radius=Math.cos(latRad);var y=Math.sin(latRad);var x=Math.sin(lngRad)*radius;var z=Math.cos(lngRad)*radius;var pos=fromValues(x,y,z);var norm=create$3();normalize$1(norm,pos);var add=scale$1(norm,norm,altitude);add$1(pos,pos,add);return pos;}/** + * @description Convert hex color to RGB array + * @param {String} h - Color Hex Code + * @param {boolean} normalize - Should the output be normalized to [0,1] + * @returns {Array} + */},{key:"hexToRGB",value:function hexToRGB(h,normalize){var r=0;var g=0;var b=0;var norm=normalize!==false;if(h.length===4){r="0x".concat(h[1]).concat(h[1]);g="0x".concat(h[2]).concat(h[2]);b="0x".concat(h[3]).concat(h[3]);}else if(h.length===7){r="0x".concat(h[1]).concat(h[2]);g="0x".concat(h[3]).concat(h[4]);b="0x".concat(h[5]).concat(h[6]);}if(norm){r/=255;g/=255;b/=255;}else{r=parseInt(r,16);g=parseInt(g,16);b=parseInt(b,16);}return[r,g,b];}/** + * @description Convert hex + alpha to RGBA + * @param {String} h - Color hex code + * @param {number} a - Alpha value [0,1] + * @param {boolean} normalize - Should the output be normalized to [0,1] + * @returns {Array} + */},{key:"hexToRGBA",value:function hexToRGBA(h,a,normalize){var rgb=this.hexToRGB(h,normalize);var alpha=normalize!==false?a:a*255;return[rgb[0],rgb[1],rgb[2],alpha];}},{key:"isSubSet",value:function isSubSet(a,b){return a.every(function(el){return b.find(function(e){return e===el;})!==undefined;});}/** + * A linear interpolator for hexadecimal colors + * @param {String} a + * @param {String} b + * @param {Number} amount + * @example + * // returns #7F7F7F + * lerpColor('#000000', '#ffffff', 0.5) + * @returns {String} + */},{key:"lerpColor",value:function lerpColor(a,b,amount){var ah=parseInt(a.replace(/#/g,''),16);var ar=ah>>16;var ag=ah>>8&0xff;var ab=ah&0xff;var bh=parseInt(b.replace(/#/g,''),16);var br=bh>>16;var bg=bh>>8&0xff;var bb=bh&0xff;var rr=ar+amount*(br-ar);var rg=ag+amount*(bg-ag);var rb=ab+amount*(bb-ab);return"#".concat(((1<<24)+(rr<<16)+(rg<<8)+rb|0).toString(16).slice(1));}}]);return GKUtils;}();var vert="#define GLSLIFY 1\nattribute vec4 position;attribute vec3 normal;attribute vec2 texcoord;uniform mat4 u_worldViewProjection;uniform mat4 u_viewInverse;uniform mat4 u_model;uniform vec3 u_cameraPos;varying float vAlpha;varying vec2 vTexture;void main(){vec4 pos=u_worldViewProjection*u_model*position;vAlpha=dot(normalize(u_cameraPos),normalize(normal.xyz));vTexture=texcoord;gl_Position=pos;}";// eslint-disable-line +var frag="precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D uTexture;varying float vAlpha;varying vec2 vTexture;void main(){vec4 textureColor=texture2D(uTexture,vec2(vTexture.x-0.25,vTexture.y));float nDot=(vAlpha+1.0)/2.0;float roundness=smoothstep(0.0,1.0,nDot);float edge=smoothstep(0.5,0.6,nDot);gl_FragColor=vec4(textureColor.rgb*vAlpha,1.0);}";// eslint-disable-line +var shaders={vertex:vert,fragment:frag};var uniforms={u_lightWorldPos:[1,3,-8],u_lightColor:[1,0.8,0.8,1],u_ambient:[1.0,1.0,1.0,1],u_specular:[1,1,1,1],u_shininess:100,u_specularFactor:0.1,uModelMatrix:[],uCameraMatrix:[],uPerspectiveMatrix:[],uCameraPos:[0,0,0]};var Icosphere=/*#__PURE__*/function(_Globe){_inherits(Icosphere,_Globe);var _super=_createSuper(Icosphere);function Icosphere(textureSrc){var _thisSuper,_this;_classCallCheck(this,Icosphere);_this=_super.call(this);_defineProperty(_assertThisInitialized(_this),"material",null);_defineProperty(_assertThisInitialized(_this),"init",function(gl){_this.geometry=new Geometry('sphere');_this.geometry.init(gl);var texturesConfig={surface:{src:_this.textureSrc.surface,minMag:gl.LINEAR}};_this.material.init(gl);_this.material.loadTextures(gl,texturesConfig,function(){_this.material.uniforms.uTexture=_this.material.textures.surface;});_this.material.uniforms.uModelMatrix=_this.modelMatrix;});_defineProperty(_assertThisInitialized(_this),"createCollisionGeo",function(){if(_this.collisionGeometry&&_this.collisionGeometry instanceof GKCollision)return;_this.collisionGeometry=GKCollider.create_collision_geometry(_this.geometry.vertices.position,_this.geometry.vertices.texcoord,_this.geometry.vertices.indices);});_defineProperty(_assertThisInitialized(_this),"rayCastFrom",function(ray){return _this.collisionGeometry.raycast(ray.origin,ray.direction);});_defineProperty(_assertThisInitialized(_this),"hitTest",function(ray){return _this.collisionGeometry.hitTest(ray.origin,ray.direction);});_defineProperty(_assertThisInitialized(_this),"onSelection",function(lat,lon,selection){// convert worldPos to lat lon +console.log('Icosphere.onSelection',GKUtils.latLonFromWorld(selection.point));});_defineProperty(_assertThisInitialized(_this),"update",function(gl,sceneProps,time){_get((_thisSuper=_assertThisInitialized(_this),_getPrototypeOf(Icosphere.prototype)),"update",_thisSuper).call(_thisSuper,sceneProps,time);_this.material.uniforms.u_model=_this.modelMatrix;console.log();});_defineProperty(_assertThisInitialized(_this),"draw",function(gl){if(!_this.isReady)return;gl.useProgram(_this.material.programInfo.program);setBuffersAndAttributes(gl,_this.material.programInfo,_this.geometry.bufferInfo);setUniforms(_this.material.programInfo,_this.material.uniforms);gl.drawElements(gl.TRIANGLES,_this.geometry.bufferInfo.numElements,gl.UNSIGNED_SHORT,0);});_this.material=new ShaderMaterial(shaders);_this.material.uniforms=uniforms;_this.textureSrc={surface:textureSrc};return _this;}return Icosphere;}(Globe);var ImageLookup=function ImageLookup(src,onInitCB){var _this=this;_classCallCheck(this,ImageLookup);_defineProperty(this,"isLoaded",false);_defineProperty(this,"ctx",undefined);_defineProperty(this,"canvas",undefined);_defineProperty(this,"image",undefined);_defineProperty(this,"getIdFromLatLon",function(lat,lon){if(!_this.isLoaded)return undefined;// Convert lat lon to normalized coords +var nX=(lon/180.0+1.0)/2.0;var nY=1.0-(lat/90.0+1.0)/2.0;// Convert normalized coords to pixels +var x=nX*_this.canvas.width;var y=nY*_this.canvas.height;return _this.ctx.getImageData(x,y,1,1).data[0];});this.image=new Image();this.image.src=src;this.image.addEventListener('load',function(){_this.canvas=document.createElement('canvas');_this.canvas.width=_this.image.width;_this.canvas.height=_this.image.height;_this.ctx=_this.canvas.getContext('2d');_this.ctx.drawImage(_this.image,0,0);_this.isLoaded=true;onInitCB();});};var Lookup=function Lookup(data,image){var _this=this;_classCallCheck(this,Lookup);_defineProperty(this,"isInit",false);_defineProperty(this,"useImageLookup",false);_defineProperty(this,"imageLookup",null);_defineProperty(this,"getIdFromLatLon",function(lat,lon){return _this.imageLookup.getIdFromLatLon(lat,lon);});_defineProperty(this,"getFromId",function(id){return _this.data.find(function(obj){return obj.id===id;});});_defineProperty(this,"getFromCode",function(code){return _this.data.find(function(obj){return obj.code===code;});});_defineProperty(this,"getFromName",function(name){return _this.data.find(function(obj){return obj.name===name;});});// Check that data is "valid" +if(!(data instanceof Array))return undefined;this.data=data;if(image){this.useImageLookup=true;this.imageLookup=new ImageLookup(image,function(){_this.isInit=true;});}};// TODO: DOcument this +//TODO: refactor into ES6 class +var Tween=/*#__PURE__*/function(){function Tween(from,to,time,props){var _this=this;_classCallCheck(this,Tween);_defineProperty(this,"time",void 0);_defineProperty(this,"delay",0);_defineProperty(this,"ease",function(p){return p;});_defineProperty(this,"onComplete",function(finished){});_defineProperty(this,"onUpdate",function(value){});_defineProperty(this,"endAt",void 0);_defineProperty(this,"isNumeric",false);_defineProperty(this,"toObj",null);_defineProperty(this,"fromObj",null);_defineProperty(this,"currentObj",null);_defineProperty(this,"mechanism",function(){if(!_this.isRunning)return;if(_this.stopped)return false;var timeLeft=_this.endAt-new Date().getTime();if(timeLeft<=0){clearTimeout(_this.playTimeout);_this.stopped=true;_this.advanceFrame(1,1);if(_this.isNumeric){_this.onUpdate(_this.currentObj.value);}else{_this.onUpdate(_this.currentObj);}_this.onComplete(true);_this.cleanup();}else{_this.advanceFrame(_this.time-timeLeft,_this.time);if(_this.isNumeric){_this.onUpdate(_this.currentObj.value);}else{_this.onUpdate(_this.currentObj);}}});props=props||{};this.time=time;this.endAt=new Date().getTime()+this.time;this.isNumeric=!isNaN(from);if(this.isNumeric){this.toObj={value:to};this.fromObj={value:from};}else{this.toObj=_objectSpread2({},to);this.fromObj=_objectSpread2({},from);}this.currentObj=_objectSpread2({},this.fromObj);this.id=Tween.getId();Tween.tweens[this.id]=this;if(props.onComplete){this.onComplete=props.onComplete;delete props.onComplete;}if(props.onUpdate){this.onUpdate=props.onUpdate;delete props.onUpdate;}if(props.ease){this.ease=props.ease;delete props.ease;}if(props.delay){this.endAt+=props.delay;this.delay=props.delay;delete props.delay;}this.playTimeout=setTimeout(function(){_this.play();},this.delay);}_createClass(Tween,[{key:"play",value:function play(){this.endAt=new Date().getTime()+this.time;this.isRunning=true;if(!Tween.isRunning){Tween.isRunning=true;requestAnimationFrame(Tween.mechanism);}}},{key:"stop",value:function stop(){clearTimeout(this.playTimeout);this.stopped=true;this.onComplete(false);this.cleanup();}},{key:"currentValue",value:function currentValue(){if(this.isNumeric){return this.currentObj.value;}return this.currentObj;}},{key:"cleanup",value:function cleanup(){this.isRunning=false;delete Tween.tweens[this.id];if(Object.keys(Tween.tweens).length===0){Tween.isRunning=false;}}},{key:"advanceFrame",value:function advanceFrame(frame,frames){var t=frames!==0?frame/frames:1;t=this.ease(t);for(var prop in this.toObj){var b=this.fromObj[prop];var e=this.toObj[prop];var m=e-b;this.currentObj[prop]=b+m*t;}}}]);return Tween;}();Tween.id=0;Tween.tweens={};Tween.killTweensOf=function(obj){for(var x in Tween.tweens){var t=Tween.tweens[x];if(t.obj===obj)t.stop();}};Tween.getId=function(){return++Tween.id;};Tween.isRunning=false;Tween.mechanism=function(){for(var key in Tween.tweens){Tween.tweens[key].mechanism();}if(Tween.isRunning){requestAnimationFrame(Tween.mechanism);}};var DataTexture=function DataTexture(width,height){var _this=this;_classCallCheck(this,DataTexture);_defineProperty(this,"width",4);_defineProperty(this,"height",4);_defineProperty(this,"channels",4);_defineProperty(this,"elementLength",1);_defineProperty(this,"data",void 0);_defineProperty(this,"texture",void 0);_defineProperty(this,"isInit",false);_defineProperty(this,"init",function(gl){var textureSettings={width:_this.width,height:_this.height,mag:gl.NEAREST,min:gl.NEAREST,src:_this.data};_this.texture=createTexture(gl,textureSettings);_this.isInit=true;});_defineProperty(this,"updatePixel",function(gl,c,row,column){if(!_this.isInit)return;var color=new Uint8Array(c);gl.bindTexture(gl.TEXTURE_2D,_this.texture);gl.texSubImage2D(gl.TEXTURE_2D,0,column,row,1,1,gl.RGBA,gl.UNSIGNED_BYTE,color);});_defineProperty(this,"updatePixelId",function(gl,c,id){//Convert id to row column +var row=Math.floor(id/_this.width);var col=id-row*_this.width;_this.updatePixel(gl,c,row,col);});_defineProperty(this,"updateSubrect",function(gl,c){if(!_this.isInit)return;gl.bindTexture(gl.TEXTURE_2D,_this.texture);gl.texSubImage2D(gl.TEXTURE_2D,0,0,0,_this.width,_this.height,gl.RGBA,gl.UNSIGNED_BYTE,c);});this.width=width||this.width;this.height=height||this.height;this.data=new Uint8Array(this.width*this.height*this.channels).fill(0);};var vert$1="#define GLSLIFY 1\nattribute vec4 position;attribute vec3 normal;attribute vec2 texcoord;uniform mat4 u_worldViewProjection;uniform mat4 u_viewInverse;uniform mat4 u_model;uniform vec3 u_cameraPos;varying float vAlpha;varying vec2 vTexture;void main(){vec4 pos=u_worldViewProjection*u_model*position;vAlpha=dot(normalize(u_cameraPos),normalize(position.xyz));vTexture=texcoord;gl_Position=pos;}";// eslint-disable-line +var frag$1="precision mediump float;\n#define GLSLIFY 1\nuniform sampler2D u_inactive;uniform sampler2D u_active;uniform sampler2D u_id;uniform sampler2D u_data;uniform float u_idAnimateIn;uniform float u_idAnimateOut;uniform float u_animateIn;uniform float u_animateOut;uniform vec3 u_animateHover;uniform vec3 u_animatable0;uniform vec3 u_animatable1;uniform vec3 u_animatable2;uniform vec3 u_animatable3;uniform vec3 u_animatable4;uniform vec3 u_animatable5;varying float vAlpha;varying vec2 vTexture;float when_eq(float x,float y){return 1.0-abs(sign(x-y));}float when_lt(float x,float y){return max(sign(y-x),0.0);}vec2 get_data_coords_from_id(float id){float width=16.0;float height=16.0;float w_pixel=1.0/width;float h_pixel=1.0/height;float row=floor(id/width);float col=id-(row*width);return vec2(col*w_pixel,row*h_pixel);}void main(){vec4 inactiveColor=texture2D(u_inactive,vec2(vTexture.x-0.25,vTexture.y));vec4 activeColor=texture2D(u_active,vec2(vTexture.x-0.25,vTexture.y));vec4 idColor=texture2D(u_id,vec2(vTexture.x-0.25,vTexture.y));vec4 dataColor=texture2D(u_data,get_data_coords_from_id(floor(idColor.r*255.0)))*idColor.a;vec3 base=inactiveColor.rgb*(1.0-dataColor.a)+dataColor.rgb*(dataColor.a);vec3 color=base;gl_FragColor=vec4(color,1.0);}";// eslint-disable-line +var shaders$1={vertex:vert$1,fragment:frag$1};var uniforms$1={u_lightWorldPos:[1,3,-8],u_lightColor:[1,0.8,0.8,1],u_ambient:[1.0,1.0,1.0,1],u_specular:[1,1,1,1],u_shininess:100,u_specularFactor:0.1};var IcosphereLookup=/*#__PURE__*/function(_Globe){_inherits(IcosphereLookup,_Globe);var _super=_createSuper(IcosphereLookup);// DEBUG +// DEBUG +function IcosphereLookup(textureSrc){var _thisSuper,_this;_classCallCheck(this,IcosphereLookup);_this=_super.call(this);_defineProperty(_assertThisInitialized(_this),"material",null);_defineProperty(_assertThisInitialized(_this),"lookup",null);_defineProperty(_assertThisInitialized(_this),"currentSelection",-1);_defineProperty(_assertThisInitialized(_this),"previousSelection",-1);_defineProperty(_assertThisInitialized(_this),"inAnimation",null);_defineProperty(_assertThisInitialized(_this),"outAnimation",null);_defineProperty(_assertThisInitialized(_this),"currentHover",-1);_defineProperty(_assertThisInitialized(_this),"hoverables",[]);_defineProperty(_assertThisInitialized(_this),"hoverableUniforms",['u_animatable0','u_animatable1','u_animatable2','u_animatable3','u_animatable4','u_animatable5']);_defineProperty(_assertThisInitialized(_this),"selection0",236);_defineProperty(_assertThisInitialized(_this),"selection1",144);_defineProperty(_assertThisInitialized(_this),"current",236);_defineProperty(_assertThisInitialized(_this),"dataTexture",void 0);_defineProperty(_assertThisInitialized(_this),"dataTextureSize",16);_defineProperty(_assertThisInitialized(_this),"updateCMDs",[]);_defineProperty(_assertThisInitialized(_this),"highlightAnimationProps",{start:0,stop:1,duration:1000,onUpdate:function onUpdate(value){_this.material.uniforms.u_animateIn=value;}});_defineProperty(_assertThisInitialized(_this),"init",function(gl,cb){_this.geometry=new Geometry('sphere');_this.geometry.init(gl);var texturesConfig={inactive:{src:_this.textureSrc.inactive,minMag:gl.LINEAR},active:{src:_this.textureSrc.active,minMag:gl.LINEAR},id:{src:_this.textureSrc.id,minMag:gl.NEAREST}};_this.material.init(gl);_this.material.loadTextures(gl,texturesConfig,function(){_this.material.uniforms.u_inactive=_this.material.textures.inactive;_this.material.uniforms.u_active=_this.material.textures.active;_this.material.uniforms.u_id=_this.material.textures.id;_this.dataTexture.init(gl);_this.material.uniforms.u_data=_this.dataTexture.texture;if(cb)cb();});});_defineProperty(_assertThisInitialized(_this),"getValueForId",function(id){return _this.lookup.getFromId(id);});_defineProperty(_assertThisInitialized(_this),"getValueForCode",function(code){return _this.lookup.getFromCode(code);});_defineProperty(_assertThisInitialized(_this),"getValueForName",function(name){return _this.lookup.getFromName(name);});_defineProperty(_assertThisInitialized(_this),"setIdColor",function(id,color,alpha){var a=alpha===undefined?1.0:alpha;var c=GKUtils.hexToRGBA(color,a,false);_this.updateCMDs.push(function(gl){_this.dataTexture.updatePixelId(gl,c,id);});});_defineProperty(_assertThisInitialized(_this),"createCollisionGeo",function(){if(_this.collisionGeometry&&_this.collisionGeometry instanceof GKCollision)return;_this.collisionGeometry=GKCollider.create_collision_geometry(_this.geometry.vertices.position,_this.geometry.vertices.texcoord,_this.geometry.vertices.indices);});_defineProperty(_assertThisInitialized(_this),"rayCastFrom",function(ray){return _this.collisionGeometry.raycast(ray.origin,ray.direction);});_defineProperty(_assertThisInitialized(_this),"hitTest",function(ray){return _this.collisionGeometry.hitTest(ray.origin,ray.direction);});_defineProperty(_assertThisInitialized(_this),"onSelectionCB",function(selectionObj){});_defineProperty(_assertThisInitialized(_this),"onSelection",function(lat,lon,collision){// convert worldPos to lat lon +var coords=GKUtils.latLonFromWorld(collision.point);_this.current=_this.lookup.getIdFromLatLon(coords.lat,coords.lon);// console.log('IcosphereLookup.onSelection', coords.lat, coords.lon, this.current); +// this.current = (this.current === this.selection0) ? this.selection1 : this.selection0; +_this.setHighlightId(_this.current);_this.onSelectionCB(_this.current);return{id:_this.current,name:_this.lookup.getFromId(_this.current)};});_defineProperty(_assertThisInitialized(_this),"onHover",function(collision){console.log('IcosphereLookup.onHover',collision);});_defineProperty(_assertThisInitialized(_this),"update",function(gl,sceneProps,time){_get((_thisSuper=_assertThisInitialized(_this),_getPrototypeOf(IcosphereLookup.prototype)),"update",_thisSuper).call(_thisSuper,sceneProps,time);_this.material.uniforms.u_model=_this.modelMatrix;// TODO: Batch Gl specific updates. +_this.updateCMDs.forEach(function(cmd){cmd(gl);});_this.updateCMDs=[];});_defineProperty(_assertThisInitialized(_this),"draw",function(gl){if(!_this.isReady||!_this.shouldDraw)return;gl.useProgram(_this.material.programInfo.program);setBuffersAndAttributes(gl,_this.material.programInfo,_this.geometry.bufferInfo);setUniforms(_this.material.programInfo,_this.material.uniforms);gl.drawElements(gl.TRIANGLES,_this.geometry.bufferInfo.numElements,gl.UNSIGNED_SHORT,0);});_defineProperty(_assertThisInitialized(_this),"setCountryHover",function(countryIndex){});_defineProperty(_assertThisInitialized(_this),"setHighlightId",function(id){_this.previousSelection=_this.currentSelection;_this.currentSelection=id;var animateOutStart=_this.inAnimation?_this.inAnimation.currentValue():1.0;// We want a full animate out to take 1 second so 1-0 in 1000 milliseconds +var animateOutDuration=animateOutStart*(300.0/1.0);_this.animateIn(_this.currentSelection,500.0);_this.animateOut(_this.previousSelection,animateOutDuration,animateOutStart);});_defineProperty(_assertThisInitialized(_this),"animateIn",function(id,duration,cb){_this.material.uniforms.u_idAnimateIn=id;if(_this.inAnimation)_this.inAnimation.stop();_this.material.uniforms.u_animateIn=0;_this.inAnimation=new Tween(_this.highlightAnimationProps.start,_this.highlightAnimationProps.stop,_this.highlightAnimationProps.duration,{onUpdate:_this.highlightAnimationProps.onUpdate});});_defineProperty(_assertThisInitialized(_this),"animateOut",function(id,duration,start,cb){_this.material.uniforms.u_idAnimateOut=id;if(_this.outAnimation)_this.outAnimation.stop();_this.material.uniforms.u_animateOut=start;_this.outAnimation=new Tween(start,0,duration,{onUpdate:function onUpdate(value){_this.material.uniforms.u_animateOut=value;}});});_defineProperty(_assertThisInitialized(_this),"addDataset",function(data){_this.lookup=new Lookup(data,_this.textureSrc.id);});_defineProperty(_assertThisInitialized(_this),"updateIdState",function(id,state){});_this.material=new ShaderMaterial(shaders$1);_this.material.uniforms=uniforms$1;_this.textureSrc={inactive:textureSrc.inactive,active:textureSrc.active,id:textureSrc.id};_this.dataTexture=new DataTexture(_this.dataTextureSize,_this.dataTextureSize);return _this;}return IcosphereLookup;}(Globe);var commonjsGlobal=typeof globalThis!=='undefined'?globalThis:typeof window!=='undefined'?window:typeof global!=='undefined'?global:typeof self!=='undefined'?self:{};function createCommonjsModule(fn,module){return module={exports:{}},fn(module,module.exports),module.exports;}var hammerMin=createCommonjsModule(function(module){/*! Hammer.JS - v2.0.8 - 2016-04-23 + * http://hammerjs.github.io/ + * + * Copyright (c) 2016 Jorik Tangelder; + * Licensed under the MIT license */!function(a,b,c,d){function e(a,b,c){return setTimeout(j(a,c),b);}function f(a,b,c){return Array.isArray(a)?(g(a,c[b],c),!0):!1;}function g(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.length!==d)for(e=0;e\s*\(/gm,"{anonymous}()@"):"Unknown Stack Trace",f=a.console&&(a.console.warn||a.console.log);return f&&f.call(a.console,e,d),b.apply(this,arguments);};}function i(a,b,c){var d,e=b.prototype;d=a.prototype=Object.create(e),d.constructor=a,d._super=e,c&&la(d,c);}function j(a,b){return function(){return a.apply(b,arguments);};}function k(a,b){return _typeof(a)==oa?a.apply(b?b[0]||d:d,b):a;}function l(a,b){return a===d?b:a;}function m(a,b,c){g(q(b),function(b){a.addEventListener(b,c,!1);});}function n(a,b,c){g(q(b),function(b){a.removeEventListener(b,c,!1);});}function o(a,b){for(;a;){if(a==b)return!0;a=a.parentNode;}return!1;}function p(a,b){return a.indexOf(b)>-1;}function q(a){return a.trim().split(/\s+/g);}function r(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;dc[b];}):d.sort()),d;}function u(a,b){for(var c,e,f=b[0].toUpperCase()+b.slice(1),g=0;g1&&!c.firstMultiple?c.firstMultiple=D(b):1===e&&(c.firstMultiple=!1);var f=c.firstInput,g=c.firstMultiple,h=g?g.center:f.center,i=b.center=E(d);b.timeStamp=ra(),b.deltaTime=b.timeStamp-f.timeStamp,b.angle=I(h,i),b.distance=H(h,i),B(c,b),b.offsetDirection=G(b.deltaX,b.deltaY);var j=F(b.deltaTime,b.deltaX,b.deltaY);b.overallVelocityX=j.x,b.overallVelocityY=j.y,b.overallVelocity=qa(j.x)>qa(j.y)?j.x:j.y,b.scale=g?K(g.pointers,d):1,b.rotation=g?J(g.pointers,d):0,b.maxPointers=c.prevInput?b.pointers.length>c.prevInput.maxPointers?b.pointers.length:c.prevInput.maxPointers:b.pointers.length,C(c,b);var k=a.element;o(b.srcEvent.target,k)&&(k=b.srcEvent.target),b.target=k;}function B(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=a.prevInput||{};b.eventType!==Ea&&f.eventType!==Ga||(e=a.prevDelta={x:f.deltaX||0,y:f.deltaY||0},d=a.offsetDelta={x:c.x,y:c.y}),b.deltaX=e.x+(c.x-d.x),b.deltaY=e.y+(c.y-d.y);}function C(a,b){var c,e,f,g,h=a.lastInterval||b,i=b.timeStamp-h.timeStamp;if(b.eventType!=Ha&&(i>Da||h.velocity===d)){var j=b.deltaX-h.deltaX,k=b.deltaY-h.deltaY,l=F(i,j,k);e=l.x,f=l.y,c=qa(l.x)>qa(l.y)?l.x:l.y,g=G(j,k),a.lastInterval=b;}else c=h.velocity,e=h.velocityX,f=h.velocityY,g=h.direction;b.velocity=c,b.velocityX=e,b.velocityY=f,b.direction=g;}function D(a){for(var b=[],c=0;ce;){c+=a[e].clientX,d+=a[e].clientY,e++;}return{x:pa(c/b),y:pa(d/b)};}function F(a,b,c){return{x:b/a||0,y:c/a||0};}function G(a,b){return a===b?Ia:qa(a)>=qa(b)?0>a?Ja:Ka:0>b?La:Ma;}function H(a,b,c){c||(c=Qa);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return Math.sqrt(d*d+e*e);}function I(a,b,c){c||(c=Qa);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*Math.atan2(e,d)/Math.PI;}function J(a,b){return I(b[1],b[0],Ra)+I(a[1],a[0],Ra);}function K(a,b){return H(b[0],b[1],Ra)/H(a[0],a[1],Ra);}function L(){this.evEl=Ta,this.evWin=Ua,this.pressed=!1,x.apply(this,arguments);}function M(){this.evEl=Xa,this.evWin=Ya,x.apply(this,arguments),this.store=this.manager.session.pointerEvents=[];}function N(){this.evTarget=$a,this.evWin=_a,this.started=!1,x.apply(this,arguments);}function O(a,b){var c=s(a.touches),d=s(a.changedTouches);return b&(Ga|Ha)&&(c=t(c.concat(d),"identifier",!0)),[c,d];}function P(){this.evTarget=bb,this.targetIds={},x.apply(this,arguments);}function Q(a,b){var c=s(a.touches),d=this.targetIds;if(b&(Ea|Fa)&&1===c.length)return d[c[0].identifier]=!0,[c,c];var e,f,g=s(a.changedTouches),h=[],i=this.target;if(f=c.filter(function(a){return o(a.target,i);}),b===Ea)for(e=0;e-1&&d.splice(a,1);};setTimeout(e,cb);}}function U(a){for(var b=a.srcEvent.clientX,c=a.srcEvent.clientY,d=0;d=f&&db>=g)return!0;}return!1;}function V(a,b){this.manager=a,this.set(b);}function W(a){if(p(a,jb))return jb;var b=p(a,kb),c=p(a,lb);return b&&c?jb:b||c?b?kb:lb:p(a,ib)?ib:hb;}function X(){if(!fb)return!1;var b={},c=a.CSS&&a.CSS.supports;return["auto","manipulation","pan-y","pan-x","pan-x pan-y","none"].forEach(function(d){b[d]=c?a.CSS.supports("touch-action",d):!0;}),b;}function Y(a){this.options=la({},this.defaults,a||{}),this.id=v(),this.manager=null,this.options.enable=l(this.options.enable,!0),this.state=nb,this.simultaneous={},this.requireFail=[];}function Z(a){return a&sb?"cancel":a&qb?"end":a&pb?"move":a&ob?"start":"";}function $(a){return a==Ma?"down":a==La?"up":a==Ja?"left":a==Ka?"right":"";}function _(a,b){var c=b.manager;return c?c.get(a):a;}function aa(){Y.apply(this,arguments);}function ba(){aa.apply(this,arguments),this.pX=null,this.pY=null;}function ca(){aa.apply(this,arguments);}function da(){Y.apply(this,arguments),this._timer=null,this._input=null;}function ea(){aa.apply(this,arguments);}function fa(){aa.apply(this,arguments);}function ga(){Y.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0;}function ha(a,b){return b=b||{},b.recognizers=l(b.recognizers,ha.defaults.preset),new ia(a,b);}function ia(a,b){this.options=la({},ha.defaults,b||{}),this.options.inputTarget=this.options.inputTarget||a,this.handlers={},this.session={},this.recognizers=[],this.oldCssProps={},this.element=a,this.input=y(this),this.touchAction=new V(this,this.options.touchAction),ja(this,!0),g(this.options.recognizers,function(a){var b=this.add(new a[0](a[1]));a[2]&&b.recognizeWith(a[2]),a[3]&&b.requireFailure(a[3]);},this);}function ja(a,b){var c=a.element;if(c.style){var d;g(a.options.cssProps,function(e,f){d=u(c.style,f),b?(a.oldCssProps[d]=c.style[d],c.style[d]=e):c.style[d]=a.oldCssProps[d]||"";}),b||(a.oldCssProps={});}}function ka(a,c){var d=b.createEvent("Event");d.initEvent(a,!0,!0),d.gesture=c,c.target.dispatchEvent(d);}var la,ma=["","webkit","Moz","MS","ms","o"],na=b.createElement("div"),oa="function",pa=Math.round,qa=Math.abs,ra=Date.now;la="function"!=typeof Object.assign?function(a){if(a===d||null===a)throw new TypeError("Cannot convert undefined or null to object");for(var b=Object(a),c=1;ch&&(b.push(a),h=b.length-1):e&(Ga|Ha)&&(c=!0),0>h||(b[h]=a,this.callback(this.manager,e,{pointers:b,changedPointers:[a],pointerType:f,srcEvent:a}),c&&b.splice(h,1));}});var Za={touchstart:Ea,touchmove:Fa,touchend:Ga,touchcancel:Ha},$a="touchstart",_a="touchstart touchmove touchend touchcancel";i(N,x,{handler:function handler(a){var b=Za[a.type];if(b===Ea&&(this.started=!0),this.started){var c=O.call(this,a,b);b&(Ga|Ha)&&c[0].length-c[1].length===0&&(this.started=!1),this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:za,srcEvent:a});}}});var ab={touchstart:Ea,touchmove:Fa,touchend:Ga,touchcancel:Ha},bb="touchstart touchmove touchend touchcancel";i(P,x,{handler:function handler(a){var b=ab[a.type],c=Q.call(this,a,b);c&&this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:za,srcEvent:a});}});var cb=2500,db=25;i(R,x,{handler:function handler(a,b,c){var d=c.pointerType==za,e=c.pointerType==Ba;if(!(e&&c.sourceCapabilities&&c.sourceCapabilities.firesTouchEvents)){if(d)S.call(this,b,c);else if(e&&U.call(this,c))return;this.callback(a,b,c);}},destroy:function destroy(){this.touch.destroy(),this.mouse.destroy();}});var eb=u(na.style,"touchAction"),fb=eb!==d,gb="compute",hb="auto",ib="manipulation",jb="none",kb="pan-x",lb="pan-y",mb=X();V.prototype={set:function set(a){a==gb&&(a=this.compute()),fb&&this.manager.element.style&&mb[a]&&(this.manager.element.style[eb]=a),this.actions=a.toLowerCase().trim();},update:function update(){this.set(this.manager.options.touchAction);},compute:function compute(){var a=[];return g(this.manager.recognizers,function(b){k(b.options.enable,[b])&&(a=a.concat(b.getTouchAction()));}),W(a.join(" "));},preventDefaults:function preventDefaults(a){var b=a.srcEvent,c=a.offsetDirection;if(this.manager.session.prevented)return void b.preventDefault();var d=this.actions,e=p(d,jb)&&!mb[jb],f=p(d,lb)&&!mb[lb],g=p(d,kb)&&!mb[kb];if(e){var h=1===a.pointers.length,i=a.distance<2,j=a.deltaTime<250;if(h&&i&&j)return;}return g&&f?void 0:e||f&&c&Na||g&&c&Oa?this.preventSrc(b):void 0;},preventSrc:function preventSrc(a){this.manager.session.prevented=!0,a.preventDefault();}};var nb=1,ob=2,pb=4,qb=8,rb=qb,sb=16,tb=32;Y.prototype={defaults:{},set:function set(a){return la(this.options,a),this.manager&&this.manager.touchAction.update(),this;},recognizeWith:function recognizeWith(a){if(f(a,"recognizeWith",this))return this;var b=this.simultaneous;return a=_(a,this),b[a.id]||(b[a.id]=a,a.recognizeWith(this)),this;},dropRecognizeWith:function dropRecognizeWith(a){return f(a,"dropRecognizeWith",this)?this:(a=_(a,this),delete this.simultaneous[a.id],this);},requireFailure:function requireFailure(a){if(f(a,"requireFailure",this))return this;var b=this.requireFail;return a=_(a,this),-1===r(b,a)&&(b.push(a),a.requireFailure(this)),this;},dropRequireFailure:function dropRequireFailure(a){if(f(a,"dropRequireFailure",this))return this;a=_(a,this);var b=r(this.requireFail,a);return b>-1&&this.requireFail.splice(b,1),this;},hasRequireFailures:function hasRequireFailures(){return this.requireFail.length>0;},canRecognizeWith:function canRecognizeWith(a){return!!this.simultaneous[a.id];},emit:function emit(a){function b(b){c.manager.emit(b,a);}var c=this,d=this.state;qb>d&&b(c.options.event+Z(d)),b(c.options.event),a.additionalEvent&&b(a.additionalEvent),d>=qb&&b(c.options.event+Z(d));},tryEmit:function tryEmit(a){return this.canEmit()?this.emit(a):void(this.state=tb);},canEmit:function canEmit(){for(var a=0;af?Ja:Ka,c=f!=this.pX,d=Math.abs(a.deltaX)):(e=0===g?Ia:0>g?La:Ma,c=g!=this.pY,d=Math.abs(a.deltaY))),a.direction=e,c&&d>b.threshold&&e&b.direction;},attrTest:function attrTest(a){return aa.prototype.attrTest.call(this,a)&&(this.state&ob||!(this.state&ob)&&this.directionTest(a));},emit:function emit(a){this.pX=a.deltaX,this.pY=a.deltaY;var b=$(a.direction);b&&(a.additionalEvent=this.options.event+b),this._super.emit.call(this,a);}}),i(ca,aa,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function getTouchAction(){return[jb];},attrTest:function attrTest(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.scale-1)>this.options.threshold||this.state&ob);},emit:function emit(a){if(1!==a.scale){var b=a.scale<1?"in":"out";a.additionalEvent=this.options.event+b;}this._super.emit.call(this,a);}}),i(da,Y,{defaults:{event:"press",pointers:1,time:251,threshold:9},getTouchAction:function getTouchAction(){return[hb];},process:function process(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distanceb.time;if(this._input=a,!d||!c||a.eventType&(Ga|Ha)&&!f)this.reset();else if(a.eventType&Ea)this.reset(),this._timer=e(function(){this.state=rb,this.tryEmit();},b.time,this);else if(a.eventType&Ga)return rb;return tb;},reset:function reset(){clearTimeout(this._timer);},emit:function emit(a){this.state===rb&&(a&&a.eventType&Ga?this.manager.emit(this.options.event+"up",a):(this._input.timeStamp=ra(),this.manager.emit(this.options.event,this._input)));}}),i(ea,aa,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function getTouchAction(){return[jb];},attrTest:function attrTest(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.rotation)>this.options.threshold||this.state&ob);}}),i(fa,aa,{defaults:{event:"swipe",threshold:10,velocity:.3,direction:Na|Oa,pointers:1},getTouchAction:function getTouchAction(){return ba.prototype.getTouchAction.call(this);},attrTest:function attrTest(a){var b,c=this.options.direction;return c&(Na|Oa)?b=a.overallVelocity:c&Na?b=a.overallVelocityX:c&Oa&&(b=a.overallVelocityY),this._super.attrTest.call(this,a)&&c&a.offsetDirection&&a.distance>this.options.threshold&&a.maxPointers==this.options.pointers&&qa(b)>this.options.velocity&&a.eventType&Ga;},emit:function emit(a){var b=$(a.offsetDirection);b&&this.manager.emit(this.options.event+b,a),this.manager.emit(this.options.event,a);}}),i(ga,Y,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:9,posThreshold:10},getTouchAction:function getTouchAction(){return[ib];},process:function process(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance0.0?absScaledDeltaY:1/absScaledDeltaY;scaledDeltaY=Math.max(0.9,scaledDeltaY);scaledDeltaY=Math.min(1.2,scaledDeltaY);// TODO: Verify multiple calls per draw cycle +_this.zStart=_this.zCurrent;_this.rotVelocity=[0,0];_this.zTarget=_this._zBounded(_this._zForScale(scaledDeltaY));_this.lastGestureChange=event.timeStamp;});_defineProperty(this,"_onPanContinue",function(event){if(!_this.isInteractive)return;if(_this.interacting===true){// TODO: this sucks and is a hack. This basically increases the size of the sphere +// that the input is acting on. This linearaly modifies the speed to feel "right" +var scale=6.0;var t=[event.deltaY/devicePixelRatio*scale,event.deltaX/devicePixelRatio*scale];var d=_this._rotForDelta([_this.panStart[0]-t[0],_this.panStart[1]-t[1]]);// console.log(d); +_this.rotTarget=_this._rotBounded([_this.rotStart[0]+d[0],_this.rotStart[1]+d[1]]);_this.lastGestureChange=event.timeStamp;}});_defineProperty(this,"_onPanEnd",function(event){if(!_this.isInteractive)return;_this.interacting=false;var curTime=event.timeStamp;var timeElapsed=curTime-_this.lastGestureChange;if(timeElapsed>0.1){_this.rotVelocity=[0,0];return;}var d=_this._rotForDelta([event.overallVelocityX,event.overallVelocityY]);_this.rotVelocity=[d[0]*0.016,d[1]*0.016];_this.rotDir=d[0]>0.0?1.0:-1.0;var pitchNorm=_this.rotTarget[0]/(Math.PI/2)/0.5;if(Math.abs(pitchNorm)<1){_this.ambientPitchX=Math.asin(pitchNorm);}else{_this.ambientPitchX=Math.PI/2*(pitchNorm/Math.abs(pitchNorm));}_this.ambientPitchDir=d[1]>0.0?-1.0:1.0;});_defineProperty(this,"_updateRot",function(){if(!_this.interacting){var ambientPitchY=0;// if (this.hasAmbient) { +// this.ambientPitch = Math.min(this.ambientPitch + (1.0 / 120.0), 1); +ambientPitchY=Math.sin(_this.ambientPitchX)*(Math.PI/2)*0.5;_this.ambientPitchX+=0.001*_this.ambientPitchDir*_this.ambientPitch;// } else { +// this.ambientPitch = 0; +// this.ambientPitchX = 0; +// ambientPitchY = 0; +// } +// console.log(this.ambientPitch); +_this.rotTarget=[_this.rotTarget[0]*(1-_this.ambientPitch)+ambientPitchY*_this.ambientPitch,_this.rotTarget[1]];var targetBounded=[Math.max(Math.min(_this.rotTarget[0],_this.settings.CAM_PITCH_SPRING_MAX),_this.settings.CAM_PITCH_SPRING_MIN),_this.rotTarget[1]];var targetDelta=[_this.rotTarget[0]-targetBounded[0]+_this.rotVelocity[0],_this.rotTarget[1]-targetBounded[1]+_this.rotVelocity[1]];_this.rotTarget=[_this.rotTarget[0]-targetDelta[0]*_this.settings.SPRING_STR*3.0,_this.rotTarget[1]-targetDelta[1]*_this.settings.SPRING_STR*3.0];_this.rotVelocity=[_this.rotVelocity[0]*_this.settings.FRICTION,_this.rotVelocity[1]*_this.settings.FRICTION];var camP=_this.zCurrent/_this.settings.CAM_Z_MAX;if(_this.hasAmbient&&_this.ambientYaw===0&&!_this.ambientTween){// this.ambientYaw = Math.min(this.ambientYaw + (this.settings.YAW_MIN_VELOCITY / 120.0), this.settings.YAW_MIN_VELOCITY); +_this.setAmbientAnimated(true,2500);}var yawMin=_this.ambientYaw*(camP*camP);if(Math.abs(_this.rotVelocity[1])_this.settings.CAM_Z_SPRING_MAX){var d=z-_this.settings.CAM_Z_SPRING_MAX;var x=_this.settings.CAM_Z_MAX-_this.settings.CAM_Z_SPRING_MAX;var f=_this.easeOutSin(Math.min(d/x,1.0));return _this.settings.CAM_Z_SPRING_MAX+x*f;}if(z<_this.settings.CAM_Z_SPRING_MIN){var _d=z-_this.settings.CAM_Z_SPRING_MIN;var _x=_this.settings.CAM_Z_MIN-_this.settings.CAM_Z_SPRING_MIN;var _f=_this.easeOutSin(Math.min(_d/_x,1.0));return _this.settings.CAM_Z_SPRING_MIN+_x*_f;}return z;});_defineProperty(this,"_rotBounded",function(r){if(r[0]>_this.settings.CAM_PITCH_SPRING_MAX){var d=r[0]-_this.settings.CAM_PITCH_SPRING_MAX;var x=_this.settings.CAM_PITCH_MAX-_this.settings.CAM_PITCH_SPRING_MAX;var f=_this.easeOutSin(Math.min(d/x,1.0));return[_this.settings.CAM_PITCH_SPRING_MAX+x*f,r[1]];}if(r[0]<_this.settings.CAM_PITCH_SPRING_MIN){var _d2=r[0]-_this.settings.CAM_PITCH_SPRING_MIN;var _x2=_this.settings.CAM_PITCH_MIN-_this.settings.CAM_PITCH_SPRING_MIN;var _f2=_this.easeOutSin(Math.min(_d2/_x2,1.0));return[_this.settings.CAM_PITCH_SPRING_MIN+_x2*_f2,r[1]];}return r;});_defineProperty(this,"_frustumDist",function(height,fov){return height*0.5/Math.tan(fov*0.5*(Math.PI/180));});_defineProperty(this,"_rotForDelta",function(delta){var pitch=delta[0]*(_this.pointsPerRadian*(_this.zCurrent/_this.zFullWidth));var yaw=delta[1]*(_this.pointsPerRadian*(_this.zCurrent/_this.zFullWidth));return[pitch,yaw];});_defineProperty(this,"easeOutSin",function(x){return Math.sin(x*Math.PI/2);});this.settings={};this.settings.EARTH_RADIUS=6378137.0;// metres +// Z config +this.settings.CAM_Z_MIN=1.0;this.settings.CAM_Z_MAX=45.0;this.settings.CAM_Z_INI=(this.settings.CAM_Z_MIN+this.settings.CAM_Z_MAX)*0.5;this.settings.CAM_Z_SPRING_BND=0.8;this.settings.CAM_Z_SPRING_MAX=this.settings.CAM_Z_MAX*this.settings.CAM_Z_SPRING_BND;this.settings.CAM_Z_SPRING_MIN=this.settings.CAM_Z_MIN*(1.0/this.settings.CAM_Z_SPRING_BND);// Pitch config +this.settings.CAM_PITCH_MAX=Math.PI*0.5;this.settings.CAM_PITCH_MIN=-Math.PI*0.5;this.settings.CAM_PITCH_INI=0.0;this.settings.CAM_PITCH_SPRING_BND=0.8;this.settings.CAM_PITCH_SPRING_MAX=this.settings.CAM_PITCH_MAX*this.settings.CAM_PITCH_SPRING_BND;this.settings.CAM_PITCH_SPRING_MIN=this.settings.CAM_PITCH_MIN*this.settings.CAM_PITCH_SPRING_BND;// General config +this.settings.FRICTION=0.1;this.settings.SPRING_STR=0.16;this.settings.YAW_MIN_VELOCITY=0.01;this.zStart=0.0;this.zCurrent=0.0;this.zTarget=0.0;this.panStart=[0,0];this.rotStart=[0.0,0.0];this.rotCurrent=[0.0,0.0];this.rotTarget=[0.0,0.0];this.rotVelocity=[0.0,0.0];this.rotDir=1.0;this.ambientYaw=0.0;this.ambientPitch=0.0;this.ambientPitchX=0.0;this.ambientPitchDir=-1.0;this.ambientTween=null;this.interacting=false;this.getInteractionState=function(){return _this.interacting;};this.lastGestureChange=0;this.pointsPerRadian=0;this.zFullWidth=0;this.onTap=function(event){};this.onPanCB=function(event){};}_createClass(MovementModel,[{key:"_onTap",value:function _onTap(event){if(!this.isInteractive)return;this.onTap(event);}},{key:"_onPinch",value:function _onPinch(event){if(!this.isInteractive)return;if(event.isFirst){this.zStart=this.zCurrent;this.rotVelocity=[0,0];}else if(event.isFinal);else{this.zTarget=this._zBounded(this._zForScale(event.scale));this.lastGestureChange=event.timeStamp;}}},{key:"_onPanStart",value:function _onPanStart(event){this.interacting=true;this.rotStart=this.rotCurrent;this.panStart=[event.deltaX/devicePixelRatio,event.deltaY/devicePixelRatio];this.rotVelocity=[0,0];// Kill Velocity +}},{key:"camPos",get:function get(){return[0.0,0.0,this.zCurrent];}},{key:"camYaw",get:function get(){return this.rotCurrent[1];}},{key:"camPitch",get:function get(){return this.rotCurrent[0];}}]);return MovementModel;}();var InteractionController=/*#__PURE__*/function(){/** + * @description Should process interations + * @memberof InteractionController# + * @member {boolean} isInteractive + */ /** + * @description Dom element to attach event listeners + * @memberof InteractionController# + * @member {HTMLElement} targetElement + */ /** + * @description Drawable to hittest against for interactions + * @memberof InteractionController# + * @member {Drawable} targetDrawable + */ /** + * @description Camera reference + * @memberof InteractionController# + * @member {Camera} camera + */ /** + * @description Movement model to use for camera control + * @memberof InteractionController# + * @member {MovementModel} movementModel + */ /** + * @description Bounding rect of targetElement + * @memberof InteractionController# + * @member {DOMRect} boundingRect + */ /** + * @description Function to call when tap is confirmed + * @memberof InteractionController# + * @member {function} onTapCB + */ /** + * @description What callbacks should be registered + * @memberof InteractionController# + * @member {Object} + */ /** + * @description Creates an interactionController + * @param {HTMLElement} targetElement - Dom element to attach event listeners + * @param {Camera} camera - Reference to the camera in use + * @param {Object} options - What callbacks should be registered + * @returns {InteractionController} + */function InteractionController(targetElement,camera,options){var _this=this;_classCallCheck(this,InteractionController);_defineProperty(this,"isInteractive",false);_defineProperty(this,"targetElement",null);_defineProperty(this,"targetDrawable",null);_defineProperty(this,"camera",null);_defineProperty(this,"movementModel",null);_defineProperty(this,"boundingRect",null);_defineProperty(this,"onTapCB",null);_defineProperty(this,"options",{tap:true,pan:true,pinch:true});_defineProperty(this,"release",function(){_this.hammer.destroy();});_defineProperty(this,"resize",function(){_this.boundingRect=_this.targetElement.getBoundingClientRect();_this.movementModel.resize(_this.boundingRect.width,_this.boundingRect.height,_this.camera.aspect,_this.camera.fov);});_defineProperty(this,"update",function(){_this.movementModel.update(_this.camera.fov);});_defineProperty(this,"isOverTarget",function(x,y){// Normalize window pos to target element +var xNorm=x-_this.boundingRect.x;var yNorm=y-_this.boundingRect.y;var xNormalized=xNorm/_this.boundingRect.width;var yNormalized=(_this.boundingRect.height-yNorm)/_this.boundingRect.height;var ray=_this.camera.getRayFromScreen(xNormalized,yNormalized);return _this.targetDrawable.hitTest(ray);// return true; +});_defineProperty(this,"onPanStart",function(event){if(!_this.isOverTarget(event.center.x,event.center.y))return;_this.movementModel._onPanStart(event);if(_this.onPan){_this.onPan(event);}});_defineProperty(this,"onPanContinue",function(event){if(event.center.x!==0&&event.center.y!==0){_this.movementModel._onPanContinue(event);if(_this.onPan){_this.onPan(event);}}});_defineProperty(this,"onPanEnd",function(event){_this.movementModel._onPanEnd(event);});_defineProperty(this,"onTap",function(event){// Normalize window pos to target element +var xNorm=event.center.x-_this.boundingRect.x;var yNorm=event.center.y-_this.boundingRect.y;if(_this.onTapCB){_this.onTapCB(xNorm,yNorm);}});if(targetElement){this.targetElement=targetElement;this.boundingRect=this.targetElement.getBoundingClientRect();}else{targetElement=window;}this.camera=camera;if(options){if(options.tap){this.options.tap=options.tap;}if(options.pan){this.options.pan=options.pan;}if(options.pinch){this.options.pinch=options.pinch;}}this.movementModel=new MovementModel();this.movementModel.init(this.boundingRect.width,this.boundingRect.height,this.camera.aspect,this.camera.fov);this.movementModel.isInteractive=true;this.movementModel.hasAmbient=false;this.hammer=window.Hammer(this.targetElement,null);if(this.options.tap)this.hammer.on('tap',this.onTap);if(this.options.pan)this.hammer.on('panstart',this.onPanStart);if(this.options.pan)this.hammer.on('pan',this.onPanContinue);if(this.options.pan)this.hammer.on('panend',this.onPanEnd);if(this.options.pinch)this.hammer.on('tap',this.onPinch);this.isInteractive=true;}_createClass(InteractionController,[{key:"target",/** + * @description sets targetDrawable + * @memberof InteractionController# + * @member {Drawable} target + */set:function set(newTarget){this.targetDrawable=newTarget;}/** + * @description Resize bounding rect and movement model + * @method + */}]);return InteractionController;}();var CubicBezier=function CubicBezier(){_classCallCheck(this,CubicBezier);};CubicBezier.create=function(p1x,p1y,p2x,p2y){// Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1). +var cx=3.0*p1x;var bx=3.0*(p2x-p1x)-cx;var ax=1.0-cx-bx;var cy=3.0*p1y;var by=3.0*(p2y-p1y)-cy;var ay=1.0-cy-by;var sampleCurveX=function sampleCurveX(t){return((ax*t+bx)*t+cx)*t;};var sampleCurveY=function sampleCurveY(t){return((ay*t+by)*t+cy)*t;};var sampleCurveDerivativeX=function sampleCurveDerivativeX(t){return(3.0*ax*t+2.0*bx)*t+cx;};var solveCurveX=function solveCurveX(x,epsilon){var t0;var t1;var t2;var x2;var d2;// First try a few iterations of Newton's method -- normally very fast. +t2=x;for(var i=0;i<8;i++){x2=sampleCurveX(t2)-x;if(Math.abs(x2)t1){return t1;}while(t0x2){t0=t2;}else{t1=t2;}t2=(t1-t0)*0.5+t0;}// Failure. +return t2;};return function(x){return sampleCurveY(solveCurveX(x,1e-9));};};var asin=Math.asin;var cos=Math.cos;var sin=Math.sin;var sqrt=Math.sqrt;var PI=Math.PI;// equatorial mean radius of Earth (in meters) +var R=6378137;function squared(x){return x*x;}function toRad(x){return x*PI/180.0;}function hav(x){return squared(sin(x/2));}// hav(theta) = hav(bLat - aLat) + cos(aLat) * cos(bLat) * hav(bLon - aLon) +function haversineDistance(a,b){var aLat=toRad(Array.isArray(a)?a[1]:a.latitude||a.lat);var bLat=toRad(Array.isArray(b)?b[1]:b.latitude||b.lat);var aLng=toRad(Array.isArray(a)?a[0]:a.longitude||a.lng||a.lon);var bLng=toRad(Array.isArray(b)?b[0]:b.longitude||b.lng||b.lon);var ht=hav(bLat-aLat)+cos(aLat)*cos(bLat)*hav(bLng-aLng);return 2*R*asin(sqrt(ht));}var haversineDistance_1=haversineDistance;/** + * @class + */var DataDrawable=/*#__PURE__*/function(_Drawable){_inherits(DataDrawable,_Drawable);var _super=_createSuper(DataDrawable);function DataDrawable(){_classCallCheck(this,DataDrawable);return _super.apply(this,arguments);}return DataDrawable;}(Drawable);/** + * A collection of shims that provide minimal functionality of the ES6 collections. + * + * These implementations are not meant to be used outside of the ResizeObserver + * modules as they cover only a limited range of use cases. + */ /* eslint-disable require-jsdoc, valid-jsdoc */var MapShim=function(){if(typeof Map!=='undefined'){return Map;}/** + * Returns index in provided array that matches the specified key. + * + * @param {Array} arr + * @param {*} key + * @returns {number} + */function getIndex(arr,key){var result=-1;arr.some(function(entry,index){if(entry[0]===key){result=index;return true;}return false;});return result;}return(/** @class */function(){function class_1(){this.__entries__=[];}Object.defineProperty(class_1.prototype,"size",{/** + * @returns {boolean} + */get:function get(){return this.__entries__.length;},enumerable:true,configurable:true});/** + * @param {*} key + * @returns {*} + */class_1.prototype.get=function(key){var index=getIndex(this.__entries__,key);var entry=this.__entries__[index];return entry&&entry[1];};/** + * @param {*} key + * @param {*} value + * @returns {void} + */class_1.prototype.set=function(key,value){var index=getIndex(this.__entries__,key);if(~index){this.__entries__[index][1]=value;}else{this.__entries__.push([key,value]);}};/** + * @param {*} key + * @returns {void} + */class_1.prototype.delete=function(key){var entries=this.__entries__;var index=getIndex(entries,key);if(~index){entries.splice(index,1);}};/** + * @param {*} key + * @returns {void} + */class_1.prototype.has=function(key){return!!~getIndex(this.__entries__,key);};/** + * @returns {void} + */class_1.prototype.clear=function(){this.__entries__.splice(0);};/** + * @param {Function} callback + * @param {*} [ctx=null] + * @returns {void} + */class_1.prototype.forEach=function(callback,ctx){if(ctx===void 0){ctx=null;}for(var _i=0,_a=this.__entries__;_i<_a.length;_i++){var entry=_a[_i];callback.call(ctx,entry[1],entry[0]);}};return class_1;}());}();/** + * Detects whether window and document objects are available in current environment. + */var isBrowser=typeof window!=='undefined'&&typeof document!=='undefined'&&window.document===document;// Returns global object of a current environment. +var global$1=function(){if(typeof global!=='undefined'&&global.Math===Math){return global;}if(typeof self!=='undefined'&&self.Math===Math){return self;}if(typeof window!=='undefined'&&window.Math===Math){return window;}// eslint-disable-next-line no-new-func +return Function('return this')();}();/** + * A shim for the requestAnimationFrame which falls back to the setTimeout if + * first one is not supported. + * + * @returns {number} Requests' identifier. + */var requestAnimationFrame$1=function(){if(typeof requestAnimationFrame==='function'){// It's required to use a bounded function because IE sometimes throws +// an "Invalid calling object" error if rAF is invoked without the global +// object on the left hand side. +return requestAnimationFrame.bind(global$1);}return function(callback){return setTimeout(function(){return callback(Date.now());},1000/60);};}();// Defines minimum timeout before adding a trailing call. +var trailingTimeout=2;/** + * Creates a wrapper function which ensures that provided callback will be + * invoked only once during the specified delay period. + * + * @param {Function} callback - Function to be invoked after the delay period. + * @param {number} delay - Delay after which to invoke callback. + * @returns {Function} + */function throttle(callback,delay){var leadingCall=false,trailingCall=false,lastCallTime=0;/** + * Invokes the original callback function and schedules new invocation if + * the "proxy" was called during current request. + * + * @returns {void} + */function resolvePending(){if(leadingCall){leadingCall=false;callback();}if(trailingCall){proxy();}}/** + * Callback invoked after the specified delay. It will further postpone + * invocation of the original function delegating it to the + * requestAnimationFrame. + * + * @returns {void} + */function timeoutCallback(){requestAnimationFrame$1(resolvePending);}/** + * Schedules invocation of the original function. + * + * @returns {void} + */function proxy(){var timeStamp=Date.now();if(leadingCall){// Reject immediately following calls. +if(timeStamp-lastCallTime} + */this.observers_=[];this.onTransitionEnd_=this.onTransitionEnd_.bind(this);this.refresh=throttle(this.refresh.bind(this),REFRESH_DELAY);}/** + * Adds observer to observers list. + * + * @param {ResizeObserverSPI} observer - Observer to be added. + * @returns {void} + */ResizeObserverController.prototype.addObserver=function(observer){if(!~this.observers_.indexOf(observer)){this.observers_.push(observer);}// Add listeners if they haven't been added yet. +if(!this.connected_){this.connect_();}};/** + * Removes observer from observers list. + * + * @param {ResizeObserverSPI} observer - Observer to be removed. + * @returns {void} + */ResizeObserverController.prototype.removeObserver=function(observer){var observers=this.observers_;var index=observers.indexOf(observer);// Remove observer if it's present in registry. +if(~index){observers.splice(index,1);}// Remove listeners if controller has no connected observers. +if(!observers.length&&this.connected_){this.disconnect_();}};/** + * Invokes the update of observers. It will continue running updates insofar + * it detects changes. + * + * @returns {void} + */ResizeObserverController.prototype.refresh=function(){var changesDetected=this.updateObservers_();// Continue running updates if changes have been detected as there might +// be future ones caused by CSS transitions. +if(changesDetected){this.refresh();}};/** + * Updates every observer from observers list and notifies them of queued + * entries. + * + * @private + * @returns {boolean} Returns "true" if any observer has detected changes in + * dimensions of it's elements. + */ResizeObserverController.prototype.updateObservers_=function(){// Collect observers that have active observations. +var activeObservers=this.observers_.filter(function(observer){return observer.gatherActive(),observer.hasActive();});// Deliver notifications in a separate cycle in order to avoid any +// collisions between observers, e.g. when multiple instances of +// ResizeObserver are tracking the same element and the callback of one +// of them changes content dimensions of the observed target. Sometimes +// this may result in notifications being blocked for the rest of observers. +activeObservers.forEach(function(observer){return observer.broadcastActive();});return activeObservers.length>0;};/** + * Initializes DOM listeners. + * + * @private + * @returns {void} + */ResizeObserverController.prototype.connect_=function(){// Do nothing if running in a non-browser environment or if listeners +// have been already added. +if(!isBrowser||this.connected_){return;}// Subscription to the "Transitionend" event is used as a workaround for +// delayed transitions. This way it's possible to capture at least the +// final state of an element. +document.addEventListener('transitionend',this.onTransitionEnd_);window.addEventListener('resize',this.refresh);if(mutationObserverSupported){this.mutationsObserver_=new MutationObserver(this.refresh);this.mutationsObserver_.observe(document,{attributes:true,childList:true,characterData:true,subtree:true});}else{document.addEventListener('DOMSubtreeModified',this.refresh);this.mutationEventsAdded_=true;}this.connected_=true;};/** + * Removes DOM listeners. + * + * @private + * @returns {void} + */ResizeObserverController.prototype.disconnect_=function(){// Do nothing if running in a non-browser environment or if listeners +// have been already removed. +if(!isBrowser||!this.connected_){return;}document.removeEventListener('transitionend',this.onTransitionEnd_);window.removeEventListener('resize',this.refresh);if(this.mutationsObserver_){this.mutationsObserver_.disconnect();}if(this.mutationEventsAdded_){document.removeEventListener('DOMSubtreeModified',this.refresh);}this.mutationsObserver_=null;this.mutationEventsAdded_=false;this.connected_=false;};/** + * "Transitionend" event handler. + * + * @private + * @param {TransitionEvent} event + * @returns {void} + */ResizeObserverController.prototype.onTransitionEnd_=function(_a){var _b=_a.propertyName,propertyName=_b===void 0?'':_b;// Detect whether transition may affect dimensions of an element. +var isReflowProperty=transitionKeys.some(function(key){return!!~propertyName.indexOf(key);});if(isReflowProperty){this.refresh();}};/** + * Returns instance of the ResizeObserverController. + * + * @returns {ResizeObserverController} + */ResizeObserverController.getInstance=function(){if(!this.instance_){this.instance_=new ResizeObserverController();}return this.instance_;};/** + * Holds reference to the controller's instance. + * + * @private {ResizeObserverController} + */ResizeObserverController.instance_=null;return ResizeObserverController;}();/** + * Defines non-writable/enumerable properties of the provided target object. + * + * @param {Object} target - Object for which to define properties. + * @param {Object} props - Properties to be defined. + * @returns {Object} Target object. + */var defineConfigurable=function defineConfigurable(target,props){for(var _i=0,_a=Object.keys(props);_i<_a.length;_i++){var key=_a[_i];Object.defineProperty(target,key,{value:props[key],enumerable:false,writable:false,configurable:true});}return target;};/** + * Returns the global object associated with provided element. + * + * @param {Object} target + * @returns {Object} + */var getWindowOf=function getWindowOf(target){// Assume that the element is an instance of Node, which means that it +// has the "ownerDocument" property from which we can retrieve a +// corresponding global object. +var ownerGlobal=target&&target.ownerDocument&&target.ownerDocument.defaultView;// Return the local global object if it's not possible extract one from +// provided element. +return ownerGlobal||global$1;};// Placeholder of an empty content rectangle. +var emptyRect=createRectInit(0,0,0,0);/** + * Converts provided string to a number. + * + * @param {number|string} value + * @returns {number} + */function toFloat(value){return parseFloat(value)||0;}/** + * Extracts borders size from provided styles. + * + * @param {CSSStyleDeclaration} styles + * @param {...string} positions - Borders positions (top, right, ...) + * @returns {number} + */function getBordersSize(styles){var positions=[];for(var _i=1;_i