├── .gitignore ├── LICENSE ├── README.md ├── bin └── minify.js ├── dist ├── app.js └── app.unchecked.js ├── img └── mask.jpg ├── index.html ├── package.json ├── screenshot.jpg └── src ├── colorpicker.js ├── main.js └── renderer.js /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 xoihazard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # webgl-triangulation 2 | 3 | A WebGL demo created by xoihazard. 4 | 5 | ![screen shot](screenshot.jpg) 6 | 7 | Photo by [Carsten Frenzl - TUT-Ausstellung_FFM_2012_47](https://www.flickr.com/photos/cfaobam/7117819557/) / Adapted. -------------------------------------------------------------------------------- /bin/minify.js: -------------------------------------------------------------------------------- 1 | var ClosureCompiler = require('google-closure-compiler').compiler; 2 | 3 | var UNCHECKED_FILE = process.argv[2]; 4 | var OUTPUT_FILE = process.argv[3]; 5 | 6 | var closureCompiler = new ClosureCompiler({ 7 | js: UNCHECKED_FILE, 8 | compilation_level: 'SIMPLE', 9 | js_output_file: OUTPUT_FILE 10 | }); 11 | 12 | closureCompiler.run(function (exitCode, stdOut, stdErr) { 13 | console.log('closure stdout:', stdOut) 14 | console.log('closure stderr:', stdErr) 15 | process.exit(exitCode) 16 | }); -------------------------------------------------------------------------------- /dist/app.js: -------------------------------------------------------------------------------- 1 | var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(l,w,t){l!=Array.prototype&&l!=Object.prototype&&(l[w]=t.value)};$jscomp.getGlobal=function(l){return"undefined"!=typeof window&&window===l?l:"undefined"!=typeof global&&null!=global?global:l};$jscomp.global=$jscomp.getGlobal(this); 2 | $jscomp.polyfill=function(l,w,t,k){if(w){t=$jscomp.global;l=l.split(".");for(k=0;ka)};t.abs=function(a){var g=a>>31;return(a^g)-g};t.min=function(a,g){return g^(a^g)&-(a>>=g;var e=(255>>=e;g|=e;e=(15>>=e;g|=e;e=(3>>e>>1};t.log10=function(a){return 1E9<=a?9:1E8<=a?8:1E7<=a?7:1E6<=a?6:1E5<=a?5:1E4<=a?4:1E3<=a?3:100<=a?2:10<=a?1:0};t.popCount=function(a){a-=a>>>1&1431655765;a=(a&858993459)+(a>>>2&858993459);return 16843009*(a+(a>>>4)&252645135)>>>24};t.countTrailingZeros=k;t.nextPow2=function(a){a+=0===a;--a;a|=a>>>1;a|=a>>>2;a|=a>>>4;a|=a>>>8;return(a|a>>>16)+1};t.prevPow2=function(a){a|=a>>>1;a|=a>>>2;a|=a>>>4;a|=a>>>8;a|=a>>>16;return a-(a>>>1)};t.parity=function(a){a^=a>>>16;a^=a>>>8;return 27030>>>((a^ 10 | a>>>4)&15)&1};var e=Array(256);(function(a){for(var g=0;256>g;++g){for(var e=g,k=g,n=7,e=e>>>1;e;e>>>=1)k<<=1,k|=e&1,--n;a[g]=k<>>8&255]<<16|e[a>>>16&255]<<8|e[a>>>24&255]};t.interleave2=function(a,g){a&=65535;a=(a|a<<8)&16711935;a=(a|a<<4)&252645135;a=(a|a<<2)&858993459;g&=65535;g=(g|g<<8)&16711935;g=(g|g<<4)&252645135;g=(g|g<<2)&858993459;return(a|a<<1)&1431655765|((g|g<<1)&1431655765)<<1};t.deinterleave2=function(a,g){a=a>>>g&1431655765; 11 | a=(a|a>>>1)&858993459;a=(a|a>>>2)&252645135;a=(a|a>>>4)&16711935;return((a|a>>>16)&65535)<<16>>16};t.interleave3=function(a,g,e){a&=1023;a=(a|a<<16)&4278190335;a=(a|a<<8)&251719695;a=(a|a<<4)&3272356035;g&=1023;g=(g|g<<16)&4278190335;g=(g|g<<8)&251719695;g=(g|g<<4)&3272356035;e&=1023;e=(e|e<<16)&4278190335;e=(e|e<<8)&251719695;e=(e|e<<4)&3272356035;return(a|a<<2)&1227133513|((g|g<<2)&1227133513)<<1|((e|e<<2)&1227133513)<<2};t.deinterleave3=function(a,e){a=a>>>e&1227133513;a=(a|a>>>2)&3272356035;a= 12 | (a|a>>>4)&251719695;a=(a|a>>>8)&4278190335;return((a|a>>>16)&1023)<<22>>22};t.nextCombination=function(a){var e=a|a-1;return e+1|(~e&-~e)-1>>>k(a)+1}},{}],2:[function(l,w,t){(function(k,e){"object"===typeof t&&"undefined"!==typeof w?e(t):"function"===typeof define&&define.amd?define(["exports"],e):e(k.d3=k.d3||{})})(this,function(k){function e(){}function a(d,b){var c=new e;if(d instanceof e)d.each(function(d,b){c.set(b,d)});else if(Array.isArray(d)){var a=-1,h=d.length,v;if(null==b)for(;++a=c.length)return null!=v?v(b):null!=h?b.sort(h):b;for(var q=-1,g=b.length,z=c[f++],n,A,k=a(),P,J=m();++qc.length)return d;var a=f[h-1];if(null!=v&&h>=c.length)var m=d.entries();else m=[],d.each(function(d,c){m.push({key:c,values:b(d,h)})});return null!=a?m.sort(function(d,b){return a(d.key,b.key)}):m}var c=[],f=[],h,v,e;return e={object:function(b){return d(b,0,g,l)},map:function(b){return d(b,0,u,n)},entries:function(c){return b(d(c,0,u,n),0)},key:function(b){c.push(b);return e},sortKeys:function(b){f[c.length- 17 | 1]=b;return e},sortValues:function(b){h=b;return e},rollup:function(b){v=b;return e}}};k.set=q;k.map=a;k.keys=function(d){var b=[],c;for(c in d)b.push(c);return b};k.values=function(c){var b=[],d;for(d in c)b.push(c[d]);return b};k.entries=function(c){var b=[],d;for(d in c)b.push({key:d,value:c[d]});return b};Object.defineProperty(k,"__esModule",{value:!0})})},{}],3:[function(l,w,t){(function(k,e){"object"===typeof t&&"undefined"!==typeof w?e(t):"function"===typeof define&&define.amd?define(["exports"], 18 | e):e(k.d3=k.d3||{})})(this,function(k){function e(){for(var e=0,g=arguments.length,q={},c;earguments.length)for(;++bv.index&&(c=z-f.x-f.vx,d=A-f.y-f.vy,a=c*c+d*d,az+e||aA+e||hc;++c)b[c]&&b[c].r>b.r&&(b.r=b[c].r)}function h(){if(f){var b,d=f.length;g=Array(d);for(b=0;bm;++m)(d=b[m])&&(a=d.value)&&(c+=a,f+=a*d.x,h+=a*d.y);b.x=f/c;b.y=h/c}else{d=b;d.x=d.data.x;d.y=d.data.y;do c+=l[d.data.index];while(d=d.next)}b.value=c}function q(b,d,c,a){if(!b.value)return!0;c=b.x-n.x;var f=b.y-n.y;d=a-d;a=c*c+f*f;if(d*d/t=y)){if(b.data!==n||b.next)0===c&&(c=m(),a+=c*c),0===f&&(f=m(),a+=f*f),a=(k=(m+g)/2))?m=k:g=k,(l=b>=(n=(e+q)/2))?e=n:q=n,f=h,!(h= 36 | h[u|=l<<1]))return f[u]=a,c;var y=+c._x.call(null,h.data);var x=+c._y.call(null,h.data);if(d===y&&b===x)return a.next=h,f?f[u]=a:c._root=a,c;do f=f?f[u]=Array(4):c._root=Array(4),(u=d>=(k=(m+g)/2))?m=k:g=k,(l=b>=(n=(e+q)/2))?e=n:q=n;while((u|=l<<1)===(l=(x>=n)<<1|y>=k));return f[l]=h,f[u]=a,c}function a(c){return c[0]}function g(c){return c[1]}function l(c,d,b){d=new u(null==d?a:d,null==b?g:b,NaN,NaN,NaN,NaN);return null==c?d:d.addAll(c)}function u(c,d,b,a,f,h){this._x=c;this._y=d;this._x0=b;this._y0= 37 | a;this._x1=f;this._y1=h;this._root=void 0}function n(c){for(var d={data:c.data},b=d;c=c.next;)b=b.next={data:c.data};return d}var y=function(c,d,b,a,f){this.node=c;this.x0=d;this.y0=b;this.x1=a;this.y1=f},q=l.prototype=u.prototype;q.copy=function(){var c=new u(this._x,this._y,this._x0,this._y0,this._x1,this._y1),d=this._root,b,a;if(!d)return c;if(!d.length)return c._root=n(d),c;for(b=[{source:d,target:c._root=Array(4)}];d=b.pop();)for(var f=0;4>f;++f)if(a=d.source[f])a.length?b.push({source:a,target:d.target[f]= 38 | Array(4)}):d.target[f]=n(a);return c};q.add=function(c){var a=+this._x.call(null,c),b=+this._y.call(null,c);return e(this.cover(a,b),a,b,c)};q.addAll=function(c){var a,b,m=c.length,f,h,g=Array(m),q=Array(m),k=Infinity,n=Infinity,u=-Infinity,l=-Infinity;for(b=0;bu&&(u=f),hl&&(l=h));uc||c>f||d>a||a>h){var e=f-b,g=this._root,q;switch(q=(a<(d+h)/2)<<1|c<(b+f)/2){case 0:do{var k=Array(4);k[q]=g;g=k}while(e*=2,f=b+e,h=d+e,c>f||a>h);break;case 1:do k=Array(4),k[q]=g,g=k;while(e*=2,b=f-e,h=d+e,b>c||a>h);break;case 2:do k=Array(4),k[q]=g,g=k;while(e*=2,f=b+e,d=h-e,c>f||d>a);break;case 3:do k= 40 | Array(4),k[q]=g,g=k;while(e*=2,b=f-e,d=h-e,b>c||d>a)}this._root&&this._root.length&&(this._root=g)}else return this;this._x0=b;this._y0=d;this._x1=f;this._y1=h;return this};q.data=function(){var c=[];this.visit(function(a){if(!a.length){do c.push(a.data);while(a=a.next)}});return c};q.extent=function(c){return arguments.length?this.cover(+c[0][0],+c[0][1]).cover(+c[1][0],+c[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]};q.find=function(c,a,b){var d=this._x0,f=this._y0,h, 41 | e,g,q,k=this._x1,n=this._y1,u=[],l=this._root,x;l&&u.push(new y(l,d,f,k,n));null==b?b=Infinity:(d=c-b,f=a-b,k=c+b,n=a+b,b*=b);for(;x=u.pop();)if(!(!(l=x.node)||(h=x.x0)>k||(e=x.y0)>n||(g=x.x1)=t)<<1|c>=x)x=u[u.length-1],u[u.length-1]=u[u.length-1-l],u[u.length-1-l]=x}else if(x=c-+this._x.call(null,l.data),t=a-+this._y.call(null,l.data),x=x*x+t*t,x=(u=(f+g)/2))?f=u:g=u;(y=n>=(l=(h+q)/2))?h=l:q=l;if(!(a=b,b=b[x|=y<<1]))return this;if(!b.length)break;if(a[x+1&3]||a[x+2&3]||a[x+3&3]){var t=a;var w=x}}for(;b.data!==c;)if(!(e=b,b=b.next))return this;(c=b.next)&&delete b.next; 43 | if(e)return c?e.next=c:delete e.next,this;if(!a)return this._root=c,this;c?a[x]=c:delete a[x];(b=a[0]||a[1]||a[2]||a[3])&&b===(a[3]||a[2]||a[1]||a[0])&&!b.length&&(t?t[w]=b:this._root=b);return this};q.removeAll=function(a){for(var c=0,b=a.length;ca._time&&(g=a._time),b=a,a=a._next):(e=a._next,a._next=null,a=b?b._next=e:m=e);f=b;q(g);v= 47 | 0}}function y(){var b=t.now(),a=b-h;1E3a&&(d=setTimeout(n,f)),b&&(b=clearInterval(b))):(b||(h=v,b=setInterval(y,1E3)),c=1,w(n))}}var c=0,d=0,b=0,m,f,h=0,v=0,z=0,t="object"===typeof performance&&performance.now?performance:Date,w="function"===typeof requestAnimationFrame?requestAnimationFrame:function(b){setTimeout(b,17)};g.prototype=l.prototype={constructor:g,restart:function(b,a,c){if("function"!==typeof b)throw new TypeError("callback is not a function"); 48 | c=(null==c?e():+c)+(null==a?0:+a);this._next||f===this||(f?f._next=this:m=this,f=this);this._call=b;this._time=c;q()},stop:function(){this._call&&(this._call=null,this._time=Infinity,q())}};k.now=e;k.timer=l;k.timerFlush=u;k.timeout=function(b,a,c){var d=new g;a=null==a?0:+a;d.restart(function(c){d.stop();b(c+a)},a,c);return d};k.interval=function(b,a,c){var d=new g,f=a;if(null==a)return d.restart(b,a,c),d;a=+a;c=null==c?e():+c;d.restart(function C(e){e+=f;d.restart(C,f+=a,c);b(e)},a,c);return d}; 49 | Object.defineProperty(k,"__esModule",{value:!0})})},{}],7:[function(l,w,t){function k(a,e){this.point=a;this.index=e}function e(a,e){a=a.point;e=e.point;for(var g=a.length,q=0;qq)return[];if(1===q)return a(u,l,n);var c=Array(u);var d=1;for(var b=0;bd&&2<=++b)return!1;a[c]=d}return!0}):u.filter(function(a){for(var b=0;b<=q;++b){var c=t[a[b]];if(0>c)return!1;a[b]=c}return!0});if(q&1)for(b=0;bf&&(h[0]=1,h[1]=0);for(var f=new k(h,Array(b+1),!1),q=f.adjacent,l=Array(b+2),g=0;g<=b;++g){var n=h.slice();for(var t=0;t<=b;++t)t===g&&(n[t]=-1);t=n[0];n[0]=n[1];n[1]=t;n=new k(n,Array(b+1),!0);q[g]=n;l[g]=n}l[b+1]=f;for(g= 54 | 0;g<=b;++g)for(n=q[g].vertices,h=q[g].adjacent,t=0;t<=b;++t){var y=n[t];if(0>y)h[t]=f;else for(var w=0;w<=b;++w)0>q[w].vertices.indexOf(y)&&(h[t]=q[w])}e=new x(b,e,l);c=!!c;for(g=b+1;gl?c:f[l]}q=this.orient();if(0=d)){g=f[k];f[k]=a;var q=this.orient();f[k]=g;if(0>q)continue a;else h.lastVisited=h.boundary?-d:d}return}return h};l.addPeaks=function(g,c){var d=this.vertices.length-1,b=this.dimension,m=this.vertices,f=this.tuple,h=this.interior,q=this.simplices,n=[c];c.lastVisited=d;c.vertices[c.vertices.indexOf(-1)]=d;c.boundary=!1;h.push(c); 57 | for(var l=[];0t))for(var y=0;y<=b;++y)if(y!==t){var w=x[y];if(w.boundary&&!(w.lastVisited>=d)){var L=w.vertices;if(w.lastVisited!==-d){for(var M=0,C=0;C<=b;++C)0>L[C]?(M=C,f[C]=g):f[C]=m[L[C]];if(0T))for(C[T]=M,Q[t]=w,L[y]=-1,Q[y]= 58 | c,x[y]=M,M.flip(),C=0;C<=b;++C)if(w=L[C],!(0>w||w===d)){w=Array(b-1);for(T=Q=0;T<=b;++T){var K=L[T];0>K||T===C||(w[Q++]=K)}l.push(new e(w,M,C))}}}}l.sort(a);for(y=0;y+1g.index||0>d||(g.cell.adjacent[g.index]=c.cell,c.cell.adjacent[c.index]=g.cell)};l.insert=function(a,c){var d=this.vertices;d.push(a);if(c=this.walk(a,c)){for(var b=this.dimension,e=this.tuple,f=0;f<=b;++f){var h=c.vertices[f];e[f]=0>h?a:d[h]}d=this.orient(e);if(!(0>d)){if(0===d&&(c=this.handleBoundaryDegeneracy(c, 59 | a),!c))return;this.addPeaks(a,c)}}};l.boundary=function(){for(var a=this.dimension,c=[],d=this.simplices,b=d.length,e=0;eb.indexOf(a)&&e("invalid value"+g(c)+". must be one of: "+b)}function u(a,b){for(a+="";a.lengtha.length)){var c=/^ERROR\:\s+(\d+)\:(\d+)\:\s*(.*)$/.exec(a); 63 | c?b.push(new q(c[1]|0,c[2]|0,c[3].trim())):0>>=b;var c=(255>>=c;b|=c;c=(15>>=c;b|=c;c=(3>>c>>1}function Z(a){a:{for(var b=16;268435456>=b;b*=16)if(a<=b){a=b;break a}a=0}b=lb[Ha(a)>>2];return 0>2].push(a)}function gb(a,b,c,d,e,f){for(var r=0;re&&(e=d.buffer.byteLength,5123===k?e>>=1:5125=== 83 | k&&(e>>=2));d.vertCount=e;e=h;0>h&&(e=4,h=d.buffer.dimension,1===h&&(e=0),2===h&&(e=1),3===h&&(e=4));d.primType=e}function h(a){d.elementsCount--;p(null!==a.buffer,"must not double destroy elements");delete r[a.id];a.buffer.destroy();a.buffer=null}var r={},g=0,m={uint8:5121,uint16:5123};b.oes_element_index_uint&&(m.uint32=5125);e.prototype.bind=function(){this.buffer.bind()};var k=[];return{create:function(a,b){function r(a){if(a)if("number"===typeof a)g(a),k.primType=4,k.vertCount=a|0,k.type=5121; 84 | else{var b=null,c=35044,d=-1,e=-1,h=0,n=0;if(Array.isArray(a)||E(a)||K(a))b=a;else if(p.type(a,"object","invalid arguments for elements"),"data"in a&&(b=a.data,p(Array.isArray(b)||E(b)||K(b),"invalid data for element buffer")),"usage"in a&&(p.parameter(a.usage,Ta,"invalid element buffer usage"),c=Ta[a.usage]),"primitive"in a&&(p.parameter(a.primitive,za,"invalid element buffer primitive"),d=za[a.primitive]),"count"in a&&(p("number"===typeof a.count&&0<=a.count,"invalid vertex count for elements"), 85 | e=a.count|0),"type"in a&&(p.parameter(a.type,m,"invalid buffer type"),n=m[a.type]),"length"in a)h=a.length|0;else if(h=e,5123===n||5122===n)h*=2;else if(5125===n||5124===n)h*=4;f(k,b,c,d,e,h,n)}else g(),k.primType=4,k.vertCount=0,k.type=5121;return r}var g=c.create(null,34963,!0),k=new e(g._buffer);d.elementsCount++;r(a);r._reglType="elements";r._elements=k;r.subdata=function(a,b){g.subdata(a,b);return r};r.destroy=function(){h(k)};return r},createStream:function(a){var b=k.pop();b||(b=new e(c.create(null, 86 | 34963,!0,!1)._buffer));f(b,a,35040,-1,-1,0,0);return b},destroyStream:function(a){k.push(a)},getElements:function(a){return"function"===typeof a&&a._elements instanceof e?a._elements:null},clear:function(){ja(r).forEach(h)}}}function nb(a){for(var b=G.allocType(5123,a.length),c=0;c>>31<<15,f=(d<<1>>>24)-127,d=d>>13&1023;b[c]=-24>f?e:-14>f?e+(d+1024>>-14-f): 87 | 15=g,"invalid number of channels"),e=!0),p(0<=f&&f<=c.maxTextureSize,"invalid width"),p(0<=h&&h<=c.maxTextureSize,"invalid height")):("radius"in d&&(f=h=d.radius,p(0<=f&&f<=c.maxTextureSize,"invalid radius")),"width"in d&&(f=d.width,p(0<=f&&f<=c.maxTextureSize, 92 | "invalid width")),"height"in d&&(h=d.height,p(0<=h&&h<=c.maxTextureSize,"invalid height")),"channels"in d&&(g=d.channels,p(0=g,"invalid number of channels"),e=!0));a.width=f|0;a.height=h|0;a.channels=g|0;f=!1;"format"in d&&(f=d.format,p(b.webgl_depth_texture||!("depth"===f||"depth stencil"===f),"you must enable the WEBGL_depth_texture extension in order to use depth/stencil textures."),p.parameter(f,O,"invalid texture format"),h=a.internalformat=O[f],a.format=Lb[h],f in ba&&!("type"in d)&&(a.type= 93 | ba[f]),f in wa&&(a.compressed=!0),f=!0);!e&&f?a.channels=U[a.format]:e&&!f?a.channels!==Va[a.format]&&(a.format=a.internalformat=Va[a.channels]):f&&e&&p(a.channels===U[a.format],"number of channels inconsistent with specified format")}}function m(b){a.pixelStorei(37440,b.flipY);a.pixelStorei(37441,b.premultiplyAlpha);a.pixelStorei(37443,b.colorSpace);a.pixelStorei(3317,b.unpackAlignment)}function n(){g.call(this);this.yOffset=this.xOffset=0;this.data=null;this.needsFree=!1;this.element=null;this.needsCopy= 94 | !1}function l(a,b){var d=null;ab(b)?d=b:b&&(p.type(b,"object","invalid pixel data type"),k(a,b),"x"in b&&(a.xOffset=b.x|0),"y"in b&&(a.yOffset=b.y|0),ab(b.data)&&(d=b.data));p(!a.compressed||d instanceof Uint8Array,"compressed texture data must be stored in a uint8array");if(b.copy)p(!d,"can not specify copy and data field for the same texture"),b=e.viewportWidth,d=e.viewportHeight,a.width=a.width||b-a.xOffset,a.height=a.height||d-a.yOffset,a.needsCopy=!0,p(0<=a.xOffset&&a.xOffset>=d,c.height>>=d,l(c,b[d]),a.mipmask|=1<b;++b)a.images[b]=null;return a}function pa(a){for(var b=a.images,c=0;cb){for(var c=0;c=F&&p.raise("insufficient number of texture units");h.profile&&f.maxTextureUnits=--this.refCount&&vb(this)}});h.profile&&(f.getTotalTextureSize=function(){var a=0;Object.keys(V).forEach(function(b){a+=V[b].stats.size});return a});return{create2D:function(b,d){function e(a,b){var d=g.texInfo;z.call(d);var f=w();"number"===typeof a?"number"===typeof b?x(f,a|0,b|0):x(f,a|0,a|0):a?(p.type(a,"object","invalid arguments to regl.texture"),ia(d,a),t(f,a)):x(f,1,1);d.genMipmaps&&(f.mipmask=(f.width<<1)-1); 112 | g.mipmask=f.mipmask;r(g,f);p.texture2D(d,f,c);g.internalformat=f.internalformat;e.width=f.width;e.height=f.height;da(g);y(f,3553);A(d,3553);ea();pa(f);h.profile&&(g.stats.size=Ua(g.internalformat,g.type,f.width,f.height,d.genMipmaps,!1));e.format=C[g.internalformat];e.type=I[g.type];e.mag=Na[d.magFilter];e.min=xa[d.minFilter];e.wrapS=ya[d.wrapS];e.wrapT=ya[d.wrapT];return e}var g=new cb(3553);V[g.id]=g;f.textureCount++;e(b,d);e.subimage=function(a,b,c,d){p(!!a,"must specify image data");b|=0;c|=0; 113 | d|=0;var f=u();r(f,g);f.width=0;f.height=0;l(f,a);f.width=f.width||(g.width>>d)-b;f.height=f.height||(g.height>>d)-c;p(g.type===f.type&&g.format===f.format&&g.internalformat===f.internalformat,"incompatible format for texture.subimage");p(0<=b&&0<=c&&b+f.width<=g.width&&c+f.height<=g.height,"texture.subimage write out of bounds");p(g.mipmask&1<>d;++d)a.texImage2D(3553,d,g.format,b>>d,c>>d,0,g.format,g.type,null);ea();h.profile&&(g.stats.size=Ua(g.internalformat,g.type,b,c,!1,!1));return e};e._reglType="texture2d";e._texture=g;h.profile&&(e.stats=g.stats);e.destroy=function(){g.decRef()};return e},createCube:function(b,d,e,g,m,n){function v(a,b,d,e,f,g){var m,na=B.texInfo;z.call(na);for(m=0;6>m;++m)D[m]=w();if("number"!==typeof a&& 115 | a)if("object"===typeof a)if(b)t(D[0],a),t(D[1],b),t(D[2],d),t(D[3],e),t(D[4],f),t(D[5],g);else if(ia(na,a),k(B,a),"faces"in a)for(a=a.faces,p(Array.isArray(a)&&6===a.length,"cube faces must be a length 6 array"),m=0;6>m;++m)p("object"===typeof a[m]&&!!a[m],"invalid input for cube map face"),r(D[m],B),t(D[m],a[m]);else for(m=0;6>m;++m)t(D[m],a);else p.raise("invalid arguments to cube map");else for(a=a|0||1,m=0;6>m;++m)x(D[m],a,a);r(B,D[0]);B.mipmask=na.genMipmaps?(D[0].width<<1)-1:D[0].mipmask;p.textureCube(B, 116 | na,D,c);B.internalformat=D[0].internalformat;v.width=D[0].width;v.height=D[0].height;da(B);for(m=0;6>m;++m)y(D[m],34069+m);A(na,34067);ea();h.profile&&(B.stats.size=Ua(B.internalformat,B.type,v.width,v.height,na.genMipmaps,!0));v.format=C[B.internalformat];v.type=I[B.type];v.mag=Na[na.magFilter];v.min=xa[na.minFilter];v.wrapS=ya[na.wrapS];v.wrapT=ya[na.wrapT];for(m=0;6>m;++m)pa(D[m]);return v}var B=new cb(34067);V[B.id]=B;f.cubeCount++;var D=Array(6);v(b,d,e,g,m,n);v.subimage=function(a,b,c,d,e){p(!!b, 117 | "must specify image data");p("number"===typeof a&&a===(a|0)&&0<=a&&6>a,"invalid face");c|=0;d|=0;e|=0;var f=u();r(f,B);f.width=0;f.height=0;l(f,b);f.width=f.width||(B.width>>e)-c;f.height=f.height||(B.height>>e)-d;p(B.type===f.type&&B.format===f.format&&B.internalformat===f.internalformat,"incompatible format for texture.subimage");p(0<=c&&0<=d&&c+f.width<=B.width&&d+f.height<=B.height,"texture.subimage write out of bounds");p(B.mipmask&1<c;++c)for(var d=0;B.mipmask>>d;++d)a.texImage2D(34069+c,d,B.format,b>>d,b>>d,0,B.format,B.type,null);ea();h.profile&&(B.stats.size=Ua(B.internalformat,B.type,v.width,v.height,!1,!0));return v}};v._reglType="textureCube";v._texture=B;h.profile&&(v.stats=B.stats);v.destroy=function(){B.decRef()};return v},clear:function(){for(var b=0;b< 119 | F;++b)a.activeTexture(33984+b),a.bindTexture(3553,null),Q[b]=null;ja(V).forEach(vb);f.cubeCount=0;f.textureCount=0},getTexture:function(a){return null},restore:function(){ja(V).forEach(function(b){b.texture=a.createTexture();a.bindTexture(b.target,b.texture);for(var c=0;32>c;++c)if(0!==(b.mipmask&1<>c,b.height>>c,0,b.internalformat,b.type,null);else for(var d=0;6>d;++d)a.texImage2D(34069+d,c,b.internalformat,b.width>>c,b.height>> 120 | c,0,b.internalformat,b.type,null);A(b.texInfo,b.target)})}}}function Nb(a,b,c,d,f,e){function h(a,b,c){this.target=a;this.texture=b;this.renderbuffer=c;var d=a=0;b?(a=b.width,d=b.height):c&&(a=c.width,d=c.height);this.width=a;this.height=d}function g(a){a&&(a.texture&&a.texture._texture.decRef(),a.renderbuffer&&a.renderbuffer._renderbuffer.decRef())}function m(a,b,c){if(a){if(a.texture){a=a.texture._texture;var d=Math.max(1,a.height);p(Math.max(1,a.width)===b&&d===c,"inconsistent width/height for supplied texture")}else a= 121 | a.renderbuffer._renderbuffer,p(a.width===b&&a.height===c,"inconsistent width/height for renderbuffer");a.refCount+=1}}function r(b,c){c&&(c.texture?a.framebufferTexture2D(36160,b,c.target,c.texture._texture.texture,0):a.framebufferRenderbuffer(36160,b,36161,c.renderbuffer._renderbuffer.renderbuffer))}function k(a){var b=3553,c=null,d=null,f=a;"object"===typeof a&&(f=a.data,"target"in a&&(b=a.target|0));p.type(f,"function","invalid attachment data");a=f._reglType;"texture2d"===a?(c=f,p(3553===b)): 122 | "textureCube"===a?(c=f,p(34069<=b&&34075>b,"invalid cube map target")):"renderbuffer"===a?(d=f,b=36161):p.raise("invalid regl object for attachment");return new h(b,c,d)}function n(a,b,c,e,g){if(c)return a=d.create2D({width:a,height:b,format:e,type:g}),a._texture.refCount=0,new h(3553,a,null);a=f.create({width:a,height:b,format:e});a._renderbuffer.refCount=0;return new h(36161,null,a)}function l(a){return a&&(a.texture||a.renderbuffer)}function q(a,b,c){a&&(a.texture?a.texture.resize(b,c):a.renderbuffer&& 123 | a.renderbuffer.resize(b,c))}function v(){this.id=ia++;A[this.id]=this;this.framebuffer=a.createFramebuffer();this.height=this.width=0;this.colorAttachments=[];this.depthStencilAttachment=this.stencilAttachment=this.depthAttachment=null}function u(a){a.colorAttachments.forEach(g);g(a.depthAttachment);g(a.stencilAttachment);g(a.depthStencilAttachment)}function t(b){var c=b.framebuffer;p(c,"must not double destroy framebuffer");a.deleteFramebuffer(c);b.framebuffer=null;e.framebufferCount--;delete A[b.id]} 124 | function x(b){var d;a.bindFramebuffer(36160,b.framebuffer);var f=b.colorAttachments;for(d=0;d=S.length,"you must enable the WEBGL_draw_buffers extension in order to use multiple color buffers.");p(S.length<=c.maxColorAttachments,"too many color attachments, not supported"); 130 | g=g||S[0].width;r=r||S[0].height;va?a=k(va):q&&!v&&(a=n(g,r,Sa,"depth","uint32"));ma?e=k(ma):v&&!q&&(e=n(g,r,!1,"stencil","uint8"));da?d=k(da):!va&&!ma&&v&&q&&(d=n(g,r,Sa,"depth stencil","depth stencil"));p(1>=!!va+!!ma+!!da,"invalid framebuffer configuration, can specify exactly one depth/stencil attachment");q=null;for(t=0;te.indexOf(y.next),"can not update framebuffer which is currently in use");var c=b.webgl_draw_buffers, 135 | h={color:null},g=0,r=null;var m="rgba";var k="uint8",n=1;if("number"===typeof a)g=a|0;else if(a){p.type(a,"object","invalid arguments for framebuffer");"shape"in a?(g=a.shape,p(Array.isArray(g)&&2<=g.length,"invalid shape for framebuffer"),p(g[0]===g[1],"cube framebuffer must be square"),g=g[0]):("radius"in a&&(g=a.radius|0),"width"in a?(g=a.width|0,"height"in a&&p(a.height===g,"must be square")):"height"in a&&(g=a.height|0));if("color"in a||"colors"in a)r=a.color||a.colors,Array.isArray(r)&&p(1=== 136 | r.length||c,"multiple render targets not supported");r||("colorCount"in a&&(n=a.colorCount|0,p(0m;++m){for(n=0;na;++a)e[a].resize(b);f.width=f.height=b;return f},_reglType:"framebufferCube",destroy:function(){e.forEach(function(a){a.destroy()})}})},clear:function(){ja(A).forEach(t)},restore:function(){ja(A).forEach(function(b){b.framebuffer=a.createFramebuffer();x(b)})}})} 139 | function xb(){this.w=this.z=this.y=this.x=this.state=0;this.buffer=null;this.size=0;this.normalized=!1;this.type=5126;this.divisor=this.stride=this.offset=0}function Rb(a,b,c,d,f){a=c.maxAttributes;b=Array(a);for(c=0;ca&&(a=b.stats.uniformsCount)});return a},c.getMaxAttributesCount=function(){var a=0;l.forEach(function(b){b.stats.attributesCount>a&&(a=b.stats.attributesCount)});return a});return{clear:function(){var b=a.deleteShader.bind(a);ja(r).forEach(b);r={};ja(k).forEach(b);k={};l.forEach(function(b){a.deleteProgram(b.program)});l.length=0;n={};c.shaderCount=0},program:function(a, 143 | b,d){p.command(0<=a,"missing vertex shader",d);p.command(0<=b,"missing fragment shader",d);var f=n[b];f||(f=n[b]={});var e=f[a];e||(e=new g(b,a),c.shaderCount++,m(e,d),f[a]=e,l.push(e));return e},restore:function(){r={};k={};for(var a=0;a=h,"data buffer for regl.read() too small");a.pixelStorei(3333,4);a.readPixels(m,r,k,n,6408,g,l);return l}function g(a){var c;b.setFBO({framebuffer:a.framebuffer},function(){c=h(a)});return c}return function(a){return a&&"framebuffer"in a?g(a):h(a)}}function Ca(a){return Array.prototype.slice.call(a)}function Da(a){return Ca(a).join("")} 147 | function Ub(){function a(){var a=[],b=[];return N(function(){a.push.apply(a,Ca(arguments))},{def:function(){var d="v"+c++;b.push(d);0=0&&"+m+">=0","invalid "+a)});return[e,h,g,m]});b&&(h.thisDep=h.thisDep||b.thisDep,h.contextDep=h.contextDep||b.contextDep, 158 | h.propDep=h.propDep||b.propDep);return h}return b?new ca(b.thisDep,b.contextDep,b.propDep,function(a,b){a=a.shared.context;return[0,0,b.def(a,".","framebufferWidth"),b.def(a,".","framebufferHeight")]}):null}var f=a.static,e=a.dynamic;if(a=d("viewport")){var h=a;a=new ca(a.thisDep,a.contextDep,a.propDep,function(a,b){var c=h.append(a,b);a=a.shared.context;b.set(a,".viewportWidth",c[2]);b.set(a,".viewportHeight",c[3]);return c})}return{viewport:a,scissor_box:d("scissor.box")}}function A(a){function c(a){if(a in 159 | d){var c=b.id(d[a]);p.optional(function(){n.shader(Ab[a],c,p.guessCommand())});var e=I(function(){return c});e.id=c;return e}if(a in f){var h=f[a];return Y(h,function(b,c){var d=b.invoke(c,h),f=c.def(b.shared.strings,".id(",d,")");p.optional(function(){c(b.shared.shader,".shader(",Ab[a],",",f,",",b.command,");")});return f})}return null}var d=a.static,f=a.dynamic,e=c("frag"),h=c("vert"),g=null;ta(e)&&ta(h)?(g=n.program(h.id,e.id),a=I(function(a,b){return a.link(g)})):a=new ca(e&&e.thisDep||h&&h.thisDep, 160 | e&&e.contextDep||h&&h.contextDep,e&&e.propDep||h&&h.propDep,function(a,b){var c=a.shared.shader;var d=e?e.append(a,b):b.def(c,".","frag");var f=h?h.append(a,b):b.def(c,".","vert");var g=c+".program("+f+","+d;p.optional(function(){g+=","+a.command});return b.def(g+")")});return{frag:e,vert:h,progVar:a,program:g}}function B(a,b){function c(a,c){if(a in d){var e=d[a]|0;p.command(!c||0<=e,"invalid "+a,b.commandStr);return I(function(a,b){c&&(a.OFFSET=e);return e})}if(a in f){var g=f[a];return Y(g,function(b, 161 | d){var f=b.invoke(d,g);c&&(b.OFFSET=f,p.optional(function(){b.assert(d,f+">=0","invalid "+a)}));return f})}return c&&h?I(function(a,b){a.OFFSET="0";return 0}):null}var d=a.static,f=a.dynamic,h=function(){if("elements"in d){var a=d.elements;Za(a)?a=e.getElements(e.create(a,!0)):a&&(a=e.getElements(a),p.command(a,"invalid elements",b.commandStr));var c=I(function(b,c){return a?(c=b.link(a),b.ELEMENTS=c):b.ELEMENTS=null});c.value=a;return c}if("elements"in f){var h=f.elements;return Y(h,function(a,b){var c= 162 | a.shared,d=c.isBufferArgs,c=c.elements,f=a.invoke(b,h),e=b.def("null"),d=b.def(d,"(",f,")"),g=a.cond(d).then(e,"=",c,".createStream(",f,");").else(e,"=",c,".getElements(",f,");");p.optional(function(){a.assert(g.else,"!"+f+"||"+e,"invalid elements")});b.entry(g);b.exit(a.cond(d).then(c,".destroyStream(",e,");"));return a.ELEMENTS=e})}return null}(),g=c("offset",!0);return{elements:h,primitive:function(){if("primitive"in d){var a=d.primitive;p.commandParameter(a,za,"invalid primitve",b.commandStr); 163 | return I(function(b,c){return za[a]})}if("primitive"in f){var c=f.primitive;return Y(c,function(a,b){var d=a.constants.primTypes,f=a.invoke(b,c);p.optional(function(){a.assert(b,f+" in "+d,"invalid primitive, must be one of "+Object.keys(za))});return b.def(d,"[",f,"]")})}return h?ta(h)?h.value?I(function(a,b){return b.def(a.ELEMENTS,".primType")}):I(function(){return 4}):new ca(h.thisDep,h.contextDep,h.propDep,function(a,b){a=a.ELEMENTS;return b.def(a,"?",a,".primType:",4)}):null}(),count:function(){if("count"in 164 | d){var a=d.count|0;p.command("number"===typeof a&&0<=a,"invalid vertex count",b.commandStr);return I(function(){return a})}if("count"in f){var c=f.count;return Y(c,function(a,b){var d=a.invoke(b,c);p.optional(function(){a.assert(b,"typeof "+d+'==="number"&&'+d+">=0&&"+d+"===("+d+"|0)","invalid vertex count")});return d})}if(h){if(ta(h)){if(h)return g?new ca(g.thisDep,g.contextDep,g.propDep,function(a,b){var c=b.def(a.ELEMENTS,".vertCount-",a.OFFSET);p.optional(function(){a.assert(b,c+">=0","invalid vertex offset/element buffer too small")}); 165 | return c}):I(function(a,b){return b.def(a.ELEMENTS,".vertCount")});var e=I(function(){return-1});p.optional(function(){e.MISSING=!0});return e}var m=new ca(h.thisDep||g.thisDep,h.contextDep||g.contextDep,h.propDep||g.propDep,function(a,b){var c=a.ELEMENTS;return a.OFFSET?b.def(c,"?",c,".vertCount-",a.OFFSET,":-1"):b.def(c,"?",c,".vertCount:-1")});p.optional(function(){m.DYNAMIC=!0});return m}return null}(),instances:c("instances",!1),offset:g}}function pa(a,b){var c=a.static,f=a.dynamic,e={};La.forEach(function(a){function h(b, 166 | d){if(a in c){var h=b(c[a]);e[g]=I(function(){return h})}else if(a in f){var m=f[a];e[g]=Y(m,function(a,b){return d(a,b,a.invoke(b,m))})}}var g=r(a);switch(a){case "cull.enable":case "blend.enable":case "dither":case "stencil.enable":case "depth.enable":case "scissor.enable":case "polygonOffset.enable":case "sample.alpha":case "sample.enable":case "depth.mask":return h(function(c){p.commandType(c,"boolean",a,b.commandStr);return c},function(b,c,d){p.optional(function(){b.assert(c,"typeof "+d+'==="boolean"', 167 | "invalid flag "+a,b.commandStr)});return d});case "depth.func":return h(function(c){p.commandParameter(c,Ea,"invalid "+a,b.commandStr);return Ea[c]},function(b,c,d){var f=b.constants.compareFuncs;p.optional(function(){b.assert(c,d+" in "+f,"invalid "+a+", must be one of "+Object.keys(Ea))});return c.def(f,"[",d,"]")});case "depth.range":return h(function(a){p.command(H(a)&&2===a.length&&"number"===typeof a[0]&&"number"===typeof a[1]&&a[0]<=a[1],"depth range is 2d array",b.commandStr);return a},function(a, 168 | b,c){p.optional(function(){a.assert(b,a.shared.isArrayLike+"("+c+")&&"+c+".length===2&&typeof "+c+'[0]==="number"&&typeof '+c+'[1]==="number"&&'+c+"[0]<="+c+"[1]","depth range must be a 2d array")});var d=b.def("+",c,"[0]"),f=b.def("+",c,"[1]");return[d,f]});case "blend.func":return h(function(a){p.commandType(a,"object","blend.func",b.commandStr);var c="srcRGB"in a?a.srcRGB:a.src,d="srcAlpha"in a?a.srcAlpha:a.src,f="dstRGB"in a?a.dstRGB:a.dst;a="dstAlpha"in a?a.dstAlpha:a.dst;p.commandParameter(c, 169 | oa,g+".srcRGB",b.commandStr);p.commandParameter(d,oa,g+".srcAlpha",b.commandStr);p.commandParameter(f,oa,g+".dstRGB",b.commandStr);p.commandParameter(a,oa,g+".dstAlpha",b.commandStr);p.command(-1===zb.indexOf(c+", "+f),"unallowed blending combination (srcRGB, dstRGB) = ("+c+", "+f+")",b.commandStr);return[oa[c],oa[f],oa[d],oa[a]]},function(b,c,d){function f(f,h){var g=c.def('"',f,h,'" in ',d,"?",d,".",f,h,":",d,".",f);p.optional(function(){b.assert(c,g+" in "+e,"invalid "+a+"."+f+h+", must be one of "+ 170 | Object.keys(oa))});return g}var e=b.constants.blendFuncs;p.optional(function(){b.assert(c,d+"&&typeof "+d+'==="object"',"invalid blend func, must be an object")});var h=f("src","RGB"),g=f("dst","RGB");p.optional(function(){b.assert(c,b.constants.invalidBlendCombinations+".indexOf("+h+'+", "+'+g+") === -1 ","unallowed blending combination for (srcRGB, dstRGB)")});var m=c.def(e,"[",h,"]"),k=c.def(e,"[",f("src","Alpha"),"]"),r=c.def(e,"[",g,"]"),n=c.def(e,"[",f("dst","Alpha"),"]");return[m,r,k,n]}); 171 | case "blend.equation":return h(function(c){if("string"===typeof c)return p.commandParameter(c,V,"invalid "+a,b.commandStr),[V[c],V[c]];if("object"===typeof c)return p.commandParameter(c.rgb,V,a+".rgb",b.commandStr),p.commandParameter(c.alpha,V,a+".alpha",b.commandStr),[V[c.rgb],V[c.alpha]];p.commandRaise("invalid blend.equation",b.commandStr)},function(b,c,d){var f=b.constants.blendEquations,e=c.def(),h=c.def(),g=b.cond("typeof ",d,'==="string"');p.optional(function(){function c(a,c,d){b.assert(a, 172 | d+" in "+f,"invalid "+c+", must be one of "+Object.keys(V))}c(g.then,a,d);b.assert(g.else,d+"&&typeof "+d+'==="object"',"invalid "+a);c(g.else,a+".rgb",d+".rgb");c(g.else,a+".alpha",d+".alpha")});g.then(e,"=",h,"=",f,"[",d,"];");g.else(e,"=",f,"[",d,".rgb];",h,"=",f,"[",d,".alpha];");c(g);return[e,h]});case "blend.color":return h(function(a){p.command(H(a)&&4===a.length,"blend.color must be a 4d array",b.commandStr);return R(4,function(b){return+a[b]})},function(a,b,c){p.optional(function(){a.assert(b, 173 | a.shared.isArrayLike+"("+c+")&&"+c+".length===4","blend.color must be a 4d array")});return R(4,function(a){return b.def("+",c,"[",a,"]")})});case "stencil.mask":return h(function(a){p.commandType(a,"number",g,b.commandStr);return a|0},function(a,b,c){p.optional(function(){a.assert(b,"typeof "+c+'==="number"',"invalid stencil.mask")});return b.def(c,"|0")});case "stencil.func":return h(function(c){p.commandType(c,"object",g,b.commandStr);var d=c.cmp||"keep",f=c.ref||0;c="mask"in c?c.mask:-1;p.commandParameter(d, 174 | Ea,a+".cmp",b.commandStr);p.commandType(f,"number",a+".ref",b.commandStr);p.commandType(c,"number",a+".mask",b.commandStr);return[Ea[d],f,c]},function(a,b,c){var d=a.constants.compareFuncs;p.optional(function(){function f(){a.assert(b,Array.prototype.join.call(arguments,""),"invalid stencil.func")}f(c+"&&typeof ",c,'==="object"');f('!("cmp" in ',c,")||(",c,".cmp in ",d,")")});var f=b.def('"cmp" in ',c,"?",d,"[",c,".cmp]",":",7680),e=b.def(c,".ref|0"),h=b.def('"mask" in ',c,"?",c,".mask|0:-1");return[f, 175 | e,h]});case "stencil.opFront":case "stencil.opBack":return h(function(c){p.commandType(c,"object",g,b.commandStr);var d=c.fail||"keep",f=c.zfail||"keep";c=c.zpass||"keep";p.commandParameter(d,ua,a+".fail",b.commandStr);p.commandParameter(f,ua,a+".zfail",b.commandStr);p.commandParameter(c,ua,a+".zpass",b.commandStr);return["stencil.opBack"===a?1029:1028,ua[d],ua[f],ua[c]]},function(b,c,d){function f(f){p.optional(function(){b.assert(c,'!("'+f+'" in '+d+")||("+d+"."+f+" in "+e+")","invalid "+a+"."+ 176 | f+", must be one of "+Object.keys(ua))});return c.def('"',f,'" in ',d,"?",e,"[",d,".",f,"]:",7680)}var e=b.constants.stencilOps;p.optional(function(){b.assert(c,d+"&&typeof "+d+'==="object"',"invalid "+a)});return["stencil.opBack"===a?1029:1028,f("fail"),f("zfail"),f("zpass")]});case "polygonOffset.offset":return h(function(a){p.commandType(a,"object",g,b.commandStr);var c=a.factor|0;a=a.units|0;p.commandType(c,"number",g+".factor",b.commandStr);p.commandType(a,"number",g+".units",b.commandStr);return[c, 177 | a]},function(b,c,d){p.optional(function(){b.assert(c,d+"&&typeof "+d+'==="object"',"invalid "+a)});var f=c.def(d,".factor|0"),e=c.def(d,".units|0");return[f,e]});case "cull.face":return h(function(a){var c=0;"front"===a?c=1028:"back"===a&&(c=1029);p.command(!!c,g,b.commandStr);return c},function(a,b,c){p.optional(function(){a.assert(b,c+'==="front"||'+c+'==="back"',"invalid cull.face")});return b.def(c,'==="front"?',1028,":",1029)});case "lineWidth":return h(function(a){p.command("number"===typeof a&& 178 | a>=d.lineWidthDims[0]&&a<=d.lineWidthDims[1],"invalid line width, must positive number between "+d.lineWidthDims[0]+" and "+d.lineWidthDims[1],b.commandStr);return a},function(a,b,c){p.optional(function(){a.assert(b,"typeof "+c+'==="number"&&'+c+">="+d.lineWidthDims[0]+"&&"+c+"<="+d.lineWidthDims[1],"invalid line width")});return c});case "frontFace":return h(function(a){p.commandParameter(a,db,g,b.commandStr);return db[a]},function(a,b,c){p.optional(function(){a.assert(b,c+'==="cw"||'+c+'==="ccw"', 179 | "invalid frontFace, must be one of cw,ccw")});return b.def(c+'==="cw"?2304:2305')});case "colorMask":return h(function(a){p.command(H(a)&&4===a.length,"color.mask must be length 4 array",b.commandStr);return a.map(function(a){return!!a})},function(a,b,c){p.optional(function(){a.assert(b,a.shared.isArrayLike+"("+c+")&&"+c+".length===4","invalid color.mask")});return R(4,function(a){return"!!"+c+"["+a+"]"})});case "sample.coverage":return h(function(a){p.command("object"===typeof a&&a,g,b.commandStr); 180 | var c="value"in a?a.value:1;a=!!a.invert;p.command("number"===typeof c&&0<=c&&1>=c,"sample.coverage.value must be a number between 0 and 1",b.commandStr);return[c,a]},function(a,b,c){p.optional(function(){a.assert(b,c+"&&typeof "+c+'==="object"',"invalid sample.coverage")});var d=b.def('"value" in ',c,"?+",c,".value:1"),f=b.def("!!",c,".invert");return[d,f]})}});return e}function va(a,b){var c=a.static,d=a.dynamic,f={};Object.keys(c).forEach(function(a){var d=c[a];if("number"===typeof d||"boolean"=== 181 | typeof d)var e=I(function(){return d});else if("function"===typeof d){var h=d._reglType;"texture2d"===h||"textureCube"===h?e=I(function(a){return a.link(d)}):"framebuffer"===h||"framebufferCube"===h?(p.command(0=r.length,"invalid constant for attribute "+a,c.commandStr),Fa.forEach(function(a,b){bl,'invalid stride for attribute "'+a+'", must be integer betweeen [0, 255]',c.commandStr);var q=e.size|0;p.command(!("size"in e)||0=q,'invalid size for attribute "'+a+'", must be 1,2,3,4',c.commandStr);var D=!!e.normalized,v=0;"type"in e&&(p.commandParameter(e.type,Ja,"invalid type for attribute "+a,c.commandStr),v=Ja[e.type]);var t=e.divisor|0;"divisor"in e&&(p.command(0===t|| 185 | K,'cannot specify divisor for attribute "'+a+'", instancing not supported',c.commandStr),p.command(0<=t,'invalid divisor for attribute "'+a+'"',c.commandStr));p.optional(function(){var b=c.commandStr,d="buffer offset divisor normalized type size stride".split(" ");Object.keys(e).forEach(function(c){p.command(0<=d.indexOf(c),'unknown parameter "'+c+'" for attribute pointer "'+a+'" (valid parameters are '+d+")",b)})});m.buffer=k;m.state=1;m.size=q;m.normalized=D;m.type=v||k.dtype;m.offset=n;m.stride= 186 | l;m.divisor=t}}h[a]=I(function(a,b){b=a.attribCache;if(g in b)return b[g];var c={isStream:!1};Object.keys(m).forEach(function(a){c[a]=m[a]});m.buffer&&(c.buffer=a.link(m.buffer),c.type=c.type||c.buffer+".dtype");return b[g]=c})});Object.keys(e).forEach(function(a){var b=e[a];h[a]=Y(b,function(c,d){function f(a){d(k[a],"=",e,".",a,"|0;")}var e=c.invoke(d,b),h=c.shared,g=h.isBufferArgs,m=h.buffer;p.optional(function(){c.assert(d,e+"&&(typeof "+e+'==="object"||typeof '+e+'==="function")&&('+g+"("+e+ 187 | ")||"+m+".getBuffer("+e+")||"+m+".getBuffer("+e+".buffer)||"+g+"("+e+'.buffer)||("constant" in '+e+"&&(typeof "+e+'.constant==="number"||'+h.isArrayLike+"("+e+".constant))))",'invalid dynamic attribute "'+a+'"')});var k={isStream:d.def(!1)},r=new G;r.state=1;Object.keys(r).forEach(function(a){k[a]=d.def(""+r[a])});var n=k.buffer,l=k.type;d("if(",g,"(",e,")){",k.isStream,"=true;",n,"=",m,".createStream(",34962,",",e,");",l,"=",n,".dtype;","}else{",n,"=",m,".getBuffer(",e,");","if(",n,"){",l,"=",n, 188 | ".dtype;",'}else if("constant" in ',e,"){",k.state,"=",2,";","if(typeof "+e+'.constant === "number"){',k[Fa[0]],"=",e,".constant;",Fa.slice(1).map(function(a){return k[a]}).join("="),"=0;","}else{",Fa.map(function(a,b){return k[a]+"="+e+".constant.length>="+b+"?"+e+".constant["+b+"]:0;"}).join(""),"}}else{","if(",g,"(",e,".buffer)){",n,"=",m,".createStream(",34962,",",e,".buffer);","}else{",n,"=",m,".getBuffer(",e,".buffer);","}",l,'="type" in ',e,"?",h.glTypes,"[",e,".type]:",n,".dtype;",k.normalized, 189 | "=!!",e,".normalized;");f("size");f("offset");f("stride");f("divisor");d("}}");d.exit("if(",k.isStream,"){",m,".destroyStream(",n,");","}");return k})});return h}function da(a){var b=a.static,c=a.dynamic,d={};Object.keys(b).forEach(function(a){var c=b[a];d[a]=I(function(a,b){return"number"===typeof c||"boolean"===typeof c?""+c:a.link(c)})});Object.keys(c).forEach(function(a){var b=c[a];d[a]=Y(b,function(a,c){return a.invoke(c,b)})});return d}function S(a,b,c,d,f){function e(a){var b=k[a];b&&(l[a]= 190 | b)}var h=a.static,g=a.dynamic;p.optional(function(){function a(a){Object.keys(a).forEach(function(a){p.command(0<=b.indexOf(a),'unknown parameter "'+a+'"',f.commandStr)})}var b="framebuffer vert frag elements primitive offset count instances profile".split(" ").concat(La);a(h);a(g)});var m=w(a,f),k=z(a,m,f),n=B(a,f),l=pa(a,f),q=A(a,f);e("viewport");e(r("scissor.box"));var D=0>1)",u],");")}function b(){c(t,".drawArraysInstancedANGLE(", 208 | [l,q,v,u],");")}n?D?a():(c("if(",n,"){"),a(),c("}else{"),b(),c("}")):b()}function h(){function a(){c(m+".drawElements("+[l,v,x,q+"<<(("+x+"-5121)>>1)"]+");")}function b(){c(m+".drawArrays("+[l,q,v]+");")}n?D?a():(c("if(",n,"){"),a(),c("}else{"),b(),c("}")):b()}var g=a.shared,m=g.gl,k=g.draw,r=d.draw,n=function(){var f=r.elements,e=b;if(f){if(f.contextDep&&d.contextDynamic||f.propDep)e=c;f=f.append(a,e)}else f=e.def(k,".","elements");f&&e("if("+f+")"+m+".bindBuffer(34963,"+f+".buffer.buffer);");return f}(), 209 | l=f("primitive"),q=f("offset"),v=function(){var f=r.count,e=b;if(f){if(f.contextDep&&d.contextDynamic||f.propDep)e=c;var h=f.append(a,e);p.optional(function(){f.MISSING&&a.assert(b,"false","missing vertex count");f.DYNAMIC&&a.assert(e,h+">=0","missing vertex count")})}else h=e.def(k,".","count"),p.optional(function(){a.assert(e,h+">=0","missing vertex count")});return h}();if("number"===typeof v){if(0===v)return}else c("if(",v,"){"),c.exit("}");if(K){var u=f("instances");var t=a.instancing}var x= 210 | n+".type",D=r.elements&&ta(r.elements);K&&("number"!==typeof u||0<=u)?"string"===typeof u?(c("if(",u,">0){"),e(),c("}else if(",u,"<0){"),h(),c("}")):e():h()}function ma(a,b,c,d,f){var e=y();f=e.proc("body",f);p.optional(function(){e.commandStr=b.commandStr;e.command=e.link(b.commandStr)});K&&(e.instancing=f.def(e.shared.extensions,".angle_instanced_arrays"));a(e,f,c,d);return e.compile().body}function Q(a,b,c,d){P(a,b);J(a,b,c,d.attributes,function(){return!0});Qa(a,b,c,d.uniforms,function(){return!0}); 211 | C(a,b,b,c)}function N(a,b){var c=a.proc("draw",1);P(a,c);Ra(a,c,b.context);ea(a,c,b.framebuffer);kb(a,c,b);ba(a,c,b.state);Pa(a,c,b,!1,!0);var d=b.shader.progVar.append(a,c);c(a.shared.gl,".useProgram(",d,".program);");if(b.shader.program)Q(a,c,b,b.shader.program);else{var f=a.global.def("{}"),e=c.def(d,".id"),h=c.def(f,"[",e,"]");c(a.cond(h).then(h,".call(this,a0);").else(h,"=",f,"[",e,"]=",a.link(function(c){return ma(Q,a,b,c,1)}),"(",d,");",h,".call(this,a0);"))}0Db.indexOf(a)&&e('invalid regl constructor argument "'+a+ 228 | '". must be one of '+Db)})},type:function(a,b,c){typeof a!==b&&e("invalid parameter type"+g(c)+". expected "+b+", got "+typeof a)},commandType:w,isTypedArray:function(a,b){E(a)||e("invalid parameter type"+g(b)+". must be a typed array")},nni:function(a,b){0<=a&&(a|0)===a||e("invalid parameter type, ("+a+")"+g(b)+". must be a nonnegative integer")},oneOf:l,shaderError:function(c,d,e,h,g){if(!c.getShaderParameter(d,c.COMPILE_STATUS)){d=c.getShaderInfoLog(d);c=h===c.FRAGMENT_SHADER?"fragment":"vertex"; 229 | w(e,"string",c+" shader source must be a string",g);var k=b(e,g);e=m(d);f(k,e);Object.keys(k).forEach(function(a){function b(a,b){d.push(a);f.push(b||"")}var c=k[a];if(c.hasErrors){var d=[""],f=[""];b("file number "+a+": "+c.name+"\n","color:red;text-decoration:underline;font-weight:bold");c.lines.forEach(function(a){if(0d.extensions.indexOf("oes_texture_float_linear")&&a(9728===b.minFilter&&9728===b.magFilter,"filter not supported, must enable oes_texture_float_linear"),a(!b.genMipmaps,"mipmap generation not supported with float textures"));var g=c.images;for(d=0;16>d;++d)if(g[d]){var m=f>>d,k=e>>d;a(c.mipmask&1<n;++n){var r=k[n];if(r){var l=e>>n,p=h>>n;a(m.mipmask&1<=--this.refCount&&h(this)};f.profile&&(d.getTotalRenderbufferSize=function(){var a=0;Object.keys(n).forEach(function(b){a+=n[b].stats.size});return a});return{create:function(b,h){function k(b,d){var e=0,h=0,n=32854; 247 | "object"===typeof b&&b?("shape"in b?(d=b.shape,p(Array.isArray(d)&&2<=d.length,"invalid renderbuffer shape"),e=d[0]|0,h=d[1]|0):("radius"in b&&(e=h=b.radius|0),"width"in b&&(e=b.width|0),"height"in b&&(h=b.height|0)),"format"in b&&(p.parameter(b.format,g,"invalid renderbuffer format"),n=g[b.format])):"number"===typeof b?(e=b|0,h="number"===typeof d?d|0:e):b?p.raise("invalid arguments to renderbuffer constructor"):e=h=1;p(0":516,notequal:517,"!=":517,"!==":517,gequal:518,">=":518,always:519},ua={0:0,zero:0,keep:7680,replace:7681,increment:7682,decrement:7683,"increment wrap":34055,"decrement wrap":34056,invert:5386},Ab={frag:35632,vert:35633},db={cw:2304,ccw:2305},Bb=new ca(!1,!1,!1,function(){}),Zb=function(a,b){function c(){this.endQueryIndex=this.startQueryIndex=-1;this.sum=0;this.stats=null}function d(a,b,d){var f= 253 | g.pop()||new c;f.startQueryIndex=a;f.endQueryIndex=b;f.sum=0;f.stats=d;m.push(f)}var f=b.ext_disjoint_timer_query;if(!f)return null;var e=[],h=[],g=[],m=[],k=[],n=[];return{beginQuery:function(a){var b=e.pop()||f.createQueryEXT();f.beginQueryEXT(35007,b);h.push(b);d(h.length-1,h.length,a)},endQuery:function(){f.endQueryEXT(35007)},pushScopeStats:d,update:function(){var a;var b=h.length;if(0!==b){n.length=Math.max(n.length,b+1);k.length=Math.max(k.length,b+1);k[0]=0;var c=n[0]=0;for(a=b=0;a=O.length&&d()}var c=Cb(O,a);p(0<=c,"cannot cancel a frame twice");O[c]=b}}}function k(){var a=fa.viewport,b=fa.scissor_box;a[0]=a[1]=b[0]=b[1]=0;C.viewportWidth=C.framebufferWidth=C.drawingBufferWidth=a[2]=b[2]=r.drawingBufferWidth;C.viewportHeight=C.framebufferHeight= 260 | C.drawingBufferHeight=a[3]=b[3]=r.drawingBufferHeight}function n(){C.tick+=1;C.time=q();k();L.procs.poll()}function l(){k();L.procs.refresh();z&&z.update()}function q(){return(Eb()-A)/1E3}a=Q(a);if(!a)return null;var r=a.gl,v=r.getContextAttributes(),u=r.isContextLost(),t=T(r,a);if(!t)return null;var x=X(),y={bufferCount:0,elementsCount:0,framebufferCount:0,shaderCount:0,textureCount:0,cubeCount:0,renderbufferCount:0,maxTextureUnits:0},w=t.extensions,z=Zb(r,w),A=Eb(),P=r.drawingBufferWidth,J=r.drawingBufferHeight, 261 | C={tick:0,time:0,viewportWidth:P,viewportHeight:J,framebufferWidth:P,framebufferHeight:J,drawingBufferWidth:P,drawingBufferHeight:J,pixelRatio:a.pixelRatio},E=Xb(r,w),F=Fb(r,y,a),I=Hb(r,w,F,y),P=Rb(r,w,E,F,x),K=Sb(r,x,y,a),G=Kb(r,w,E,function(){L.procs.poll()},C,y,a),M=Yb(r,w,E,y,a),H=Nb(r,w,E,G,M,y),L=Vb(r,x,w,E,F,I,G,H,{},P,K,{elements:null,primitive:4,count:-1,offset:0,instances:-1},C,z,a),x=Tb(r,H,L.procs.poll,C,v,w),fa=L.next,R=r.canvas,O=[],W=[],Y=[],Z=[a.onDestroy],U=null;R&&(R.addEventListener("webglcontextlost", 262 | f,!1),R.addEventListener("webglcontextrestored",e,!1));var ca=H.setFBO=h({framebuffer:la.define.call(null,1,"framebuffer")});l();v=N(h,{clear:function(a){p("object"===typeof a&&a,"regl.clear() takes an object as input");if("framebuffer"in a)if(a.framebuffer&&"framebufferCube"===a.framebuffer_reglType)for(var b=0;6>b;++b)ca(N({framebuffer:a.framebuffer.faces[b]},a),g);else ca(a,g);else g(null,a)},prop:la.define.bind(null,1),context:la.define.bind(null,2),this:la.define.bind(null,3),draw:h({}),buffer:function(a){return F.create(a, 263 | 34962,!1,!1)},elements:function(a){return I.create(a,!1)},texture:G.create2D,cube:G.createCube,renderbuffer:M.create,framebuffer:H.create,framebufferCube:H.createCube,attributes:v,frame:m,on:function(a,b){p.type(b,"function","listener callback must be a function");switch(a){case "frame":return m(b);case "lost":var c=W;break;case "restore":c=Y;break;case "destroy":c=Z;break;default:p.raise("invalid event, must be one of frame,lost,restore,destroy")}c.push(b);return{cancel:function(){for(var a=0;a< 264 | c.length;++a)if(c[a]===b){c[a]=c[c.length-1];c.pop();break}}}},limits:E,hasExtension:function(a){return 0<=E.extensions.indexOf(a.toLowerCase())},read:x,destroy:function(){O.length=0;d();R&&(R.removeEventListener("webglcontextlost",f),R.removeEventListener("webglcontextrestored",e));K.clear();H.clear();M.clear();G.clear();I.clear();F.clear();z&&z.clear();Z.forEach(function(a){a()})},_gl:r,_refresh:l,poll:function(){n();z&&z.update()},now:q,stats:y});a.onDone(null,v);return v}})},{}],10:[function(l, 265 | w,t){function k(a,b){for(var c=Array(a.length-1),d=1;d>1;return["sum(",e(a.slice(0,b)),",",e(a.slice(b)),")"].join("")}function a(b){if(2===b.length)return[["sum(prod(",b[0][0],",",b[1][1],"),prod(-",b[0][1],",",b[1][0],"))"].join("")];for(var c=[],d=0;d=e)return h;f+=e}else if(0>f){if(0<=e)return h;f=-(f+e)}else return h;f*=3.3306690738754716E-16;return h>=f||h<=-f?h:c(a,b,d)},function(a,b,c,e){var f=a[0]-e[0],h=b[0]- 268 | e[0],g=c[0]-e[0],m=a[1]-e[1],k=b[1]-e[1],n=c[1]-e[1],l=a[2]-e[2],q=b[2]-e[2],u=c[2]-e[2],v=h*n,t=g*k,g=g*m,n=f*n,f=f*k,m=h*m,h=l*(v-t)+q*(g-n)+u*(f-m),l=7.771561172376103E-16*((Math.abs(v)+Math.abs(t))*Math.abs(l)+(Math.abs(g)+Math.abs(n))*Math.abs(q)+(Math.abs(f)+Math.abs(m))*Math.abs(u));return h>l||-h>l?h:d(a,b,c,e)}];(function(){for(;5>=b.length;)b.push(g(b.length));for(var a=[],c=["slow"],d=0;5>=d;++d)a.push("a"+d),c.push("o"+d);for(var e=["function getOrientation(",a.join(),"){switch(arguments.length){case 0:case 1:return 0;"], 269 | d=2;5>=d;++d)e.push("case ",d,":return o",d,"(",a.slice(0,d).join(),");");e.push("}var s=new Array(arguments.length);for(var i=0;i=d;++d)w.exports[d]=b[d]})()},{"robust-scale":11,"robust-subtract":12,"robust-sum":13,"two-product":15}],11:[function(l,w,t){var k=l("two-product"),e=l("two-sum");w.exports=function(a,g){var l= 270 | a.length;if(1===l)return a=k(a[0],g),a[0]?a:[a[1]];var u=Array(2*l),n=[.1,.1],t=[.1,.1],q=0;k(a[0],g,n);n[0]&&(u[q++]=n[0]);for(var c=1;c=g){var h=c;n+=1;n=g){var h= 273 | c;n+=1;n>1,g=k(a[e],d);0>=g?(0===g&&(f=e),b=e+1):0t))for(;!(b[t++].push(c),t>=a.length||0!==k(a[t],f)););}return b}function n(c,d){if(0>d)return[];for(var b=[],e=(1<>>q&1&&n.push(f[q]);d.push(n)}return a(d)};t.skeleton=n;t.boundary=function(c){for(var d=[],b=0,e=c.length;bf[h]?(f[h]=e.length,e.push([c[b].slice(0)])):e[f[h]].push(c[b].slice(0));return e}d=g(a(n(c,0)));b=new q(d.length);for(e=0;eh[k]?(h[k]=f.length,f.push([c[e].slice(0)])):f[h[k]].push(c[e].slice(0));return f}},{"bit-twiddle":1,"union-find":17}],15:[function(l,w,t){w.exports=function(e,a,g){var l=e*a,t=k*e,t=t-(t-e);e-=t;var n=k*a,n=n-(n-a);a-=n;a=e*a-(l-t*n-e*n-t*a);return g?(g[0]=a,g[1]=l,g):[a,l]};var k=+(Math.pow(2,27)+1)},{}],16:[function(l,w,t){w.exports=function(k,e,a){var g=k+e,l=g-k;e-=l;k-=g-l;return a?(a[0]=k+e,a[1]=g,a):[k+e,g]}},{}],17:[function(l,w,t){function k(e){this.roots=Array(e); 281 | this.ranks=Array(e);for(var a=0;a=e?e:k};l=function(){function a(){if(!(this instanceof a))throw new TypeError("Cannot call a class as a function");this.canvas=document.createElement("canvas");this.ctx=this.canvas.getContext("2d");this.height=this.width=0}k(a,[{key:"load",value:function(a,e,k){e=Math.min(e/a.width,e/a.height);this.width= 284 | Math.round(a.width*e);this.height=Math.round(a.height*e);this.canvas.width=this.width;this.canvas.height=this.height;this.ctx.drawImage(a,0,0,this.width,this.height);a=this.imageData=this.ctx.getImageData(0,0,this.width,this.height);e=new Float32Array(a.data.length/4);for(var g=0;gX||0>Ga||X>=e||Ga>=g||(f+=a[X+Ga*e],h++)}}catch(Z){u=!0,w=Z}finally{try{!t&&x.return&&x.return()}finally{if(u)throw w;}}var t=f/h,h=f=0,u=!0,w=!1,L=void 0;try{for(var M=k[Symbol.iterator](),C;!(u=(C=M.next()).done);u=!0){var Q=C.value,T=d+Q.x,K=m+Q.y;if(!(0>T|| 286 | 0>K||T>=e||K>=g)){var R=a[T+K*e],f=f+(R-t)*(R-t);h++}}}catch(Z){w=!0,L=Z}finally{try{!u&&M.return&&M.return()}finally{if(w)throw L;}}d=Math.sqrt(f/h);l[b]=d;dc&&(c=d)}for(var Ha in l)l[Ha]=(l[Ha]-q)/(c-q);this.sDev=l}},{key:"getRGBA",value:function(a,k){a=e(0,this.imageData.width,~~a);k=e(0,this.imageData.height,~~k);var g=this.imageData.width;return[this.imageData.data[4*(a+k*g)+0]/255,this.imageData.data[4*(a+k*g)+1]/255,this.imageData.data[4*(a+k*g)+2]/255,this.imageData.data[4*(a+ 287 | k*g)+3]/255]}},{key:"getLuminance",value:function(a,k){a=e(0,this.width,~~a);k=e(0,this.height,~~k);return this.luminance[a+k*this.imageData.width]}},{key:"getSDev",value:function(a,k){a=e(0,this.width,~~a);k=e(0,this.height,~~k);return this.sDev[a+k*this.imageData.width]}}]);return a}();t.default=l},{}],20:[function(l,w,t){function k(a){return a&&a.__esModule?a:{default:a}}w=function(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]= 288 | a[c]);b.default=a;return b}(l("d3-force"));t=l("delaunay-triangulate");var e=k(t);t=l("./colorpicker");t=k(t);l=l("./renderer");var a={},g=new (k(l).default)(a),x=new t.default,u=new Image,n=1,y=function(a,c,d){var b=Math.cos(d);d=Math.sin(d);return[b*a-d*c,d*a+b*c]},q=[],c=w.forceSimulation(q).velocityDecay(.2).force("collide",w.forceCollide().radius(function(a,c){var b=a.x*n+x.width/2,d=a.y*-n+x.height/2;c=1-x.getSDev(b,d);a.color=x.getRGBA(b,d);b=y(a.x,a.y,-.001);a.vx+=.999*b[0]-a.x;a.vy+=.999* 289 | b[1]-a.y;a.r=.01+.3*Math.pow(c,6);return a.r}).strength(.7).iterations(2)),d=function(){for(var a=0q.length?d(1):q.shift();c.nodes(q);c.tick();a.points=q.map(function(a){return[a.x,a.y]});a.colors=q.map(function(a){return a.color});a.triangles=(0,e.default)(a.points); 290 | a.lines=[];for(var b in a.triangles)a.lines.push([a.triangles[b][0],a.triangles[b][1]]),a.lines.push([a.triangles[b][1],a.triangles[b][2]]),a.lines.push([a.triangles[b][2],a.triangles[b][0]])})};u.src="img/mask.jpg"},{"./colorpicker":19,"./renderer":21,"d3-force":4,"delaunay-triangulate":7}],21:[function(l,w,t){Object.defineProperty(t,"__esModule",{value:!0});var k=function(){function a(a,e){for(var g=0;g 1.0) {\n discard;\n }\n gl_FragColor = vec4(color.rgb, 1.0 - len);\n }",vert:"\n precision mediump float;\n attribute vec2 position;\n uniform vec2 aspect;\n uniform float zoom;\n\n void main() {\n gl_PointSize = 3.0;\n gl_Position = vec4(position * aspect * zoom, 0.0, 1.0);\n }", 292 | blend:{enable:!0,func:{srcRGB:"src alpha",srcAlpha:1,dstRGB:"one",dstAlpha:1},equation:{rgb:"add",alpha:"add"}},uniforms:{aspect:e.prop("aspect"),zoom:e.prop("zoom"),color:e.prop("color")},attributes:{position:e.prop("position")},count:e.prop("count"),primitive:"points"}),g=e({frag:"\n precision mediump float;\n varying lowp vec4 vColor;\n void main() {\n gl_FragColor = vec4(vColor.rgb, 0.5);\n }",vert:"\n precision mediump float;\n attribute vec2 position;\n attribute vec4 color;\n uniform vec2 aspect;\n uniform float zoom;\n varying lowp vec4 vColor;\n\n void main() {\n gl_Position = vec4(position * aspect * zoom, 0.5, 1.0);\n vColor = color;\n }", 293 | blend:{enable:!0,func:{srcRGB:"src alpha",srcAlpha:1,dstRGB:"one",dstAlpha:1},equation:{rgb:"add",alpha:"add"}},uniforms:{aspect:e.prop("aspect"),zoom:e.prop("zoom")},attributes:{position:e.prop("position"),color:e.prop("color")},elements:e.prop("elements"),primitive:"line",lineWidth:1}),x=e({frag:"\n precision mediump float;\n varying lowp vec4 vColor;\n void main() {\n gl_FragColor = vec4(vColor.rgb, 0.8);\n }",vert:"\n precision mediump float;\n attribute vec2 position;\n attribute vec4 color;\n uniform vec2 aspect;\n uniform float zoom;\n varying lowp vec4 vColor;\n\n void main() {\n gl_Position = vec4(position * aspect * zoom, 0.6, 1.0);\n vColor = color;\n }", 294 | blend:{enable:!0,func:{srcRGB:"src alpha",srcAlpha:1,dstRGB:"one",dstAlpha:1},equation:{rgb:"add",alpha:"add"}},uniforms:{aspect:e.prop("aspect"),zoom:e.prop("zoom")},attributes:{position:e.prop("position"),color:e.prop("color")},elements:e.prop("elements"),primitive:"triangle"});l=function(){function l(a){if(!(this instanceof l))throw new TypeError("Cannot call a class as a function");this.model=a}k(l,[{key:"start",value:function(a){var g=this;e.frame(function(e){a();g.render(e)})}},{key:"render", 295 | value:function(k){var l=k.viewportWidth;var n=k.viewportHeight;l=l>n?[n/l,1]:[1,l/n];k=1+.5*Math.sin(.1*k.time);e.clear({color:[0,0,.2,1],depth:1});x({aspect:l,zoom:k,position:this.model.points,color:this.model.colors,elements:this.model.triangles});g({aspect:l,zoom:k,position:this.model.points,color:this.model.colors,elements:this.model.lines});a({aspect:l,zoom:k,position:this.model.points,color:[1,1,1,1],count:this.model.points.length})}}]);return l}();t.default=l},{regl:9}]},{},[20]); 296 | -------------------------------------------------------------------------------- /img/mask.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoihazard/webgl-triangulation/6760be3a4a958e3b938b9509ccc87f2441069162/img/mask.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Image Triangulation Demo 9 | 65 | 66 | 67 | 68 |
69 |
70 |

XOIHAZARD.COM

71 |
72 |
73 |
74 | 78 |
79 | 80 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webgl-triangulation", 3 | "version": "0.0.1", 4 | "description": "a WebGL demo", 5 | "main": "dist/app.js", 6 | "scripts": { 7 | "build": "browserify src/main.js -t [ babelify --presets [ es2015 ] ] -t [ brfs ] -o dist/app.unchecked.js && node bin/minify.js dist/app.unchecked.js dist/app.js", 8 | "watch": "watchify src/main.js -t [ babelify --presets [ es2015 ] ] -t [ brfs ] -o dist/app.js -v", 9 | "sync": "browser-sync start --server --files='dist/**'", 10 | "dev": "concurrently -k \"npm run watch\" \"npm run sync\"", 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "author": "xoihazard", 14 | "license": "MIT", 15 | "devDependencies": { 16 | "babel-plugin-external-helpers": "^6.22.0", 17 | "babel-preset-es2015": "^6.24.1", 18 | "babelify": "^7.3.0", 19 | "brfs": "^1.4.3", 20 | "browser-sync": "^2.18.8", 21 | "browserify": "^14.3.0", 22 | "concurrently": "^3.4.0", 23 | "d3-force": "^1.0.6", 24 | "delaunay-triangulate": "^1.1.6", 25 | "google-closure-compiler": "^20170521.0.0", 26 | "regl": "^1.3.0", 27 | "watchify": "^3.9.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoihazard/webgl-triangulation/6760be3a4a958e3b938b9509ccc87f2441069162/screenshot.jpg -------------------------------------------------------------------------------- /src/colorpicker.js: -------------------------------------------------------------------------------- 1 | const constrain = (min, max, value) => { 2 | if (value <= min) { 3 | return min 4 | } else if (value >= max) { 5 | return max 6 | } else { 7 | return value 8 | } 9 | } 10 | 11 | const createKernel = (radius) => { 12 | radius = ~~radius 13 | const a = [] 14 | 15 | for (let y = -radius; y < radius + 1; y++) { 16 | for (let x = -radius; x < radius + 1; x++) { 17 | const len = Math.round(Math.sqrt(x * x + y * y)) 18 | if (len <= radius) { 19 | a.push({ 20 | x: x, 21 | y: y 22 | }) 23 | } 24 | } 25 | } 26 | 27 | return a 28 | } 29 | 30 | const createSDevArray = (luminanceArray, width, height, radius) => { 31 | const a = new Float32Array(luminanceArray.length) 32 | const kernel = createKernel(radius) 33 | 34 | let minValue = 1000000 35 | let maxValue = -1000000 36 | 37 | for (const index in a) { 38 | const x = index % width 39 | const y = ~~(index / height) 40 | 41 | // avarage 42 | let total = 0 43 | let count = 0 44 | 45 | for (const k of kernel) { 46 | const sx = x + k.x 47 | const sy = y + k.y 48 | 49 | if (sx < 0 || sy < 0 || sx >= width || sy >= height) { 50 | continue 51 | } 52 | 53 | total += luminanceArray[sx + sy * width] 54 | count++ 55 | } 56 | 57 | const average = total / count 58 | 59 | // standard deviation 60 | total = 0 61 | count = 0 62 | 63 | for (const k of kernel) { 64 | const sx = x + k.x 65 | const sy = y + k.y 66 | 67 | if (sx < 0 || sy < 0 || sx >= width || sy >= height) { 68 | continue 69 | } 70 | 71 | const value = luminanceArray[sx + sy * width] 72 | total += (value - average) * (value - average) 73 | count++ 74 | } 75 | 76 | const value = Math.sqrt(total / count) 77 | a[index] = value 78 | 79 | if (value < minValue) { 80 | minValue = value 81 | } 82 | if (value > maxValue) { 83 | maxValue = value 84 | } 85 | } 86 | 87 | // normalize 88 | for (const index in a) { 89 | a[index] = (a[index] - minValue) / (maxValue - minValue) 90 | } 91 | 92 | return a 93 | } 94 | 95 | const createLuminanceArray = (imageData) => { 96 | const a = new Float32Array(imageData.data.length / 4) 97 | 98 | for (let i = 0; i < imageData.data.length / 4; i++) { 99 | const R = imageData.data[i * 4 + 0] 100 | const G = imageData.data[i * 4 + 1] 101 | const B = imageData.data[i * 4 + 2] 102 | 103 | a[i] = (0.299 * R + 0.587 * G + 0.114 * B) / 255 104 | } 105 | 106 | return a 107 | } 108 | 109 | export default class { 110 | constructor() { 111 | this.canvas = document.createElement('canvas') 112 | this.ctx = this.canvas.getContext('2d') 113 | this.width = 0 114 | this.height = 0 115 | } 116 | 117 | load(image, size, radius) { 118 | const scale = Math.min(size / image.width, size / image.height) 119 | 120 | this.width = Math.round(image.width * scale) 121 | this.height = Math.round(image.height * scale) 122 | 123 | this.canvas.width = this.width 124 | this.canvas.height = this.height 125 | this.ctx.drawImage(image, 0, 0, this.width, this.height) 126 | 127 | this.imageData = this.ctx.getImageData(0, 0, this.width, this.height) 128 | this.luminance = createLuminanceArray(this.imageData) 129 | this.sDev = createSDevArray(this.luminance, this.width, this.height, radius) 130 | } 131 | 132 | getRGBA(x, y) { 133 | x = constrain(0, this.imageData.width, ~~x) 134 | y = constrain(0, this.imageData.height, ~~y) 135 | 136 | const w = this.imageData.width 137 | 138 | const R = this.imageData.data[(x + y * w) * 4 + 0] / 255 139 | const G = this.imageData.data[(x + y * w) * 4 + 1] / 255 140 | const B = this.imageData.data[(x + y * w) * 4 + 2] / 255 141 | const A = this.imageData.data[(x + y * w) * 4 + 3] / 255 142 | 143 | return [R, G, B, A] 144 | } 145 | 146 | getLuminance(x, y) { 147 | x = constrain(0, this.width, ~~x) 148 | y = constrain(0, this.height, ~~y) 149 | 150 | const w = this.imageData.width 151 | return this.luminance[x + y * w] 152 | } 153 | 154 | getSDev(x, y) { 155 | x = constrain(0, this.width, ~~x) 156 | y = constrain(0, this.height, ~~y) 157 | 158 | const w = this.imageData.width 159 | return this.sDev[x + y * w] 160 | } 161 | } -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import * as D3Force from 'd3-force' 2 | import DelaunayTriangulate from 'delaunay-triangulate' 3 | import ColorPicker from './colorpicker' 4 | import Renderer from './renderer' 5 | 6 | const NUM_POINTS = 1500 7 | const V_ATTRACT = 0.001 8 | const V_THETA = -0.001 9 | const V_RADIUS_MIN = 0.01 10 | const V_RADIUS_MAX = 0.3 11 | 12 | const model = {} 13 | const renderer = new Renderer(model) 14 | const picker = new ColorPicker() 15 | const image = new Image() 16 | 17 | let imageScale = 1.0 18 | 19 | const rotate = (x, y, theta) => { 20 | const c = Math.cos(theta) 21 | const s = Math.sin(theta) 22 | return [ 23 | c * x - s * y, 24 | s * x + c * y 25 | ] 26 | } 27 | 28 | const nodes = [] 29 | const simulation = D3Force.forceSimulation(nodes) 30 | .velocityDecay(0.2) 31 | .force('collide', D3Force.forceCollide() 32 | .radius((node, i) => { 33 | const x = node.x * imageScale + picker.width / 2 34 | const y = node.y * -imageScale + picker.height / 2 35 | 36 | //const l = 1 - picker.getLuminance(x, y) 37 | const l = 1 - picker.getSDev(x, y) 38 | node.color = picker.getRGBA(x, y) 39 | 40 | const r = rotate(node.x, node.y, V_THETA) 41 | 42 | node.vx += r[0] * (1 - V_ATTRACT) - node.x 43 | node.vy += r[1] * (1 - V_ATTRACT) - node.y 44 | 45 | node.r = V_RADIUS_MIN + V_RADIUS_MAX * Math.pow(l, 6) 46 | return node.r 47 | }) 48 | .strength(0.7) 49 | .iterations(2) 50 | ) 51 | 52 | const addNode = (count = 1) => { 53 | for (let i = 0; i < count; i++) { 54 | const v = rotate(Math.random() * 1.0, 0, Math.random() * Math.PI * 2) 55 | nodes.push({ 56 | x: v[0], 57 | y: v[1] 58 | }) 59 | } 60 | } 61 | 62 | image.onload = (ev) => { 63 | picker.load(image, 256, 9) 64 | imageScale = Math.min(picker.width, picker.height) * 0.5 65 | addNode(100) 66 | 67 | renderer.start(() => { 68 | if (nodes.length < NUM_POINTS) { 69 | addNode(1) 70 | } else { 71 | nodes.shift() 72 | } 73 | 74 | simulation.nodes(nodes) 75 | simulation.tick() 76 | 77 | model.points = nodes.map(node => { 78 | return [node.x, node.y] 79 | }) 80 | 81 | model.colors = nodes.map(node => { 82 | return node.color 83 | }) 84 | 85 | model.triangles = DelaunayTriangulate(model.points) 86 | model.lines = [] 87 | 88 | for (const i in model.triangles) { 89 | model.lines.push([model.triangles[i][0], model.triangles[i][1]]) 90 | model.lines.push([model.triangles[i][1], model.triangles[i][2]]) 91 | model.lines.push([model.triangles[i][2], model.triangles[i][0]]) 92 | } 93 | }) 94 | } 95 | 96 | image.src = 'img/mask.jpg' -------------------------------------------------------------------------------- /src/renderer.js: -------------------------------------------------------------------------------- 1 | import REGL from 'regl' 2 | 3 | const regl = REGL() 4 | 5 | const aspectVec2 = (width, height) => { 6 | if (width > height) { 7 | return [height / width, 1] 8 | } else { 9 | return [1, width / height] 10 | } 11 | } 12 | 13 | const drawPoints = regl({ 14 | frag: ` 15 | precision mediump float; 16 | uniform vec4 color; 17 | 18 | void main() { 19 | float len = length(gl_PointCoord.xy - 0.5) * 2.0; 20 | if (len > 1.0) { 21 | discard; 22 | } 23 | gl_FragColor = vec4(color.rgb, 1.0 - len); 24 | }`, 25 | 26 | vert: ` 27 | precision mediump float; 28 | attribute vec2 position; 29 | uniform vec2 aspect; 30 | uniform float zoom; 31 | 32 | void main() { 33 | gl_PointSize = 3.0; 34 | gl_Position = vec4(position * aspect * zoom, 0.0, 1.0); 35 | }`, 36 | 37 | blend: { 38 | enable: true, 39 | func: { 40 | srcRGB: 'src alpha', 41 | srcAlpha: 1, 42 | dstRGB: 'one', 43 | dstAlpha: 1 44 | }, 45 | equation: { 46 | rgb: 'add', 47 | alpha: 'add' 48 | } 49 | }, 50 | 51 | uniforms: { 52 | aspect: regl.prop('aspect'), 53 | zoom: regl.prop('zoom'), 54 | color: regl.prop('color') 55 | }, 56 | 57 | attributes: { 58 | position: regl.prop('position') 59 | }, 60 | 61 | count: regl.prop('count'), 62 | primitive: 'points' 63 | }) 64 | 65 | const drawLines = regl({ 66 | frag: ` 67 | precision mediump float; 68 | varying lowp vec4 vColor; 69 | void main() { 70 | gl_FragColor = vec4(vColor.rgb, 0.5); 71 | }`, 72 | vert: ` 73 | precision mediump float; 74 | attribute vec2 position; 75 | attribute vec4 color; 76 | uniform vec2 aspect; 77 | uniform float zoom; 78 | varying lowp vec4 vColor; 79 | 80 | void main() { 81 | gl_Position = vec4(position * aspect * zoom, 0.5, 1.0); 82 | vColor = color; 83 | }`, 84 | 85 | blend: { 86 | enable: true, 87 | func: { 88 | srcRGB: 'src alpha', 89 | srcAlpha: 1, 90 | dstRGB: 'one', 91 | dstAlpha: 1 92 | }, 93 | equation: { 94 | rgb: 'add', 95 | alpha: 'add' 96 | } 97 | }, 98 | 99 | uniforms: { 100 | aspect: regl.prop('aspect'), 101 | zoom: regl.prop('zoom') 102 | }, 103 | 104 | attributes: { 105 | position: regl.prop('position'), 106 | color: regl.prop('color') 107 | }, 108 | 109 | elements: regl.prop('elements'), 110 | primitive: 'line', 111 | lineWidth: 1 112 | }) 113 | 114 | const drawFaces = regl({ 115 | frag: ` 116 | precision mediump float; 117 | varying lowp vec4 vColor; 118 | void main() { 119 | gl_FragColor = vec4(vColor.rgb, 0.8); 120 | }`, 121 | vert: ` 122 | precision mediump float; 123 | attribute vec2 position; 124 | attribute vec4 color; 125 | uniform vec2 aspect; 126 | uniform float zoom; 127 | varying lowp vec4 vColor; 128 | 129 | void main() { 130 | gl_Position = vec4(position * aspect * zoom, 0.6, 1.0); 131 | vColor = color; 132 | }`, 133 | 134 | blend: { 135 | enable: true, 136 | func: { 137 | srcRGB: 'src alpha', 138 | srcAlpha: 1, 139 | dstRGB: 'one', 140 | dstAlpha: 1 141 | }, 142 | equation: { 143 | rgb: 'add', 144 | alpha: 'add' 145 | } 146 | }, 147 | 148 | uniforms: { 149 | aspect: regl.prop('aspect'), 150 | zoom: regl.prop('zoom') 151 | }, 152 | 153 | attributes: { 154 | position: regl.prop('position'), 155 | color: regl.prop('color') 156 | }, 157 | 158 | elements: regl.prop('elements'), 159 | primitive: 'triangle' 160 | }) 161 | 162 | export default class { 163 | constructor(model) { 164 | this.model = model 165 | } 166 | 167 | start(arrange) { 168 | regl.frame(ctx => { 169 | arrange() 170 | this.render(ctx) 171 | }) 172 | } 173 | 174 | render(ctx) { 175 | const aspect = aspectVec2(ctx.viewportWidth, ctx.viewportHeight) 176 | const zoom = 1 + Math.sin(ctx.time * 0.1) * 0.5 177 | 178 | regl.clear({ 179 | color: [0.0, 0.0, 0.2, 1], 180 | depth: 1 181 | }) 182 | 183 | drawFaces({ 184 | aspect: aspect, 185 | zoom: zoom, 186 | position: this.model.points, 187 | color: this.model.colors, 188 | elements: this.model.triangles 189 | }) 190 | 191 | drawLines({ 192 | aspect: aspect, 193 | zoom: zoom, 194 | position: this.model.points, 195 | color: this.model.colors, 196 | elements: this.model.lines 197 | }) 198 | 199 | drawPoints({ 200 | aspect: aspect, 201 | zoom: zoom, 202 | position: this.model.points, 203 | color: [1, 1, 1, 1], 204 | count: this.model.points.length 205 | }) 206 | } 207 | } --------------------------------------------------------------------------------