Skip to content

Instantly share code, notes, and snippets.

@wallabyway
Last active May 12, 2020 01:54
Show Gist options
  • Save wallabyway/a577623e2b7984a14afec626fa9a6c8e to your computer and use it in GitHub Desktop.
Save wallabyway/a577623e2b7984a14afec626fa9a6c8e to your computer and use it in GitHub Desktop.
/**
* @license twgl.js 0.0.26 Copyright (c) 2015, Gregg Tavares All Rights Reserved.
* Available via the MIT license.
* see: http://github.com/greggman/twgl.js for details
*/
/**
* @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/almond for details
*/
/**
Modifications to twgl.js:
MB - added 6x2 stereo cubemap layout to 'setTextureFromElement()', use 'shift=1' to select offset
MB - added 'twgl.m4.fromRotationTranslation()' for minimal quaternion webVR support (borrowed from Gregg Tavares's glmatrix library)
MB - added 'twgl.m4.eularToQuat()' to convert onDeviceOrientation input to quaternion
MB - added option 'shrink'. Resize cubemap destination canvas to allow for bad GPU's (ie. where max cube map texture size = 1024)
*/
!function(a,b){"function"==typeof define&&define.amd?define([],b):a.twgl=b()}(this,function(){var a,b,c;return function(d){function e(a,b){return v.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o=b&&b.split("/"),p=t.map,q=p&&p["*"]||{};if(a){for(a=a.split("/"),g=a.length-1,t.nodeIdCompat&&x.test(a[g])&&(a[g]=a[g].replace(x,"")),"."===a[0].charAt(0)&&o&&(n=o.slice(0,o.length-1),a=n.concat(a)),k=0;k<a.length;k++)if("."===(m=a[k]))a.splice(k,1),k-=1;else if(".."===m){if(0===k||1===k&&".."===a[2]||".."===a[k-1])continue;k>0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}if((o||q)&&p){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),o)for(l=o.length;l>0;l-=1)if((e=p[o.slice(0,l).join("/")])&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&q&&q[d]&&(i=q[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,b){return function(){var c=w.call(arguments,0);return"string"!=typeof c[0]&&1===c.length&&c.push(null),o.apply(d,c.concat([a,b]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){r[a]=b}}function j(a){if(e(s,a)){var b=s[a];delete s[a],u[a]=!0,n.apply(d,b)}if(!e(r,a)&&!e(u,a))throw new Error("No "+a);return r[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return a?k(a):[]}function m(a){return function(){return t&&t.config&&t.config[a]||{}}}var n,o,p,q,r={},s={},t={},u={},v=Object.prototype.hasOwnProperty,w=[].slice,x=/\.js$/;p=function(a,b){var c,d=k(a),e=d[0],g=b[1];return a=d[1],e&&(e=f(e,g),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(g)):f(a,g):(a=f(a,g),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},q={require:function(a){return g(a)},exports:function(a){var b=r[a];return void 0!==b?b:r[a]={}},module:function(a){return{id:a,uri:"",exports:r[a],config:m(a)}}},n=function(a,b,c,f){var h,k,m,n,o,t,v,w=[],x=typeof c;if(f=f||a,t=l(f),"undefined"===x||"function"===x){for(b=!b.length&&c.length?["require","exports","module"]:b,o=0;o<b.length;o+=1)if(n=p(b[o],t),"require"===(k=n.f))w[o]=q.require(a);else if("exports"===k)w[o]=q.exports(a),v=!0;else if("module"===k)h=w[o]=q.module(a);else if(e(r,k)||e(s,k)||e(u,k))w[o]=j(k);else{if(!n.p)throw new Error(a+" missing "+k);n.p.load(n.n,g(f,!0),i(k),{}),w[o]=r[k]}m=c?c.apply(r[a],w):void 0,a&&(h&&h.exports!==d&&h.exports!==r[a]?r[a]=h.exports:m===d&&v||(r[a]=m))}else a&&(r[a]=c)},a=b=o=function(a,b,c,e,f){if("string"==typeof a)return q[a]?q[a](b):j(p(a,l(b)).f);if(!a.splice){if(t=a,t.deps&&o(t.deps,t.callback),!b)return;b.splice?(a=b,b=c,c=null):a=d}return b=b||function(){},"function"==typeof c&&(c=e,e=f),e?n(d,a,b,c):setTimeout(function(){n(d,a,b,c)},4),o},o.config=function(a){return o(a)},a._defined=r,c=function(a,b,c){if("string"!=typeof a)throw new Error("See almond README: incorrect module build, no module name");b.splice||(c=b,b=[]),e(r,a)||e(s,a)||(s[a]=[a,b,c])},c.amd={jQuery:!0}}(),c("node_modules/almond/almond.js",function(){}),c("twgl/twgl",[],function(){function a(a){ea=new Uint8Array([255*a[0],255*a[1],255*a[2],255*a[3]])}function b(a){da=a}function c(a,b){for(var c=["webgl","experimental-webgl"],d=null,e=0;e<c.length;++e){try{d=a.getContext(c[e],b)}catch(f){}if(d)break}return d}function d(a,b){return c(a,b)}function e(a){return a.split("\n").map(function(a,b){return b+1+": "+a}).join("\n")}function f(a,b,c,d){var f=d||ca,g=a.createShader(c);if(a.shaderSource(g,b),a.compileShader(g),!a.getShaderParameter(g,a.COMPILE_STATUS)){var h=a.getShaderInfoLog(g);return f(e(b)+"\n*** Error compiling shader: "+h),a.deleteShader(g),null}return g}function g(a,b,c,d,e){var f=e||ca,g=a.createProgram();if(b.forEach(function(b){a.attachShader(g,b)}),c&&c.forEach(function(b,c){a.bindAttribLocation(g,d?d[c]:c,b)}),a.linkProgram(g),!a.getProgramParameter(g,a.LINK_STATUS))return f("Error in program linking:"+a.getProgramInfoLog(g)),a.deleteProgram(g),null;return g}function h(a,b,c,d){var e,g="",h=document.getElementById(b);if(!h)throw"*** Error: unknown script element"+b;if(g=h.text,!c)if("x-shader/x-vertex"===h.type)e=a.VERTEX_SHADER;else if("x-shader/x-fragment"===h.type)e=a.FRAGMENT_SHADER;else if(e!==a.VERTEX_SHADER&&e!==a.FRAGMENT_SHADER)throw"*** Error: unknown shader type";return f(a,g,c||e,d)}function i(a,b,c,d,e){for(var f=[],i=0;i<b.length;++i){var j=h(a,b[i],a[Fa[i]],e);if(!j)return null;f.push(j)}return g(a,f,c,d,e)}function j(a,b,c,d,e){for(var h=[],i=0;i<b.length;++i){var j=f(a,b[i],a[Fa[i]],e);if(!j)return null;h.push(j)}return g(a,h,c,d,e)}function k(a,b){return b===a.SAMPLER_2D?a.TEXTURE_2D:b===a.SAMPLER_CUBE?a.TEXTURE_CUBE_MAP:void 0}function l(a,b){function c(b,c){var e=a.getUniformLocation(b,c.name),f=c.type,g=c.size>1&&"[0]"===c.name.substr(-3);if(f===a.FLOAT&&g)return function(b){a.uniform1fv(e,b)};if(f===a.FLOAT)return function(b){a.uniform1f(e,b)};if(f===a.FLOAT_VEC2)return function(b){a.uniform2fv(e,b)};if(f===a.FLOAT_VEC3)return function(b){a.uniform3fv(e,b)};if(f===a.FLOAT_VEC4)return function(b){a.uniform4fv(e,b)};if(f===a.INT&&g)return function(b){a.uniform1iv(e,b)};if(f===a.INT)return function(b){a.uniform1i(e,b)};if(f===a.INT_VEC2)return function(b){a.uniform2iv(e,b)};if(f===a.INT_VEC3)return function(b){a.uniform3iv(e,b)};if(f===a.INT_VEC4)return function(b){a.uniform4iv(e,b)};if(f===a.BOOL&&g)return function(b){a.uniform1iv(e,b)};if(f===a.BOOL)return function(b){a.uniform1i(e,b)};if(f===a.BOOL_VEC2)return function(b){a.uniform2iv(e,b)};if(f===a.BOOL_VEC3)return function(b){a.uniform3iv(e,b)};if(f===a.BOOL_VEC4)return function(b){a.uniform4iv(e,b)};if(f===a.FLOAT_MAT2)return function(b){a.uniformMatrix2fv(e,!1,b)};if(f===a.FLOAT_MAT3)return function(b){a.uniformMatrix3fv(e,!1,b)};if(f===a.FLOAT_MAT4)return function(b){a.uniformMatrix4fv(e,!1,b)};if((f===a.SAMPLER_2D||f===a.SAMPLER_CUBE)&&g){for(var h=[],i=0;i<c.size;++i)h.push(d++);return function(b,c){return function(d){a.uniform1iv(e,c),d.forEach(function(d,e){a.activeTexture(a.TEXTURE0+c[e]),a.bindTexture(b,d)})}}(k(a,f),h)}if(f===a.SAMPLER_2D||f===a.SAMPLER_CUBE)return function(b,c){return function(d){a.uniform1i(e,c),a.activeTexture(a.TEXTURE0+c),a.bindTexture(b,d)}}(k(a,f),d++);throw"unknown type: 0x"+f.toString(16)}for(var d=0,e={},f=a.getProgramParameter(b,a.ACTIVE_UNIFORMS),g=0;g<f;++g){var h=a.getActiveUniform(b,g);if(!h)break;var i=h.name;"[0]"===i.substr(-3)&&(i=i.substr(0,i.length-3));var j=c(b,h);e[i]=j}return e}function m(a,b){a=a.uniformSetters||a;for(var c=arguments.length,d=1;d<c;++d){var e=arguments[d];if(Array.isArray(e))for(var f=e.length,g=0;g<f;++g)m(a,e[g]);else for(var h in e){var i=a[h];i&&i(e[h])}}}function n(a,b){function c(b){return function(c){a.bindBuffer(a.ARRAY_BUFFER,c.buffer),a.enableVertexAttribArray(b),a.vertexAttribPointer(b,c.numComponents||c.size,c.type||a.FLOAT,c.normalize||!1,c.stride||0,c.offset||0)}}for(var d={},e=a.getProgramParameter(b,a.ACTIVE_ATTRIBUTES),f=0;f<e;++f){var g=a.getActiveAttrib(b,f);if(!g)break;var h=a.getAttribLocation(b,g.name);d[g.name]=c(h)}return d}function o(a,b){for(var c in b){var d=a[c];d&&d(b[c])}}function p(a,b,c){o(b.attribSetters||b,c.attribs),c.indices&&a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,c.indices)}function q(a,b,c,d,e){b=b.map(function(a){var b=document.getElementById(a);return b?b.text:a});var f=j(a,b,c,d,e);return f?{program:f,uniformSetters:l(a,f),attribSetters:n(a,f)}:null}function r(a,b){b=b||1,b=Math.max(1,b);var c=a.clientWidth*b|0,d=a.clientHeight*b|0;return(a.width!==c||a.height!==d)&&(a.width=c,a.height=d,!0)}function s(a,b,c,d){if(b instanceof WebGLBuffer)return b;c=c||a.ARRAY_BUFFER;var e=a.createBuffer();return a.bindBuffer(c,e),a.bufferData(c,b,d||a.STATIC_DRAW),e}function t(a){return"indices"===a}function u(a){if(a instanceof Int8Array)return ga;if(a instanceof Uint8Array)return ha;if(a instanceof Int16Array)return ia;if(a instanceof Uint16Array)return ja;if(a instanceof Int32Array)return ka;if(a instanceof Uint32Array)return la;if(a instanceof Float32Array)return ma;throw"unsupported typed array type"}function v(a,b){switch(b){case a.BYTE:return Int8Array;case a.UNSIGNED_BYTE:return Uint8Array;case a.SHORT:return Int16Array;case a.UNSIGNED_SHORT:return Uint16Array;case a.INT:return Int32Array;case a.UNSIGNED_INT:return Uint32Array;case a.FLOAT:return Float32Array;default:throw"unknown gl type"}}function w(a){return a instanceof Int8Array||a instanceof Uint8Array}function x(a){return a&&a.buffer&&a.buffer instanceof ArrayBuffer}function y(a,b){var c;if(c=a.indexOf("coord")>=0?2:a.indexOf("color")>=0?4:3,b%c>0)throw"can not guess numComponents. You should specify it.";return c}function z(a,b){if(x(a))return a;if(x(a.data))return a.data;Array.isArray(a)&&(a={data:a});var c=a.type;return c||(c="indices"===b?Uint16Array:Float32Array),new c(a.data)}function A(a,b){var c={};return Object.keys(b).forEach(function(d){if(!t(d)){var e=b[d],f=e.attrib||e.name||e.attribName||da+d,g=z(e,d);c[f]={buffer:s(a,g,void 0,e.drawType),numComponents:e.numComponents||e.size||y(d),type:u(g),normalize:void 0!==e.normalize?e.normalize:w(g),stride:e.stride||0,offset:e.offset||0}}}),c}function B(a,b){var c={attribs:A(a,b)},d=b.indices;return d?(d=z(d,"indices"),c.indices=s(a,d,a.ELEMENT_ARRAY_BUFFER),c.numElements=d.length,c.elementType=d instanceof Uint32Array?a.UNSIGNED_INT:a.UNSIGNED_SHORT):c.numElements=Ga(b),c}function C(a,b){var c={};return Object.keys(b).forEach(function(d){var e="indices"===d?a.ELEMENT_ARRAY_BUFFER:a.ARRAY_BUFFER,f=z(b[d],d);c[d]=s(a,f,e)}),c}function D(a,b,c,d,e){var f=c.indices,g=void 0===d?c.numElements:d;e=void 0===e?0:e,f?a.drawElements(b,g,void 0===c.elementType?a.UNSIGNED_SHORT:c.elementType,e):a.drawArrays(b,e,g)}function E(a,b){var c=null,d=null;b.forEach(function(b){if(!1!==b.active){var e=b.programInfo,f=b.bufferInfo,g=!1;e!==c&&(c=e,a.useProgram(e.program),g=!0),(g||f!==d)&&(d=f,p(a,e,f)),m(e,b.uniforms),D(a,b.type||a.TRIANGLES,f,b.count,b.offset)}})}function F(a,b){void 0!==b.colorspaceConversion&&(Ha.colorSpaceConversion=a.getParameter(a.UNPACK_COLORSPACE_CONVERSION_WEBGL)),void 0!==b.premultiplyAlpha&&(Ha.premultiplyAlpha=a.getParameter(a.UNPACK_PREMULTIPLY_ALPHA_WEBGL)),void 0!==b.flipY&&(Ha.flipY=a.getParameter(a.UNPACK_FLIP_Y_WEBGL))}function G(a,b){void 0!==b.colorspaceConversion&&a.pixelStorei(a.UNPACK_COLORSPACE_CONVERSION_WEBGL,Ha.colorSpaceConversion),void 0!==b.premultiplyAlpha&&a.pixelStorei(a.UNPACK_PREMULTIPLY_ALPHA_WEBGL,Ha.premultiplyAlpha),void 0!==b.flipY&&a.pixelStorei(a.UNPACK_FLIP_Y_WEBGL,Ha.flipY)}function H(a,b,c){var d=c.target||a.TEXTURE_2D;a.bindTexture(d,b),c.min&&a.texParameteri(d,a.TEXTURE_MIN_FILTER,c.min),c.mag&&a.texParameteri(d,a.TEXTURE_MAG_FILTER,c.mag),c.wrap&&(a.texParameteri(d,a.TEXTURE_WRAP_S,c.wrap),a.texParameteri(d,a.TEXTURE_WRAP_T,c.wrap)),c.wrapS&&a.texParameteri(d,a.TEXTURE_WRAP_S,c.wrapS),c.wrapT&&a.texParameteri(d,a.TEXTURE_WRAP_T,c.wrapT)}function I(a){return a=a||ea,x(a)?a:new Uint8Array([255*a[0],255*a[1],255*a[2],255*a[3]])}function J(a){return 0==(a&a-1)}function K(a,b,c,d,e){c=c||fa;var f=c.target||a.TEXTURE_2D;d=d||c.width,e=e||c.height,a.bindTexture(f,b),J(d)&&J(e)?a.generateMipmap(f):(a.texParameteri(f,a.TEXTURE_MIN_FILTER,a.LINEAR),a.texParameteri(f,a.TEXTURE_WRAP_S,a.CLAMP_TO_EDGE),a.texParameteri(f,a.TEXTURE_WRAP_T,a.CLAMP_TO_EDGE))}function L(a,b){return b=b||{},b.cubeFaceOrder||[a.TEXTURE_CUBE_MAP_POSITIVE_X,a.TEXTURE_CUBE_MAP_NEGATIVE_X,a.TEXTURE_CUBE_MAP_POSITIVE_Y,a.TEXTURE_CUBE_MAP_NEGATIVE_Y,a.TEXTURE_CUBE_MAP_POSITIVE_Z,a.TEXTURE_CUBE_MAP_NEGATIVE_Z]}function M(a,b){var c=L(a,b),d=c.map(function(a,b){return{face:a,ndx:b}});return d.sort(function(a,b){return a.face-b.face}),d}function N(a){var b={};return Object.keys(a).forEach(function(c){b[c]=a[c]}),b}function O(a,b,c){var d=new Image;return b&&(d.crossOrigin=b),d.onerror=function(){var b="couldn't load image: "+a;ca(b),c(b,d)},d.onload=function(){c(null,d)},d.src=a,d}function P(a,b,c){c=c||fa;var d=c.target||a.TEXTURE_2D;if(a.bindTexture(d,b),!1!==c.color){var e=I(c.color);if(d===a.TEXTURE_CUBE_MAP)for(var f=0;f<6;++f)a.texImage2D(a.TEXTURE_CUBE_MAP_POSITIVE_X+f,0,a.RGBA,1,1,0,a.RGBA,a.UNSIGNED_BYTE,e);else a.texImage2D(d,0,a.RGBA,1,1,0,a.RGBA,a.UNSIGNED_BYTE,e)}}function Q(a,b,c,d){return c=c||fa,P(a,b,c),c=N(c),O(c.src,c.crossOrigin,function(e,f){e?d(e,b,f):(Ia(a,b,f,c),d(null,b,f))})}function R(a,b,c,d){function e(e){return function(f,m){--k,f?l.push(f):m.width!==m.height?l.push("cubemap face img is not a square: "+m.src):(F(a,c),a.bindTexture(i,b),n.push({face:e,image:m}),0===k&&n.forEach(function(b){a.texImage2D(b.face,0,g,g,h,b.image)}),G(a,c),!1!==c.auto&&K(a,b,c,m.width,m.width),a.generateMipmap(i)),0===k&&d&&d(l.length?l:void 0,j,b)}}var f=c.src;if(6!==f.length)throw"there must be 6 urls for a cubemap";var g=c.format||a.RGBA,h=c.type||a.UNSIGNED_BYTE,i=c.target||a.TEXTURE_2D;if(i!==a.TEXTURE_CUBE_MAP)throw"target must be TEXTURE_CUBE_MAP";P(a,b,c),c=N(c);var j,k=6,l=[],m=L(a,c),n=[];j=f.map(function(a,b){return O(a,c.crossOrigin,e(m[b]))})}function S(a){switch(a){case na:case qa:return 1;case ra:return 2;case oa:return 3;case pa:return 4;default:throw"unknown type: "+a}}function T(a,b){return x(b)?u(b):a.UNSIGNED_BYTE}function U(a,b,c,d){d=d||fa;var e=d.target||a.TEXTURE_2D,f=d.width,g=d.height,h=d.format||a.RGBA,i=d.type||T(a,c),j=S(h),k=c.length/j;if(k%1)throw"length wrong size of format: "+Ea(a,h);if(f||g){if(g){if(!f&&(f=k/g)%1)throw"can't guess width"}else if((g=k/f)%1)throw"can't guess height"}else{var l=Math.sqrt(k/(e===a.TEXTURE_CUBE_MAP?6:1));l%1==0?(f=l,g=l):(f=k,g=1)}if(!x(c)){var m=v(a,i);c=new m(c)}if(a.pixelStorei(a.UNPACK_ALIGNMENT,d.unpackAlignment||1),F(a,d),e===a.TEXTURE_CUBE_MAP){var n=k/6*j;M(a,d).forEach(function(b){var d=n*b.ndx,e=c.subarray(d,d+n);a.texImage2D(b.face,0,h,f,g,0,h,i,e)})}else a.texImage2D(e,0,h,f,g,0,h,i,c);return G(a,d),{width:f,height:g}}function V(a,b,c){var d=c.target||a.TEXTURE_2D;a.bindTexture(d,b);var e=c.format||a.RGBA,f=c.type||a.UNSIGNED_BYTE;if(F(a,c),d===a.TEXTURE_CUBE_MAP)for(var g=0;g<6;++g)a.texImage2D(a.TEXTURE_CUBE_MAP_POSITIVE_X+g,0,e,c.width,c.height,0,e,f,null);else a.texImage2D(d,0,e,c.width,c.height,0,e,f,null)}function W(a,b,c){b=b||fa;var d=a.createTexture(),e=b.target||a.TEXTURE_2D,f=b.width||1,g=b.height||1;a.bindTexture(e,d),e===a.TEXTURE_CUBE_MAP&&(a.texParameteri(e,a.TEXTURE_WRAP_S,a.CLAMP_TO_EDGE),a.texParameteri(e,a.TEXTURE_WRAP_T,a.CLAMP_TO_EDGE));var h=b.src;if(h)if("function"==typeof h&&(h=h(a,b)),"string"==typeof h)Q(a,d,b,c);else if(x(h)||Array.isArray(h)&&("number"==typeof h[0]||Array.isArray(h[0])||x(h[0]))){var i=U(a,d,h,b);f=i.width,g=i.height}else if(Array.isArray(h)&&"string"==typeof h[0])R(a,d,b,c);else{if(!(h instanceof HTMLElement))throw"unsupported src type";Ia(a,d,h,b),f=h.width,g=h.height}else V(a,d,b);return!1!==b.auto&&K(a,d,b,f,g),H(a,d,b),d}function X(a,b,c,d,e){d=d||c.width,e=e||c.height;var f=c.target||a.TEXTURE_2D;a.bindTexture(f,b);var g,h=c.format||a.RGBA,i=c.src;if(g=i&&(x(i)||Array.isArray(i)&&"number"==typeof i[0])?c.type||T(a,i):c.type||a.UNSIGNED_BYTE,f===a.TEXTURE_CUBE_MAP)for(var j=0;j<6;++j)a.texImage2D(a.TEXTURE_CUBE_MAP_POSITIVE_X+j,0,h,d,e,0,h,g,null);else a.texImage2D(f,0,h,d,e,0,h,g,null)}function Y(a){return"string"==typeof a||Array.isArray(a)&&"string"==typeof a[0]}function Z(a,b,c){function d(){0===f&&c&&setTimeout(function(){c(g.length?g:void 0,b)},0)}function e(a){--f,a&&g.push(a),d()}var f=0,g=[],h={};return Object.keys(b).forEach(function(c){var d=b[c],g=void 0;Y(d.src)&&(g=e,++f),h[c]=W(a,d,g)}),d(),h}function $(a){return Ka[a]}function _(a){return La[a]}function aa(a,b,c,d){var e=a.FRAMEBUFFER,f=a.createFramebuffer();a.bindFramebuffer(e,f),c=c||a.drawingBufferWidth,d=d||a.drawingBufferHeight,b=b||Ja;var g=0,h={framebuffer:f,attachments:[]};return b.forEach(function(b){var f=b.attachment,i=b.format,j=$(i);if(j||(j=za+g++),!f)if(_(i))f=a.createRenderbuffer(),a.bindRenderbuffer(a.RENDERBUFFER,f),a.renderbufferStorage(a.RENDERBUFFER,i,c,d);else{var k=N(b);k.width=c,k.height=d,k.auto=void 0!==b.auto&&b.auto,f=W(a,k)}if(f instanceof WebGLRenderbuffer)a.framebufferRenderbuffer(e,j,a.RENDERBUFFER,f);else{if(!(f instanceof WebGLTexture))throw"unknown attachment type";a.framebufferTexture2D(e,j,b.texTarget||a.TEXTURE_2D,f,b.level||0)}h.attachments.push(f)}),h}function ba(a,b,c,d,e){d=d||a.drawingBufferWidth,e=e||a.drawingBufferHeight,c=c||Ja,c.forEach(function(c,f){var g=b.attachments[f],h=c.format;if(g instanceof WebGLRenderbuffer)a.bindRenderbuffer(a.RENDERBUFFER,g),a.renderbufferStorage(a.RENDERBUFFER,h,d,e);else{if(!(g instanceof WebGLTexture))throw"unknown attachment type";X(a,g,c,d,e)}})}var ca=window.console&&window.console.error?window.console.error.bind(window.console):function(){},da="",ea=new Uint8Array([128,192,255,255]),fa={},ga=5120,ha=5121,ia=5122,ja=5123,ka=5124,la=5125,ma=5126,na=6406,oa=6407,pa=6408,qa=6409,ra=6410,sa=32854,ta=32855,ua=36194,va=33189,wa=6401,xa=36168,ya=34041,za=36064,Aa=36096,Ba=36128,Ca=33071,Da=9729,Ea=function(){function a(a){b||(b={},Object.keys(a).forEach(function(c){"number"==typeof a[c]&&(b[a[c]]=c)}))}var b;return function(c,d){return a(),b[d]||"0x"+d.toString(16)}}(),Fa=["VERTEX_SHADER","FRAGMENT_SHADER"],Ga=function(){var a=["position","positions","a_position"];return function(b){for(var c,d=0;d<a.length&&!((c=a[d])in b);++d);d===a.length&&(c=Object.keys(b)[0]);var e=b[c],f=e.length||e.data.length,g=e.numComponents||y(c,f),h=f/g;if(f%g>0)throw"numComponents "+g+" not correct for length "+f;return h}}(),Ha={},Ia=function(){var a=document.createElement("canvas").getContext("2d");return function(b,c,d,e){e=e||fa;var f=e.target||b.TEXTURE_2D,g=d.width,h=d.height,i=e.format||b.RGBA,j=e.type||b.UNSIGNED_BYTE;if(F(b,e),b.bindTexture(f,c),f===b.TEXTURE_CUBE_MAP){var k,l,m=d.width,n=d.height,o=[0,0,0,0,0,0];if(m/6===n)k=n,l=[0,0,1,0,2,0,3,0,4,0,5,0];else if(m/6==n/2)k=n/2,l=[0,0,1,0,2,0,3,0,4,0,5,0];else if(n/6===m)k=m,l=[0,0,0,1,0,2,0,3,0,4,0,5];else if(m/3==n/2)k=m/3,l=[0,0,1,0,2,0,0,1,1,1,2,1];else if(m/2==n/3)k=m/2,l=[0,0,1,0,0,1,1,1,0,2,1,2];else{if(m/4!=n/3)throw"can't figure out cube map from element: "+(d.src?d.src:d.nodeName);k=m/4,l=[3,1,1,1,1,0,1,2,0,1,2,1],o=[0,0,90,270,0,0]}var p=k;e.isBadGpu&&k>256&&(p=1024),a.canvas.width=p,a.canvas.height=p,g=k,h=k;var q=e.shift?k:0;M(b,e).forEach(function(c){var e=l[2*c.ndx+0]*k,f=l[2*c.ndx+1]*k+q;a.translate(p/2,p/2),a.rotate(o[c.ndx]*Math.PI/180),a.drawImage(d,e,f,k,k,-p/2-1,-p/2-1,p+2,p+2),a.setTransform(1,0,0,1,0,0),b.texImage2D(c.face,0,i,i,j,a.canvas)}),a.canvas.width=1,a.canvas.height=1}else b.texImage2D(f,0,i,i,j,d);G(b,e),!1!==e.auto&&K(b,c,e,g,h),H(b,c,e)}}(),Ja=[{format:pa,type:ha,min:Da,wrap:Ca},{format:ya}],Ka={};Ka[ya]=33306,Ka[wa]=Ba,Ka[xa]=Ba,Ka[6402]=Aa,Ka[va]=Aa;var La={};return La[sa]=!0,La[ta]=!0,La[ua]=!0,La[ya]=!0,La[va]=!0,La[wa]=!0,La[xa]=!0,{createAttribsFromArrays:A,createBuffersFromArrays:C,createBufferInfoFromArrays:B,createAttributeSetters:n,createProgram:g,createProgramFromScripts:i,createProgramFromSources:j,createProgramInfo:q,createUniformSetters:l,drawBufferInfo:D,drawObjectList:E,getWebGLContext:d,resizeCanvasToDisplaySize:r,setAttributes:o,setAttributePrefix:b,setBuffersAndAttributes:p,setUniforms:m,createTexture:W,setEmptyTexture:V,setTextureFromArray:U,loadTextureFromUrl:Q,setTextureFromElement:Ia,setTextureFilteringForSize:K,setTextureParameters:H,setDefaultTextureColor:a,createTextures:Z,resizeTexture:X,createFramebufferInfo:aa,resizeFramebufferInfo:ba,loadCubemapFromUrls:R}}),c("twgl/v3",[],function(){function a(a){q=a}function b(){return new q(3)}function c(a,b,c){return c=c||new q(3),c[0]=a[0]+b[0],c[1]=a[1]+b[1],c[2]=a[2]+b[2],c}function d(a,b,c){return c=c||new q(3),c[0]=a[0]-b[0],c[1]=a[1]-b[1],c[2]=a[2]-b[2],c}function e(a,b,c,d){return d=d||new q(3),d[0]=(1-c)*a[0]+c*b[0],d[1]=(1-c)*a[1]+c*b[1],d[2]=(1-c)*a[2]+c*b[2],d}function f(a,b,c){return c=c||new q(3),c[0]=a[0]*b,c[1]=a[1]*b,c[2]=a[2]*b,c}function g(a,b,c){return c=c||new q(3),c[0]=a[0]/b,c[1]=a[1]/b,c[2]=a[2]/b,c}function h(a,b,c){return c=c||new q(3),c[0]=a[1]*b[2]-a[2]*b[1],c[1]=a[2]*b[0]-a[0]*b[2],c[2]=a[0]*b[1]-a[1]*b[0],c}function i(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]}function j(a){return Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2])}function k(a){return a[0]*a[0]+a[1]*a[1]+a[2]*a[2]}function l(a,b){b=b||new q(3);var c=a[0]*a[0]+a[1]*a[1]+a[2]*a[2],d=Math.sqrt(c);return d>1e-5?(b[0]=a[0]/d,b[1]=a[1]/d,b[2]=a[2]/d):(b[0]=0,b[1]=0,b[2]=0),b}function m(a,b){return b=b||new q(3),b[0]=-a[0],b[1]=-a[1],b[2]=-a[2],b}function n(a,b){return b=b||new q(3),b[0]=a[0],b[1]=a[1],b[2]=a[2],b}function o(a,b,c){return c=c||new q(3),c[0]=a[0]*b[0],c[1]=a[1]*b[1],c[2]=a[2]*b[2],c}function p(a,b,c){return c=c||new q(3),c[0]=a[0]/b[0],c[1]=a[1]/b[1],c[2]=a[2]/b[2],c}var q=Float32Array;return{add:c,copy:n,create:b,cross:h,divide:p,divScalar:g,dot:i,lerp:e,length:j,lengthSq:k,mulScalar:f,multiply:o,negate:m,normalize:l,setDefaultType:a,subtract:d}}),c("twgl/m4",["./v3"],function(a){function b(a){VecType=a}function c(a,b){return b=b||new K(16),b[0]=-a[0],b[1]=-a[1],b[2]=-a[2],b[3]=-a[3],b[4]=-a[4],b[5]=-a[5],b[6]=-a[6],b[7]=-a[7],b[8]=-a[8],b[9]=-a[9],b[10]=-a[10],b[11]=-a[11],b[12]=-a[12],b[13]=-a[13],b[14]=-a[14],b[15]=-a[15],b}function d(a,b){return b=b||new K(16),b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3],b[4]=a[4],b[5]=a[5],b[6]=a[6],b[7]=a[7],b[8]=a[8],b[9]=a[9],b[10]=a[10],b[11]=a[11],b[12]=a[12],b[13]=a[13],b[14]=a[14],b[15]=a[15],b}function e(a){return a=a||new K(16),a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1,a}function f(a,b){if((b=b||new K(16))===a){var c;return c=a[1],a[1]=a[4],a[4]=c,c=a[2],a[2]=a[8],a[8]=c,c=a[3],a[3]=a[12],a[12]=c,c=a[6],a[6]=a[9],a[9]=c,c=a[7],a[7]=a[13],a[13]=c,c=a[11],a[11]=a[14],a[14]=c,b}var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],m=a[9],n=a[10],o=a[11],p=a[12],q=a[13],r=a[14],s=a[15];return b[0]=d,b[1]=h,b[2]=l,b[3]=p,b[4]=e,b[5]=i,b[6]=m,b[7]=q,b[8]=f,b[9]=j,b[10]=n,b[11]=r,b[12]=g,b[13]=k,b[14]=o,b[15]=s,b}function g(a,b){b=b||new K(16);var c=a[0],d=a[1],e=a[2],f=a[3],g=a[4],h=a[5],i=a[6],j=a[7],k=a[8],l=a[9],m=a[10],n=a[11],o=a[12],p=a[13],q=a[14],r=a[15],s=m*r,t=q*n,u=i*r,v=q*j,w=i*n,x=m*j,y=e*r,z=q*f,A=e*n,B=m*f,C=e*j,D=i*f,E=k*p,F=o*l,G=g*p,H=o*h,I=g*l,J=k*h,L=c*p,M=o*d,N=c*l,O=k*d,P=c*h,Q=g*d,R=s*h+v*l+w*p-(t*h+u*l+x*p),S=t*d+y*l+B*p-(s*d+z*l+A*p),T=u*d+z*h+C*p-(v*d+y*h+D*p),U=x*d+A*h+D*l-(w*d+B*h+C*l),V=1/(c*R+g*S+k*T+o*U);return b[0]=V*R,b[1]=V*S,b[2]=V*T,b[3]=V*U,b[4]=V*(t*g+u*k+x*o-(s*g+v*k+w*o)),b[5]=V*(s*c+z*k+A*o-(t*c+y*k+B*o)),b[6]=V*(v*c+y*g+D*o-(u*c+z*g+C*o)),b[7]=V*(w*c+B*g+C*k-(x*c+A*g+D*k)),b[8]=V*(E*j+H*n+I*r-(F*j+G*n+J*r)),b[9]=V*(F*f+L*n+O*r-(E*f+M*n+N*r)),b[10]=V*(G*f+M*j+P*r-(H*f+L*j+Q*r)),b[11]=V*(J*f+N*j+Q*n-(I*f+O*j+P*n)),b[12]=V*(G*m+J*q+F*i-(I*q+E*i+H*m)),b[13]=V*(N*q+E*e+M*m-(L*m+O*q+F*e)),b[14]=V*(L*i+Q*q+H*e-(P*q+G*e+M*i)),b[15]=V*(P*m+I*e+O*i-(N*i+Q*m+J*e)),b}function h(a,b,c){c=c||new K(16);var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],m=a[9],n=a[10],o=a[11],p=a[12],q=a[13],r=a[14],s=a[15],t=b[0],u=b[1],v=b[2],w=b[3],x=b[4],y=b[5],z=b[6],A=b[7],B=b[8],C=b[9],D=b[10],E=b[11],F=b[12],G=b[13],H=b[14],I=b[15];return c[0]=d*t+e*x+f*B+g*F,c[1]=d*u+e*y+f*C+g*G,c[2]=d*v+e*z+f*D+g*H,c[3]=d*w+e*A+f*E+g*I,c[4]=h*t+i*x+j*B+k*F,c[5]=h*u+i*y+j*C+k*G,c[6]=h*v+i*z+j*D+k*H,c[7]=h*w+i*A+j*E+k*I,c[8]=l*t+m*x+n*B+o*F,c[9]=l*u+m*y+n*C+o*G,c[10]=l*v+m*z+n*D+o*H,c[11]=l*w+m*A+n*E+o*I,c[12]=p*t+q*x+r*B+s*F,c[13]=p*u+q*y+r*C+s*G,c[14]=p*v+q*z+r*D+s*H,c[15]=p*w+q*A+r*E+s*I,c}function i(a,b,c){return c=c||e(),a!==c&&(c[0]=a[0],c[1]=a[1],c[2]=a[2],c[3]=a[3],c[4]=a[4],c[5]=a[5],c[6]=a[6],c[7]=a[7],c[8]=a[8],c[9]=a[9],c[10]=a[10],c[11]=a[11]),c[12]=b[0],c[13]=b[1],c[14]=b[2],c[15]=1,c}function j(b,c){return c=c||a.create(),c[0]=b[12],c[1]=b[13],c[2]=b[14],c}function k(b,c,d){d=d||a.create();var e=4*c;return d[0]=b[e+0],d[1]=b[e+1],d[2]=b[e+2],d}function l(a,b,c,d,e){e=e||new K(16);var f=Math.tan(.5*Math.PI-.5*a),g=1/(c-d);return e[0]=f/b,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=f,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=(c+d)*g,e[11]=-1,e[12]=0,e[13]=0,e[14]=c*d*g*2,e[15]=0,e}function m(a,b,c,d,e,f,g){return g=g||new K(16),g[0]=2/(b-a),g[1]=0,g[2]=0,g[3]=0,g[4]=0,g[5]=2/(d-c),g[6]=0,g[7]=0,g[8]=0,g[9]=0,g[10]=-1/(f-e),g[11]=0,g[12]=(b+a)/(a-b),g[13]=(d+c)/(c-d),g[14]=-e/(e-f),g[15]=1,g}function n(a,b,c,d,e,f,g){g=g||new K(16);var h=b-a,i=d-c,j=e-f;return g[0]=2*e/h,g[1]=0,g[2]=0,g[3]=0,g[4]=0,g[5]=2*e/i,g[6]=0,g[7]=0,g[8]=(a+b)/h,g[9]=(d+c)/i,g[10]=f/j,g[11]=-1,g[12]=0,g[13]=0,g[14]=e*f/j,g[15]=0,g}function o(b,c,d,e){e=e||new K(16);var f=L,g=M,h=N;return a.normalize(a.subtract(b,c,h),h),a.normalize(a.cross(d,h,f),f),a.normalize(a.cross(h,f,g),g),e[0]=f[0],e[1]=f[1],e[2]=f[2],e[3]=0,e[4]=g[0],e[5]=g[1],e[6]=g[2],e[7]=0,e[8]=h[0],e[9]=h[1],e[10]=h[2],e[11]=0,e[12]=b[0],e[13]=b[1],e[14]=b[2],e[15]=1,e}function p(a,b){return b=b||new K(16),b[0]=1,b[1]=0,b[2]=0,b[3]=0,b[4]=0,b[5]=1,b[6]=0,b[7]=0,b[8]=0,b[9]=0,b[10]=1,b[11]=0,b[12]=a[0],b[13]=a[1],b[14]=a[2],b[15]=1,b}function q(a,b,c){c=c||new K(16);var d=b[0],e=b[1],f=b[2],g=a[0],h=a[1],i=a[2],j=a[3],k=a[4],l=a[5],m=a[6],n=a[7],o=a[8],p=a[9],q=a[10],r=a[11],s=a[12],t=a[13],u=a[14],v=a[15];return a!==c&&(c[0]=g,c[1]=h,c[2]=i,c[3]=j,c[4]=k,c[5]=l,c[6]=m,c[7]=n,c[8]=o,c[9]=p,c[10]=q,c[11]=r),c[12]=g*d+k*e+o*f+s,c[13]=h*d+l*e+p*f+t,c[14]=i*d+m*e+q*f+u,c[15]=j*d+n*e+r*f+v,c}function r(a,b){b=b||new K(16);var c=Math.cos(a),d=Math.sin(a);return b[0]=1,b[1]=0,b[2]=0,b[3]=0,b[4]=0,b[5]=c,b[6]=d,b[7]=0,b[8]=0,b[9]=-d,b[10]=c,b[11]=0,b[12]=0,b[13]=0,b[14]=0,b[15]=1,b}function s(a,b,c){c=c||new K(16);var d=a[4],e=a[5],f=a[6],g=a[7],h=a[8],i=a[9],j=a[10],k=a[11],l=Math.cos(b),m=Math.sin(b);return c[4]=l*d+m*h,c[5]=l*e+m*i,c[6]=l*f+m*j,c[7]=l*g+m*k,c[8]=l*h-m*d,c[9]=l*i-m*e,c[10]=l*j-m*f,c[11]=l*k-m*g,a!==c&&(c[0]=a[0],c[1]=a[1],c[2]=a[2],c[3]=a[3],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]),c}function t(a,b){b=b||new K(16);var c=Math.cos(a),d=Math.sin(a);return b[0]=c,b[1]=0,b[2]=-d,b[3]=0,b[4]=0,b[5]=1,b[6]=0,b[7]=0,b[8]=d,b[9]=0,b[10]=c,b[11]=0,b[12]=0,b[13]=0,b[14]=0,b[15]=1,b}function u(a,b,c){c=c||new K(16);var d=a[0],e=a[1],f=a[2],g=a[3],h=a[8],i=a[9],j=a[10],k=a[11],l=Math.cos(b),m=Math.sin(b);return c[0]=l*d-m*h,c[1]=l*e-m*i,c[2]=l*f-m*j,c[3]=l*g-m*k,c[8]=l*h+m*d,c[9]=l*i+m*e,c[10]=l*j+m*f,c[11]=l*k+m*g,a!==c&&(c[4]=a[4],c[5]=a[5],c[6]=a[6],c[7]=a[7],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]),c}function v(a,b){b=b||new K(16);var c=Math.cos(a),d=Math.sin(a);return b[0]=c,b[1]=d,b[2]=0,b[3]=0,b[4]=-d,b[5]=c,b[6]=0,b[7]=0,b[8]=0,b[9]=0,b[10]=1,b[11]=0,b[12]=0,b[13]=0,b[14]=0,b[15]=1,b}function A(a,b,c){c=c||new K(16);var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=Math.cos(b),m=Math.sin(b);return c[0]=l*d+m*h,c[1]=l*e+m*i,c[2]=l*f+m*j,c[3]=l*g+m*k,c[4]=l*h-m*d,c[5]=l*i-m*e,c[6]=l*j-m*f,c[7]=l*k-m*g,a!==c&&(c[8]=a[8],c[9]=a[9],c[10]=a[10],c[11]=a[11],c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]),c}function B(a,b,c){c=c||new K(16);var d=a[0],e=a[1],f=a[2],g=Math.sqrt(d*d+e*e+f*f);d/=g,e/=g,f/=g;var h=d*d,i=e*e,j=f*f,k=Math.cos(b),l=Math.sin(b),m=1-k;return c[0]=h+(1-h)*k,c[1]=d*e*m+f*l,c[2]=d*f*m-e*l,c[3]=0,c[4]=d*e*m-f*l,c[5]=i+(1-i)*k,c[6]=e*f*m+d*l,c[7]=0,c[8]=d*f*m+e*l,c[9]=e*f*m-d*l,c[10]=j+(1-j)*k,c[11]=0,c[12]=0,c[13]=0,c[14]=0,c[15]=1,c}function C(a,b,c,d){d=d||new K(16);var e=b[0],f=b[1],g=b[2],h=Math.sqrt(e*e+f*f+g*g);e/=h,f/=h,g/=h;var i=e*e,j=f*f,k=g*g,l=Math.cos(c),m=Math.sin(c),n=1-l,o=i+(1-i)*l,p=e*f*n+g*m,q=e*g*n-f*m,r=e*f*n-g*m,s=j+(1-j)*l,t=f*g*n+e*m,u=e*g*n+f*m,v=f*g*n-e*m,w=k+(1-k)*l,x=a[0],y=a[1],z=a[2],A=a[3],B=a[4],C=a[5],D=a[6],E=a[7],F=a[8],G=a[9],H=a[10],I=a[11];return d[0]=o*x+p*B+q*F,d[1]=o*y+p*C+q*G,d[2]=o*z+p*D+q*H,d[3]=o*A+p*E+q*I,d[4]=r*x+s*B+t*F,d[5]=r*y+s*C+t*G,d[6]=r*z+s*D+t*H,d[7]=r*A+s*E+t*I,d[8]=u*x+v*B+w*F,d[9]=u*y+v*C+w*G,d[10]=u*z+v*D+w*H,d[11]=u*A+v*E+w*I,a!==d&&(d[12]=a[12],d[13]=a[13],d[14]=a[14],d[15]=a[15]),d}function D(a,b){return b=b||new K(16),b[0]=a[0],b[1]=0,b[2]=0,b[3]=0,b[4]=0,b[5]=a[1],b[6]=0,b[7]=0,b[8]=0,b[9]=0,b[10]=a[2],b[11]=0,b[12]=0,b[13]=0,b[14]=0,b[15]=1,b}function E(a,b,c){c=c||new K(16);var d=b[0],e=b[1],f=b[2];return c[0]=d*a[0],c[1]=d*a[1],c[2]=d*a[2],c[3]=d*a[3],c[4]=e*a[4],c[5]=e*a[5],c[6]=e*a[6],c[7]=e*a[7],c[8]=f*a[8],c[9]=f*a[9],c[10]=f*a[10],c[11]=f*a[11],a!==c&&(c[12]=a[12],c[13]=a[13],c[14]=a[14],c[15]=a[15]),a}function F(b,c,d){d=d||a.create();var e=c[0],f=c[1],g=c[2],h=e*b[3]+f*b[7]+g*b[11]+b[15];return d[0]=(e*b[0]+f*b[4]+g*b[8]+b[12])/h,d[1]=(e*b[1]+f*b[5]+g*b[9]+b[13])/h,d[2]=(e*b[2]+f*b[6]+g*b[10]+b[14])/h,d}function G(b,c,d){d=d||a.create();var e=c[0],f=c[1],g=c[2];return d[0]=e*b[0]+f*b[4]+g*b[8],d[1]=e*b[1]+f*b[5]+g*b[9],d[2]=e*b[2]+f*b[6]+g*b[10],d}function H(b,c,d){d=d||a.create();var e=g(b),f=c[0],h=c[1],i=c[2];return d[0]=f*e[0]+h*e[1]+i*e[2],d[1]=f*e[4]+h*e[5]+i*e[6],d[2]=f*e[8]+h*e[9]+i*e[10],d}function I(a,b,c){var d=a[0],e=a[1],f=a[2],g=a[3],h=d+d,i=e+e,j=f+f,k=d*h,l=d*i,m=d*j,n=e*i,o=e*j,p=f*j,q=g*h,r=g*i,s=g*j;return c[0]=1-(n+p),c[1]=l+s,c[2]=m-r,c[3]=0,c[4]=l-s,c[5]=1-(k+p),c[6]=o+q,c[7]=0,c[8]=m+r,c[9]=o-q,c[10]=1-(k+n),c[11]=0,c[12]=b[0],c[13]=b[1],c[14]=b[2],c[15]=1,c}function J(a,b,c){var d=Math.cos(a/2),e=Math.sin(a/2),f=Math.cos(b/2),g=Math.sin(b/2),h=Math.cos(c/2),i=Math.sin(c/2),j=d*f,k=e*g;return w=j*h-k*i,x=j*i+k*h,y=e*f*h+d*g*i,z=d*g*h-e*f*i,[x,y,z,w]}var K=Float32Array,L=a.create(),M=a.create(),N=a.create();return{axisRotate:C,axisRotation:B,create:e,copy:d,frustum:n,getAxis:k,getTranslation:j,identity:e,inverse:g,lookAt:o,multiply:h,negate:c,ortho:m,perspective:l,rotateX:s,rotateY:u,rotateZ:A,rotationX:r,rotationY:t,rotationZ:v,scale:E,scaling:D,setDefaultType:b,setTranslation:i,transformDirection:G,transformNormal:H,transformPoint:F,translate:q,translation:p,transpose:f,eularToQuat:J,fromRotationTranslation:I}}),c("twgl/primitives",["./twgl","./m4","./v3"],function(a,b,c){function d(a,b){var c=0;return a.push=function(){for(var b=0;b<arguments.length;++b){var d=arguments[b];if(d instanceof Array||d.buffer&&d.buffer instanceof ArrayBuffer)for(var e=0;e<d.length;++e)a[c++]=d[e];else a[c++]=d}},a.reset=function(a){c=a||0},a.numComponents=b,Object.defineProperty(a,"numElements",{get:function(){return this.length/this.numComponents|0}}),a}function e(a,b,c){return d(new(c||Float32Array)(a*b),a)}function f(a){return"indices"!==a}function g(a){function b(b){for(var f=a[b],h=f.numComponents,i=e(h,g,f.constructor),j=0;j<g;++j)for(var k=c[j],l=k*h,m=0;m<h;++m)i.push(f[l+m]);d[b]=i}var c=a.indices,d={},g=c.length;return Object.keys(a).filter(f).forEach(b),d}function h(a){if(a.indices)throw"can't flatten normals of indexed vertices. deindex them first";for(var b=a.normal,c=b.length,d=0;d<c;d+=9){var e=b[d+0],f=b[d+1],g=b[d+2],h=b[d+3],i=b[d+4],j=b[d+5],k=b[d+6],l=b[d+7],m=b[d+8],n=e+h+k,o=f+i+l,p=g+j+m,q=Math.sqrt(n*n+o*o+p*p);n/=q,o/=q,p/=q,b[d+0]=n,b[d+1]=o,b[d+2]=p,b[d+3]=n,b[d+4]=o,b[d+5]=p,b[d+6]=n,b[d+7]=o,b[d+8]=p}return a}function i(a,b,c){for(var d=a.length,e=new Float32Array(3),f=0;f<d;f+=3)c(b,[a[f],a[f+1],a[f+2]],e),a[f]=e[0],a[f+1]=e[1],a[f+2]=e[2]}function j(a,b,d){d=d||c.create();var e=b[0],f=b[1],g=b[2];return d[0]=e*a[0]+f*a[1]+g*a[2],d[1]=e*a[4]+f*a[5]+g*a[6],d[2]=e*a[8]+f*a[9]+g*a[10],d}function k(a,c){return i(a,c,b.transformDirection),a}function l(a,c){return i(a,b.inverse(c),j),a}function m(a,c){return i(a,c,b.transformPoint),a}function n(a,b){return Object.keys(a).forEach(function(c){var d=a[c];c.indexOf("pos")>=0?m(d,b):c.indexOf("tan")>=0||c.indexOf("binorm")>=0?k(d,b):c.indexOf("norm")>=0&&l(d,b)}),a}function o(a,b,c){return a=a||2,b=b||0,c=c||0,a*=.5,{position:{numComponents:2,data:[b+-1*a,c+-1*a,b+1*a,c+-1*a,b+-1*a,c+1*a,b+1*a,c+1*a]},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]}}function p(a,c,d,f,g){a=a||1,c=c||1,d=d||1,f=f||1,g=g||b.identity();for(var h=(d+1)*(f+1),i=e(3,h),j=e(3,h),k=e(2,h),l=0;l<=f;l++)for(var m=0;m<=d;m++){
var o=m/d,p=l/f;i.push(a*o-.5*a,0,c*p-.5*c),j.push(0,1,0),k.push(o,p)}for(var q=d+1,r=e(3,d*f*2,Uint16Array),l=0;l<f;l++)for(var m=0;m<d;m++)r.push((l+0)*q+m,(l+1)*q+m,(l+0)*q+m+1),r.push((l+1)*q+m,(l+1)*q+m+1,(l+0)*q+m+1);return n({position:i,normal:j,texcoord:k,indices:r},g)}function q(a,b,c,d,f,g,h){if(b<=0||c<=0)throw Error("subdivisionAxis and subdivisionHeight must be > 0");d=d||0,f=f||Math.PI,g=g||0,h=h||2*Math.PI;for(var i=f-d,j=h-g,k=(b+1)*(c+1),l=e(3,k),m=e(3,k),n=e(2,k),o=0;o<=c;o++)for(var p=0;p<=b;p++){var q=p/b,r=o/c,s=j*q,t=i*r,u=Math.sin(s),v=Math.cos(s),w=Math.sin(t),x=Math.cos(t),y=v*w,z=x,A=u*w;l.push(a*y,a*z,a*A),m.push(y,z,A),n.push(1-q,r)}for(var B=b+1,C=e(3,b*c*2,Uint16Array),p=0;p<b;p++)for(var o=0;o<c;o++)C.push((o+0)*B+p,(o+0)*B+p+1,(o+1)*B+p),C.push((o+1)*B+p,(o+0)*B+p+1,(o+1)*B+p+1);return{position:l,normal:m,texcoord:n,indices:C}}function r(a){a=a||1;for(var b=a/2,c=[[-b,-b,-b],[+b,-b,-b],[-b,+b,-b],[+b,+b,-b],[-b,-b,+b],[+b,-b,+b],[-b,+b,+b],[+b,+b,+b]],d=[[1,0,0],[-1,0,0],[0,1,0],[0,-1,0],[0,0,1],[0,0,-1]],f=[[1,0],[0,0],[0,1],[1,1]],g=24,h=e(3,g),i=e(3,g),j=e(2,g),k=e(3,12,Uint16Array),l=0;l<6;++l){for(var m=D[l],n=0;n<4;++n){var o=c[m[n]],p=d[l],q=f[n];h.push(o),i.push(p),j.push(q)}var r=4*l;k.push(r+0,r+1,r+2),k.push(r+0,r+2,r+3)}return{position:h,normal:i,texcoord:j,indices:k}}function s(a,b,c,d,f,g,h){if(d<3)throw Error("radialSubdivisions must be 3 or greater");if(f<1)throw Error("verticalSubdivisions must be 1 or greater");for(var i=void 0===g||g,j=void 0===h||h,k=(i?2:0)+(j?2:0),l=(d+1)*(f+1+k),m=e(3,l),n=e(3,l),o=e(2,l),p=e(3,d*(f+k)*2,Uint16Array),q=d+1,r=Math.atan2(a-b,c),s=Math.cos(r),t=Math.sin(r),u=i?-2:0,v=f+(j?2:0),w=u;w<=v;++w){var x,y=w/f,z=c*y;w<0?(z=0,y=1,x=a):w>f?(z=c,y=1,x=b):x=a+w/f*(b-a),-2!==w&&w!==f+2||(x=0,y=0),z-=c/2;for(var A=0;A<q;++A){var B=Math.sin(A*Math.PI*2/d),C=Math.cos(A*Math.PI*2/d);m.push(B*x,z,C*x),n.push(w<0||w>f?0:B*s,w<0?-1:w>f?1:t,w<0||w>f?0:C*s),o.push(A/d,1-y)}}for(var w=0;w<f+k;++w)for(var A=0;A<d;++A)p.push(q*(w+0)+0+A,q*(w+0)+1+A,q*(w+1)+1+A),p.push(q*(w+0)+0+A,q*(w+1)+1+A,q*(w+1)+0+A);return{position:m,normal:n,texcoord:o,indices:p}}function t(a,b){b=b||[];for(var c=[],d=0;d<a.length;d+=4){var e=a[d],f=a.slice(d+1,d+4);f.push.apply(f,b);for(var g=0;g<e;++g)c.push.apply(c,f)}return c}function u(){var a=[0,0,0,0,150,0,30,0,0,0,150,0,30,150,0,30,0,0,30,0,0,30,30,0,100,0,0,30,30,0,100,30,0,100,0,0,30,60,0,30,90,0,67,60,0,30,90,0,67,90,0,67,60,0,0,0,30,30,0,30,0,150,30,0,150,30,30,0,30,30,150,30,30,0,30,100,0,30,30,30,30,30,30,30,100,0,30,100,30,30,30,60,30,67,60,30,30,90,30,30,90,30,67,60,30,67,90,30,0,0,0,100,0,0,100,0,30,0,0,0,100,0,30,0,0,30,100,0,0,100,30,0,100,30,30,100,0,0,100,30,30,100,0,30,30,30,0,30,30,30,100,30,30,30,30,0,100,30,30,100,30,0,30,30,0,30,60,30,30,30,30,30,30,0,30,60,0,30,60,30,30,60,0,67,60,30,30,60,30,30,60,0,67,60,0,67,60,30,67,60,0,67,90,30,67,60,30,67,60,0,67,90,0,67,90,30,30,90,0,30,90,30,67,90,30,30,90,0,67,90,30,67,90,0,30,90,0,30,150,30,30,90,30,30,90,0,30,150,0,30,150,30,0,150,0,0,150,30,30,150,30,0,150,0,30,150,30,30,150,0,0,0,0,0,0,30,0,150,30,0,0,0,0,150,30,0,150,0],b=[.22,.19,.22,.79,.34,.19,.22,.79,.34,.79,.34,.19,.34,.19,.34,.31,.62,.19,.34,.31,.62,.31,.62,.19,.34,.43,.34,.55,.49,.43,.34,.55,.49,.55,.49,.43,0,0,1,0,0,1,0,1,1,0,1,1,0,0,1,0,0,1,0,1,1,0,1,1,0,0,1,0,0,1,0,1,1,0,1,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1,1,0,1,0,0,1,0,1,1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,0,1,1,1,0,0,1,1,1,0],c=t([18,0,0,1,18,0,0,-1,6,0,1,0,6,1,0,0,6,0,-1,0,6,1,0,0,6,0,1,0,6,1,0,0,6,0,-1,0,6,1,0,0,6,0,-1,0,6,-1,0,0]),d=t([18,200,70,120,18,80,70,200,6,70,200,210,6,200,200,70,6,210,100,70,6,210,160,70,6,70,180,210,6,100,70,210,6,76,210,100,6,140,210,80,6,90,130,110,6,160,160,220],[255]),f=a.length/3,g={position:e(3,f),texcoord:e(2,f),normal:e(3,f),color:e(4,f,Uint8Array),indices:e(3,f/3,Uint16Array)};g.position.push(a),g.texcoord.push(b),g.normal.push(c),g.color.push(d);for(var h=0;h<f;++h)g.indices.push(h);return g}function v(a,b,d,f,g,h,i){function j(a,b,c){return a+(b-a)*c}function k(b,d,e,i,k,l){for(var o=0;o<=g;o++){var s=d/(m-1),t=o/g,u=2*(s-.5),v=(h+t*n)*Math.PI,w=Math.sin(v),x=Math.cos(v),y=j(a,b,w),z=u*f,A=x*a,B=w*y;p.push(z,A,B);var C=c.add(c.multiply([0,w,x],e),i);q.push(C),r.push(s*k+l,t)}}function l(a,b){for(var c=0;c<g;++c)u.push(a+c+0,a+c+1,b+c+0),u.push(a+c+1,b+c+1,b+c+0)}if(g<=0)throw Error("subdivisionDown must be > 0");h=h||0,i=i||1;for(var m=2,n=i-h,o=2*(g+1)*(2+m),p=e(3,o),q=e(3,o),r=e(2,o),s=0;s<m;s++){var t=2*(s/(m-1)-.5);k(b,s,[1,1,1],[0,0,0],1,0),k(b,s,[0,0,0],[t,0,0],0,0),k(d,s,[1,1,1],[0,0,0],1,0),k(d,s,[0,0,0],[t,0,0],0,1)}var u=e(3,2*g*(2+m),Uint16Array),v=g+1;return l(0*v,4*v),l(5*v,7*v),l(6*v,2*v),l(3*v,1*v),{position:p,normal:q,texcoord:r,indices:u}}function w(a,b,c,d,e,f){return s(a,a,b,c,d,e,f)}function x(a,b,c,d,f,g){if(c<3)throw Error("radialSubdivisions must be 3 or greater");if(d<3)throw Error("verticalSubdivisions must be 3 or greater");f=f||0,g=g||2*Math.PI,range=g-f;for(var h=c+1,i=d+1,j=h*i,k=e(3,j),l=e(3,j),m=e(2,j),n=e(3,c*d*2,Uint16Array),o=0;o<i;++o)for(var p=o/d,q=p*Math.PI*2,r=Math.sin(q),s=a+r*b,t=Math.cos(q),u=t*b,v=0;v<h;++v){var w=v/c,x=f+w*range,y=Math.sin(x),z=Math.cos(x),A=y*s,B=z*s,C=y*r,D=z*r;k.push(A,u,B),l.push(C,t,D),m.push(w,1-p)}for(var o=0;o<d;++o)for(var v=0;v<c;++v){var E=1+v,F=1+o;n.push(h*o+v,h*F+v,h*o+E),n.push(h*F+v,h*F+E,h*o+E)}return{position:k,normal:l,texcoord:m,indices:n}}function y(a,b,c,d,f){if(b<3)throw Error("divisions must be at least 3");c=c||1,f=f||1,d=d||0;for(var g=(b+1)*(c+1),h=e(3,g),i=e(3,g),j=e(2,g),k=e(3,c*b*2,Uint16Array),l=0,m=a-d,n=0;n<=c;++n){for(var o=d+m*Math.pow(n/c,f),p=0;p<=b;++p){var q=2*Math.PI*p/b,r=o*Math.cos(q),s=o*Math.sin(q);if(h.push(r,0,s),i.push(0,1,0),j.push(1-p/b,n/c),n>0&&p!==b){var t=l+(p+1),u=l+p,v=l+p-b,w=l+(p+1)-b;k.push(t,u,v),k.push(t,v,w)}}l+=b+1}return{position:h,normal:i,texcoord:j,indices:k}}function z(a){return Math.random()*a|0}function A(a,b){b=b||{};var c=a.position.numElements,d=e(4,c,Uint8Array),f=b.rand||function(a,b){return b<3?z(256):255};if(a.color=d,a.indices)for(var g=0;g<c;++g)d.push(f(g,0),f(g,1),f(g,2),f(g,3));else for(var h=b.vertsPerColor||3,i=c/h,g=0;g<i;++g)for(var j=[f(g,0),f(g,1),f(g,2),f(g,3)],k=0;k<h;++k)d.push(j);return a}function B(b){return function(c){var d=b.apply(this,Array.prototype.slice.call(arguments,1));return a.createBuffersFromArrays(c,d)}}function C(b){return function(c){var d=b.apply(null,Array.prototype.slice.call(arguments,1));return a.createBufferInfoFromArrays(c,d)}}var D=[[3,7,5,1],[6,2,0,4],[6,7,3,2],[0,1,5,4],[7,6,4,5],[2,3,1,0]];return{create3DFBufferInfo:C(u),create3DFBuffers:B(u),create3DFVertices:u,createAugmentedTypedArray:e,createCubeBufferInfo:C(r),createCubeBuffers:B(r),createCubeVertices:r,createPlaneBufferInfo:C(p),createPlaneBuffers:B(p),createPlaneVertices:p,createSphereBufferInfo:C(q),createSphereBuffers:B(q),createSphereVertices:q,createTruncatedConeBufferInfo:C(s),createTruncatedConeBuffers:B(s),createTruncatedConeVertices:s,createXYQuadBufferInfo:C(o),createXYQuadBuffers:B(o),createXYQuadVertices:o,createCresentBufferInfo:C(v),createCresentBuffers:B(v),createCresentVertices:v,createCylinderBufferInfo:C(w),createCylinderBuffers:B(w),createCylinderVertices:w,createTorusBufferInfo:C(x),createTorusBuffers:B(x),createTorusVertices:x,createDiscBufferInfo:C(y),createDiscBuffers:B(y),createDiscVertices:y,deindexVertices:g,flattenNormals:h,makeRandomVertexColors:A,reorientDirections:k,reorientNormals:l,reorientPositions:m,reorientVertices:n}}),c("main",["twgl/twgl","twgl/m4","twgl/v3","twgl/primitives"],function(a,b,c,d){return a.m4=b,a.v3=c,a.primitives=d,a}),b(["main"],function(a){return a},void 0,!0),c("build/js/twgl-includer-full",function(){}),b("main")});
// Class to load and hold the textures for the panorama viewer.
var PanoTex = /** @class */ (function () {
function PanoTex(gl) {
this.gl = gl;
this.imageUrl = undefined;
this.ts = 0;
this.tex = [];
this.options = {
target: gl.TEXTURE_CUBE_MAP
};
this.tex.push(twgl.createTexture(gl, this.options));
this.tex.push(twgl.createTexture(gl, this.options));
}
PanoTex.prototype.loadImage = function (url, onSuccess, onError) {
var img = new Image();
img.onload = function () {
onSuccess && onSuccess(img);
};
img.onerror = function () {
onError && onError(new Error("Couldn't load image: " + url));
};
img.crossOrigin = 'anonymous';
img.src = url;
};
PanoTex.prototype.load = function (options, isMono,isMultiFrame, onSuccess, onError) {
if(isMultiFrame){
return this.loadInMultiFrame(options, isMono, onSuccess, onError);
}
var _this = this;
options = angular.extend({}, this.options, options[0]);
var imageUrl = options.src;
var ts = new Date().getTime();
this.loadImage(imageUrl, function (img) {
// Disposed..
if (!_this.gl) {
onError && onError(undefined);
}
// The image may arrive out-of-order. Discard the prior images.
if (ts < _this.ts) {
onError && onError(undefined);
}
_this.ts = ts;
// This may happen if the user switch between panoramas. The image
// is loaded but the user has switched to another panorama. Discard
// the image in such case.
if (_this.imageUrl === imageUrl) {
onError && onError(undefined);
}
_this.imageUrl = imageUrl;
if (isMono) {
// Mono panorama is a 1x6 image.
twgl.setTextureFromElement(_this.gl, _this.tex[0], img, options);
return [_this.tex[0], _this.tex[0]];
} else {
// Stereo panorama is a 6x1x2 image. Right eye up and left eye down.
options = [
angular.extend({}, options, {shift: 1}),
angular.extend({}, options)
];
twgl.setTextureFromElement(_this.gl, _this.tex[0], img, options[0]);
twgl.setTextureFromElement(_this.gl, _this.tex[1], img, options[1]);
return [_this.tex[0], _this.tex[1]];
}
});
};
PanoTex.prototype.loadInMultiFrame = function (options, isMono, onSuccess, onError) {
if(isMono){
//Panorama
twgl.loadCubemapFromUrls(this.gl,this.tex[0],options[0],function () {
});
onSuccess([this.tex[0], this.tex[0]]);
}else{
//Stereo Panorama
twgl.loadCubemapFromUrls(this.gl,this.tex[0],options[0],function () {
});
twgl.loadCubemapFromUrls(this.gl,this.tex[1],options[1],function () {
});
onSuccess([this.tex[0], this.tex[1]]);
}
};
PanoTex.prototype.dispose = function () {
// Graphics resources should be disposed in time. GC behavior is not
// determinstic and it only do eager collection when CPU memory is low.
// Otherwise, we will run out of VRAM quickly.
for (var i in this.tex) {
gl.deleteTexture(this.tex[i]);
}
this.tex = [];
this.gl = null;
};
return PanoTex;
}());
/**
VR support (using WebVR)
*/
var vrHMD, vrSensor, vrEnabled = false;
function initVR(callbackfn) {
function enumerateVRDevices(vrdevs) {
// First, find a HMD -- just use the first one we find
vrdevs.every(function(e) {
vrHMD = e;
return (!e instanceof HMDVRDevice)
})
if (!vrHMD) return;
if (callbackfn) callbackfn();
// Then, find that HMD's position sensor
vrdevs.every(function(e) {
getCameraQuaternion = function() {
var quat = [0, 0, 0, 0];
if (vrSensor) {
var state = vrSensor.getState();
if (state.orientation)
quat = [state.orientation.x, state.orientation.y, state.orientation.z, state.orientation.w];
}
return quat;
}
vrSensor = e;
return !((e.hardwareUnitId == vrHMD.hardwareUnitId) && (e instanceof PositionSensorVRDevice))
})
}
if (navigator.getVRDevices)
navigator.getVRDevices().then(enumerateVRDevices);
else if (navigator.mozGetVRDevices)
navigator.mozGetVRDevices(enumerateVRDevices);
}
initVR(function(){
setSvgIcon(1);
});
function startVRfullscreen() {
if (!vrHMD)
console.log("couldn't find webVR. Opening to full screen, and displaying the info card on how to support Oculus by installing webVR.");
if (isMobile)
isDistortion = (isDistortion) ? 0 : 1;
if (isMobile || vrEnabled)
isStereo = (isStereo) ? null:1;
if (document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement) {
if (document.msExitFullscreen) document.msExitFullscreen();
if (document.webkitIsFullScreen) document.webkitExitFullscreen();
if (document.mozFullScreen) document.mozCancelFullScreen();
}
else {
var t = { vrDisplay: vrHMD /*,vrDistortion: false */ }
if (document.body.webkitRequestFullScreen) document.body.webkitRequestFullScreen(t)
if (document.body.mozRequestFullScreen) document.body.mozRequestFullScreen(t)
if (document.body.msRequestFullscreen) document.body.msRequestFullscreen()
}
}
function fullScreenChange() {
var isFullscreen = (document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenEnabled);
vrEnabled = vrHMD && isFullscreen;
//automatically switch to stereo mode if 'cardboard' or is 'webVR' enabled
//update icon's
if (!vrHMD) {
setSvgIcon((isFullscreen) ? 2:0);
}
}
document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
document.addEventListener('mozfullscreenchange', fullScreenChange, false);
document.addEventListener('fullscreenchange', fullScreenChange, false);
/**
Command line URL Inputs - stereo=1, flipLR=1, msaa=1, fov=80.
*/
var q = {};
if (location.href.split('?')[1]) location.href.split('?')[1].split('&').forEach(function(i) {
q[i.split('=')[0]] = i.split('=')[1];
});
var isMobile = navigator.userAgent.match(/iPhone|Android|iPad|iPod/);
var isAndroid = navigator.userAgent.match(/Android/);
var isIEwin = navigator.userAgent.match(/Trident/); //IE11 cannot handle NPOT textures
var isStereo = q.stereo || q.flipLR; // flip left and right eye, for debugging stereo on desktop/ipad (cross your eyes)
var isDistortion = q.distort;
var fov = q.fov || 80; // set the field of view
var useMSAA = q.msaa || 1;
/**
webgl - using twgl.js helper library. Based on 'primitives' scenegraph example. Added stereo and popup labels
*/
twgl.setAttributePrefix("a_");
var m4 = twgl.m4;
var gl = twgl.getWebGLContext(c, {depth:true, antialias:true});
var eye = [0, 0, 0];
var eyeLookat, up, target;
var camera = m4.identity();
var view = m4.identity();
var viewDirection = m4.identity();
var viewDirectionProjection = m4.identity();
var viewDirectionProjectionInverse = m4.identity();
var objects = [];
var drawObjects = [];
function initStereoSkybox() {
var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
var plane = twgl.primitives.createXYQuadBufferInfo(gl);
var previewTxture = twgl.createTexture(gl, {
target:
gl.TEXTURE_CUBE_MAP,
format: gl.LUMINANCE,
src: [ 0xF0, 0xE0, 0xD0, 0xC0, 0xB0, 0xA0, ]
});
var uniforms = {
u_skybox: previewTxture,
u_color: [1, 1, 1, 1],
u_viewDirectionProjectionInverse: viewDirectionProjectionInverse,
u_distortion: [1.0,0.05,0.07] // cardboard v1 [1.0,0.15,0.18] // SVR Glass [1.0,0.08,0.09]
}
drawObjects.push({
programInfo: programInfo,
bufferInfo: plane,
uniforms: uniforms,
});
objects.push({
skyboxL: previewTxture,
skyboxR: previewTxture,
fov: 90,
uniforms: uniforms,
type: 0
});
}
var g_suspendRenderingLoop = false;
var _fov = fov;
function render(time) {
//time *= 0.001;
requestAnimationFrame(render);
if (g_suspendRenderingLoop) return; //check for any movement.
var aspect = gl.canvas.width / gl.canvas.height * ((isStereo) ? 0.5 : 1.0);
var projection = m4.perspective(_fov * Math.PI / 180, aspect, 0.5, 10);
var quat = getCameraQuaternion();
_fov += (fov-_fov)*0.1;
m4.fromRotationTranslation(quat, eye, camera)
if(typeof(version) != 'undefined' && version == 2 && eyeLookat){
var look = m4.lookAt(eyeLookat,target,up);
var coordTransform = m4.identity();
m4.rotateX(coordTransform, -90*Math.PI/180, coordTransform);
m4.rotateZ(coordTransform, 270*Math.PI/180, coordTransform);
m4.multiply(look, coordTransform, look);
m4.multiply(camera,look ,camera);
}
m4.inverse(camera, view);
m4.setTranslation(view, eye, viewDirection);
if (q.flip == "F") // Fusion Pano
m4.rotateX(viewDirection, -Math.PI/2, viewDirection);
if (q.flip == "I") // Inventor Pano
m4.rotateX(viewDirection, Math.PI/2, viewDirection);
m4.multiply(viewDirection, projection, viewDirectionProjection);
m4.inverse(viewDirectionProjection, viewDirectionProjectionInverse);
objects[0].uniforms.u_distortion[0] = (isDistortion==1) ? 1:0;
//Render CubeMaps (either stereo or mono)
if (!isStereo) {
// Render Mono
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
twgl.drawObjectList(gl, drawObjects);
} else {
// Render Stereo
gl.viewport(0, 0, gl.canvas.width / 2, gl.canvas.height);
objects.forEach(function(obj) { obj.uniforms.u_skybox = obj.skyboxL });
twgl.drawObjectList(gl, drawObjects);
// Render Right
gl.viewport(gl.canvas.width / 2, 0, gl.canvas.width / 2, gl.canvas.height);
objects.forEach(function(obj) { obj.uniforms.u_skybox = obj.skyboxR });
twgl.drawObjectList(gl, drawObjects);
}
}
initStereoSkybox();
requestAnimationFrame(render);
/**
Input - Touch/Mouse and html5-DeviceOrientation
*/
var ox, oy, dx, dy, ddx, ddy;
var tx, ty, rx, ry;
ox = 100, oy = 0.0, dx = -40, dy = 0.0, dz = 0.0, ddx = -70.0, ddy = 10.0;
rx = -40.0, ry = -20.0, rz=0;
var friction = 0.001;
var Pii = Math.PI / 180;
function $(elem) {return document.getElementById(elem)}
function $$(elem) {return document.getElementById(elem).style}
var getCameraQuaternion = function() {
if (isMobile) friction = 0.7; //sensor refresh is 20Hz on ios8, 60Hz on ios9, and android 60Hz
if ( (Math.abs(ddx + dx - rx) > 90) || (Math.abs(-ddy + dy - ry) > 90)) friction=1;
if (Math.abs(dz - rz)>3) friction=1;
rx += (ddx + dx - rx) * friction;
ry += (-ddy + dy - ry) * friction;
rz += (dz - rz) * friction;
return m4.eularToQuat(rx * Pii, rz, ry * Pii);
}
window.onorientationchange = function() {
var isPortrait = (window.orientation == 0);
var isLandscape = !isPortrait && isMobile;
if (isLandscape && q.url) { isStereo = 1; isDistortion = 1; useMSAA = q.msaa || 2;}
twgl.resizeCanvasToDisplaySize(gl.canvas, useMSAA);
$$('rotatePhone').cssText = (isPortrait && q.url) ? 'display:block':'display:none';
$$('info-icon').cssText = (isMobile) ? 'display:none;':'';
}
window.onorientationchange();
if (isMobile && window.DeviceOrientationEvent) {
var ondeviceorientation = function(e) {
dx = e.alpha +0.01;
dy = -(90.0 + e.gamma);
dz = -e.beta * Pii;
//Handle orientation quirk, if phone is landscape upside down
if (window.orientation == -90) {
dy = (isAndroid) ? -dy : 180.0 - dy;
dx = (isAndroid) ? dx : 180.0 + dx;
dz = -dz;
}
//Handle portrait
if (window.orientation == 0) {
isStereo = 0;
dx = 90 + dx;
dy = -(90 + dz / Pii);
dz = 0;
isDistortion = null;
}
};
//check whether permission API is supported
if (typeof DeviceOrientationEvent.requestPermission === 'function') {
var btn = document.createElement('DIV');
btn.innerText = 'Tap here to enable device orientation tracking';
btn.style.cssText = 'position:absolute;left:0;top:0;z-index:9999;width:auto;padding:10px;color:#fff;font-size:14px;background:rgba(0,0,0,0.2);';
btn.addEventListener('click', function(){
DeviceOrientationEvent.requestPermission().then(function(resp){
if (resp == 'granted') {
window.ondeviceorientation = ondeviceorientation;
}
}).catch(console.error);
document.body.removeChild(btn);
});
document.body.appendChild(btn);
} else {
window.ondeviceorientation = ondeviceorientation;
}
}
// twgl uses 'c' global for canvas
var suspend_timer, m_button;
c.onmouseup = function(evt) {
evt.preventDefault();
m_button = 0;
window.clearTimeout(suspend_timer);
suspend_timer = window.setTimeout(function() {
g_suspendRenderingLoop = true;
}, 4000);
}
c.onmousedown = function(evt) {
m_button = 1;
friction = 0.05; //when the pano first opens, do a slow initial camera pan of the scene, to indicate to the user that this is not just a static image. Also, the mouse cursor is changed to a spin symbol, to also help indicate that the user can spin the scene with their mouse.
}
c.ontouchstart = function(evt) {
evt.preventDefault();
var tap = (isMobile) ? evt.touches[0] : evt;
tx = tap.pageX;
ty = tap.pageY;
}
c.ontouchmove = c.onmousemove = function(evt) {
evt.preventDefault();
var tap = (isMobile) ? evt.touches[0] : evt;
ox = tx;
oy = ty;
tx = tap.pageX;
ty = tap.pageY;
if (isMobile || m_button) {
ddx += (tx - ox) / 4;
ddy -= (ty - oy) / 6;
g_suspendRenderingLoop = false;
}
}
window.onresize = function() { twgl.resizeCanvasToDisplaySize(gl.canvas, useMSAA)}
var isviz = false;
function zoom() {fov=(fov<40)?110:(fov-30);g_suspendRenderingLoop=false; $$('icon-zoomin').cssText = (fov<39) ? 'display:none':'';}
function showinfo() {isviz=!isviz;if (isviz) $("infocard").focus(); else $("webvr-container").focus();}
function setSvgIcon(n) {
var szWVR = '<svg viewBox="0 25 185 140"><g><g><path fill="white" stroke="black" stroke-width="1" id="_x3C_Path_x3E__9_" d="M171.2,144.2c0-5.6-3.6-7.2-8.8-7.2H155v26h6v-11h-0.4l6.4,11h6.2l-7.4-11.3 C169.3,151.1,171.2,147.6,171.2,144.2z M161.2,149H161v-9h0.3c2.7,0,4.8,1.2,4.8,4.4C166,147.6,164.1,149,161.2,149z"/> <polygon fill="white" stroke="black" stroke-width="1" points="132.3,153 132.2,153 125.9,137 120.4,137 130.4,163 133.4,163 143.6,137 138.1,137 "/> <path fill="white" stroke="black" stroke-width="1" id="_x3C_Path_x3E__8_" d="M105,147.9c1.6-1,2.3-2.5,2.3-4.4c0-5.2-3-6.5-7.9-6.5H93v26h8.1c4.8,0,8.4-2.9,8.4-8 C109.5,152.1,108.1,148.4,105,147.9z M98,140h0.8c2.2,0,3.7,0.8,3.7,3.5c0,2.7-1.2,3.5-3.7,3.5H98V140z M99.3,158H98v-7h1 c2.6,0,5.4,0,5.4,3.4S102,158,99.3,158z"/> <polygon fill="white" stroke="black" stroke-width="1" points="65,163 79,163 79,158 71,158 71,151 79,151 79,147 71,147 71,140 79,140 79,137 65,137 "/> <polygon fill="white" stroke="black" stroke-width="1" points="43.3,154 43.2,154 37.8,137 34.7,137 29.5,154 29.4,154 24.1,137 18.8,137 27.1,163 30.9,163 35.8,146 35.9,146 41.1,163 44.9,163 53.8,137 48.4,137 "/> </g> <circle fill="white" stroke="black" stroke-width="3" cx="62.4" cy="73.5" r="13.9"/> <circle fill="white" stroke="black" stroke-width="3" cx="130" cy="73.5" r="13.9"/> <path fill="white" stroke="black" stroke-width="3" id="_x3C_Path_x3E__5_" d="M129.6,117c34.5,0,56.1-43.9,56.1-43.9s-21.6-43.8-56.1-43.9c0,0-67.2,0.1-67.3,0.1 c-34.5,0-56.1,43.8-56.1,43.8S27.8,117,62.4,117c13.3,0,24.7-6.5,33.6-14.5C105,110.5,116.3,117,129.6,117z M85.7,91.7 c-6.2,5.7-14.1,10.6-23.5,10.6c-23.2,0-37.7-29.3-37.7-29.3s14.5-29.3,37.7-29.3c9.6,0,17.6,5,23.8,10.8c4.1,3.9,7.4,8.2,9.8,11.7 c2.4-3.5,5.8-8,10.1-11.9c6.2-5.7,14.1-10.6,23.6-10.6c23.2,0,37.7,29.3,37.7,29.3s-14.5,29.3-37.7,29.3c-9.3,0-17.1-4.7-23.3-10.3 c-4.4-4.1-7.9-8.6-10.4-12.2C93.4,83.2,90,87.7,85.7,91.7z"/> <path fill="none" d="M0,0h192v192H0V0z"/></g></svg>'
var szFull = '<svg viewBox="2 2 19 19"><g fill="white"> <path d="M8.476,7.77l1.367-1.366h-3.44v3.439l1.366-1.366l2.327,2.328c0.098,0.098,0.226,0.146,0.354,0.146 s0.256-0.049,0.354-0.146c0.195-0.195,0.195-0.512,0-0.707L8.476,7.77z"/> <path d="M12.902,12.196c-0.195-0.195-0.512-0.195-0.707,0c-0.196,0.195-0.196,0.512,0,0.707l2.326,2.326 l-1.365,1.365h3.441v-3.439l-1.367,1.367L12.902,12.196z"/> <path d="M10.096,12.194l-2.327,2.328l-1.366-1.367v3.441h3.44l-1.367-1.367l2.327-2.328 c0.195-0.195,0.195-0.512,0-0.707S10.292,11.999,10.096,12.194z"/> <path d="M13.158,6.403l1.365,1.366l-2.326,2.328c-0.195,0.195-0.195,0.512,0,0.707 c0.098,0.098,0.225,0.146,0.354,0.146c0.127,0,0.256-0.049,0.354-0.146l2.326-2.328l1.367,1.367v-3.44H13.158z"/> </g></svg>'
var szExit = '<svg viewBox="0 0 24 24"><g fill="white"><path d="M7.341,6.635c-0.195-0.195-0.512-0.195-0.707,0c-0.195,0.195-0.195,0.512,0,0.707l1.749,1.75L7,10.475 h3.441V7.036L9.09,8.385L7.341,6.635z"/><path d="M14.563,13.857l1.367-1.367h-3.441v3.44l1.366-1.366l1.803,1.801c0.098,0.098,0.226,0.146,0.354,0.146 s0.256-0.049,0.354-0.146c0.195-0.195,0.195-0.512,0-0.707L14.563,13.857z"/><path d="M14.582,9.127l1.784-1.786c0.195-0.196,0.195-0.512,0-0.708c-0.195-0.194-0.512-0.195-0.707,0L13.875,8.42 l-1.386-1.386v3.441h3.44L14.582,9.127z"/><path d="M8.401,13.891l-1.766,1.768c-0.195,0.195-0.195,0.512,0,0.707c0.098,0.098,0.226,0.146,0.354,0.146 s0.256-0.049,0.354-0.146l1.766-1.768l1.332,1.333v-3.44H7.001L8.401,13.891z"/></g></svg>'
$("webvr-container").innerHTML = (n==1) ? szWVR : ((n==2) ? szExit : szFull );
}
setSvgIcon(0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment