=y}},"es6","es3");
19 | $jscomp.polyfill("Array.prototype.copyWithin",function(h){function n(k){k=Number(k);return Infinity===k||-Infinity===k?k:k|0}return h?h:function(k,p,l){var y=this.length;k=n(k);p=n(p);l=void 0===l?y:n(l);k=0>k?Math.max(y+k,0):Math.min(k,y);p=0>p?Math.max(y+p,0):Math.min(p,y);l=0>l?Math.max(y+l,0):Math.min(l,y);if(kp;)--l in this?this[--k]=this[l]:delete this[--k];return this}},"es6","es3");
20 | $jscomp.typedArrayCopyWithin=function(h){return h?h:Array.prototype.copyWithin};$jscomp.polyfill("Int8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8ClampedArray.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
21 | $jscomp.polyfill("Uint16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float64Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
22 | var DracoDecoderModule=function(){var h="undefined"!==typeof document&&document.currentScript?document.currentScript.src:void 0;"undefined"!==typeof __filename&&(h=h||__filename);return function(n){function k(e){return a.locateFile?a.locateFile(e,U):U+e}function p(e,b){if(e){var c=ia;var d=e+b;for(b=e;c[b]&&!(b>=d);)++b;if(16g?d+=String.fromCharCode(g):(g-=65536,d+=String.fromCharCode(55296|g>>10,56320|g&1023))}}else d+=String.fromCharCode(g)}c=d}}else c="";return c}function l(){var e=ja.buffer;a.HEAP8=W=new Int8Array(e);a.HEAP16=new Int16Array(e);a.HEAP32=ca=new Int32Array(e);a.HEAPU8=ia=new Uint8Array(e);a.HEAPU16=new Uint16Array(e);a.HEAPU32=Y=new Uint32Array(e);a.HEAPF32=new Float32Array(e);a.HEAPF64=new Float64Array(e)}function y(e){if(a.onAbort)a.onAbort(e);
24 | e="Aborted("+e+")";da(e);sa=!0;e=new WebAssembly.RuntimeError(e+". Build with -sASSERTIONS for more info.");ka(e);throw e;}function f(e){try{if(e==P&&ea)return new Uint8Array(ea);if(ma)return ma(e);throw"both async and sync fetching of the wasm failed";}catch(b){y(b)}}function q(){if(!ea&&(ta||fa)){if("function"==typeof fetch&&!P.startsWith("file://"))return fetch(P,{credentials:"same-origin"}).then(function(e){if(!e.ok)throw"failed to load wasm binary file at '"+P+"'";return e.arrayBuffer()}).catch(function(){return f(P)});
25 | if(na)return new Promise(function(e,b){na(P,function(c){e(new Uint8Array(c))},b)})}return Promise.resolve().then(function(){return f(P)})}function u(e){for(;0>2]=b};this.get_type=function(){return Y[this.ptr+4>>2]};this.set_destructor=function(b){Y[this.ptr+8>>2]=b};this.get_destructor=function(){return Y[this.ptr+8>>2]};this.set_refcount=function(b){ca[this.ptr>>2]=b};this.set_caught=function(b){W[this.ptr+
26 | 12>>0]=b?1:0};this.get_caught=function(){return 0!=W[this.ptr+12>>0]};this.set_rethrown=function(b){W[this.ptr+13>>0]=b?1:0};this.get_rethrown=function(){return 0!=W[this.ptr+13>>0]};this.init=function(b,c){this.set_adjusted_ptr(0);this.set_type(b);this.set_destructor(c);this.set_refcount(0);this.set_caught(!1);this.set_rethrown(!1)};this.add_ref=function(){ca[this.ptr>>2]+=1};this.release_ref=function(){var b=ca[this.ptr>>2];ca[this.ptr>>2]=b-1;return 1===b};this.set_adjusted_ptr=function(b){Y[this.ptr+
27 | 16>>2]=b};this.get_adjusted_ptr=function(){return Y[this.ptr+16>>2]};this.get_exception_ptr=function(){if(ua(this.get_type()))return Y[this.excPtr>>2];var b=this.get_adjusted_ptr();return 0!==b?b:this.excPtr}}function F(){function e(){if(!la&&(la=!0,a.calledRun=!0,!sa)){va=!0;u(oa);wa(a);if(a.onRuntimeInitialized)a.onRuntimeInitialized();if(a.postRun)for("function"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;)xa.unshift(a.postRun.shift());u(xa)}}if(!(0=d?b++:2047>=d?b+=2:55296<=d&&57343>=
29 | d?(b+=4,++c):b+=3}b=Array(b+1);c=0;d=b.length;if(0=t){var aa=e.charCodeAt(++g);t=65536+((t&1023)<<10)|aa&1023}if(127>=t){if(c>=d)break;b[c++]=t}else{if(2047>=t){if(c+1>=d)break;b[c++]=192|t>>6}else{if(65535>=t){if(c+2>=d)break;b[c++]=224|t>>12}else{if(c+3>=d)break;b[c++]=240|t>>18;b[c++]=128|t>>12&63}b[c++]=128|t>>6&63}b[c++]=128|t&63}}b[c]=0}e=r.alloc(b,W);r.copy(b,W,e);return e}return e}function Z(e){if("object"===
30 | typeof e){var b=r.alloc(e,W);r.copy(e,W,b);return b}return e}function X(){throw"cannot construct a VoidPtr, no constructor in IDL";}function S(){this.ptr=za();w(S)[this.ptr]=this}function Q(){this.ptr=Aa();w(Q)[this.ptr]=this}function V(){this.ptr=Ba();w(V)[this.ptr]=this}function x(){this.ptr=Ca();w(x)[this.ptr]=this}function D(){this.ptr=Da();w(D)[this.ptr]=this}function G(){this.ptr=Ea();w(G)[this.ptr]=this}function H(){this.ptr=Fa();w(H)[this.ptr]=this}function E(){this.ptr=Ga();w(E)[this.ptr]=
31 | this}function T(){this.ptr=Ha();w(T)[this.ptr]=this}function C(){throw"cannot construct a Status, no constructor in IDL";}function I(){this.ptr=Ia();w(I)[this.ptr]=this}function J(){this.ptr=Ja();w(J)[this.ptr]=this}function K(){this.ptr=Ka();w(K)[this.ptr]=this}function L(){this.ptr=La();w(L)[this.ptr]=this}function M(){this.ptr=Ma();w(M)[this.ptr]=this}function N(){this.ptr=Na();w(N)[this.ptr]=this}function O(){this.ptr=Oa();w(O)[this.ptr]=this}function z(){this.ptr=Pa();w(z)[this.ptr]=this}function m(){this.ptr=
32 | Qa();w(m)[this.ptr]=this}n=void 0===n?{}:n;var a="undefined"!=typeof n?n:{},wa,ka;a.ready=new Promise(function(e,b){wa=e;ka=b});var Ra=!1,Sa=!1;a.onRuntimeInitialized=function(){Ra=!0;if(Sa&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.onModuleParsed=function(){Sa=!0;if(Ra&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.isVersionSupported=function(e){if("string"!==typeof e)return!1;e=e.split(".");return 2>e.length||3=e[1]?!0:0!=e[0]||10<
33 | e[1]?!1:!0};var Ta=Object.assign({},a),ta="object"==typeof window,fa="function"==typeof importScripts,Ua="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,U="";if(Ua){var Va=require("fs"),pa=require("path");U=fa?pa.dirname(U)+"/":__dirname+"/";var Wa=function(e,b){e=e.startsWith("file://")?new URL(e):pa.normalize(e);return Va.readFileSync(e,b?void 0:"utf8")};var ma=function(e){e=Wa(e,!0);e.buffer||(e=new Uint8Array(e));return e};var na=function(e,
34 | b,c){e=e.startsWith("file://")?new URL(e):pa.normalize(e);Va.readFile(e,function(d,g){d?c(d):b(g.buffer)})};1>>=0;if(2147483648=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,e+100663296);var g=Math;d=Math.max(e,d);g=g.min.call(g,2147483648,d+(65536-d%65536)%65536);a:{d=ja.buffer;try{ja.grow(g-d.byteLength+65535>>>16);l();var t=1;break a}catch(aa){}t=void 0}if(t)return!0}return!1}};(function(){function e(g,t){a.asm=g.exports;ja=a.asm.e;l();oa.unshift(a.asm.f);ba--;a.monitorRunDependencies&&a.monitorRunDependencies(ba);0==ba&&(null!==qa&&(clearInterval(qa),qa=null),ha&&(g=ha,ha=null,g()))}function b(g){e(g.instance)}
38 | function c(g){return q().then(function(t){return WebAssembly.instantiate(t,d)}).then(function(t){return t}).then(g,function(t){da("failed to asynchronously prepare wasm: "+t);y(t)})}var d={a:qd};ba++;a.monitorRunDependencies&&a.monitorRunDependencies(ba);if(a.instantiateWasm)try{return a.instantiateWasm(d,e)}catch(g){da("Module.instantiateWasm callback failed with error: "+g),ka(g)}(function(){return ea||"function"!=typeof WebAssembly.instantiateStreaming||P.startsWith("data:application/octet-stream;base64,")||
39 | P.startsWith("file://")||Ua||"function"!=typeof fetch?c(b):fetch(P,{credentials:"same-origin"}).then(function(g){return WebAssembly.instantiateStreaming(g,d).then(b,function(t){da("wasm streaming compile failed: "+t);da("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(ka);return{}})();var Xa=a._emscripten_bind_VoidPtr___destroy___0=function(){return(Xa=a._emscripten_bind_VoidPtr___destroy___0=a.asm.h).apply(null,arguments)},za=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=
40 | function(){return(za=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=a.asm.i).apply(null,arguments)},Ya=a._emscripten_bind_DecoderBuffer_Init_2=function(){return(Ya=a._emscripten_bind_DecoderBuffer_Init_2=a.asm.j).apply(null,arguments)},Za=a._emscripten_bind_DecoderBuffer___destroy___0=function(){return(Za=a._emscripten_bind_DecoderBuffer___destroy___0=a.asm.k).apply(null,arguments)},Aa=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=function(){return(Aa=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=
41 | a.asm.l).apply(null,arguments)},$a=a._emscripten_bind_AttributeTransformData_transform_type_0=function(){return($a=a._emscripten_bind_AttributeTransformData_transform_type_0=a.asm.m).apply(null,arguments)},ab=a._emscripten_bind_AttributeTransformData___destroy___0=function(){return(ab=a._emscripten_bind_AttributeTransformData___destroy___0=a.asm.n).apply(null,arguments)},Ba=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=function(){return(Ba=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=
42 | a.asm.o).apply(null,arguments)},bb=a._emscripten_bind_GeometryAttribute___destroy___0=function(){return(bb=a._emscripten_bind_GeometryAttribute___destroy___0=a.asm.p).apply(null,arguments)},Ca=a._emscripten_bind_PointAttribute_PointAttribute_0=function(){return(Ca=a._emscripten_bind_PointAttribute_PointAttribute_0=a.asm.q).apply(null,arguments)},cb=a._emscripten_bind_PointAttribute_size_0=function(){return(cb=a._emscripten_bind_PointAttribute_size_0=a.asm.r).apply(null,arguments)},db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=
43 | function(){return(db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=a.asm.s).apply(null,arguments)},eb=a._emscripten_bind_PointAttribute_attribute_type_0=function(){return(eb=a._emscripten_bind_PointAttribute_attribute_type_0=a.asm.t).apply(null,arguments)},fb=a._emscripten_bind_PointAttribute_data_type_0=function(){return(fb=a._emscripten_bind_PointAttribute_data_type_0=a.asm.u).apply(null,arguments)},gb=a._emscripten_bind_PointAttribute_num_components_0=function(){return(gb=a._emscripten_bind_PointAttribute_num_components_0=
44 | a.asm.v).apply(null,arguments)},hb=a._emscripten_bind_PointAttribute_normalized_0=function(){return(hb=a._emscripten_bind_PointAttribute_normalized_0=a.asm.w).apply(null,arguments)},ib=a._emscripten_bind_PointAttribute_byte_stride_0=function(){return(ib=a._emscripten_bind_PointAttribute_byte_stride_0=a.asm.x).apply(null,arguments)},jb=a._emscripten_bind_PointAttribute_byte_offset_0=function(){return(jb=a._emscripten_bind_PointAttribute_byte_offset_0=a.asm.y).apply(null,arguments)},kb=a._emscripten_bind_PointAttribute_unique_id_0=
45 | function(){return(kb=a._emscripten_bind_PointAttribute_unique_id_0=a.asm.z).apply(null,arguments)},lb=a._emscripten_bind_PointAttribute___destroy___0=function(){return(lb=a._emscripten_bind_PointAttribute___destroy___0=a.asm.A).apply(null,arguments)},Da=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=function(){return(Da=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=a.asm.B).apply(null,arguments)},mb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=
46 | function(){return(mb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=a.asm.C).apply(null,arguments)},nb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=function(){return(nb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=a.asm.D).apply(null,arguments)},ob=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=function(){return(ob=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=a.asm.E).apply(null,arguments)},pb=
47 | a._emscripten_bind_AttributeQuantizationTransform_range_0=function(){return(pb=a._emscripten_bind_AttributeQuantizationTransform_range_0=a.asm.F).apply(null,arguments)},qb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=function(){return(qb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=a.asm.G).apply(null,arguments)},Ea=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=function(){return(Ea=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=
48 | a.asm.H).apply(null,arguments)},rb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=function(){return(rb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=a.asm.I).apply(null,arguments)},sb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=function(){return(sb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=a.asm.J).apply(null,arguments)},tb=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=function(){return(tb=
49 | a._emscripten_bind_AttributeOctahedronTransform___destroy___0=a.asm.K).apply(null,arguments)},Fa=a._emscripten_bind_PointCloud_PointCloud_0=function(){return(Fa=a._emscripten_bind_PointCloud_PointCloud_0=a.asm.L).apply(null,arguments)},ub=a._emscripten_bind_PointCloud_num_attributes_0=function(){return(ub=a._emscripten_bind_PointCloud_num_attributes_0=a.asm.M).apply(null,arguments)},vb=a._emscripten_bind_PointCloud_num_points_0=function(){return(vb=a._emscripten_bind_PointCloud_num_points_0=a.asm.N).apply(null,
50 | arguments)},wb=a._emscripten_bind_PointCloud___destroy___0=function(){return(wb=a._emscripten_bind_PointCloud___destroy___0=a.asm.O).apply(null,arguments)},Ga=a._emscripten_bind_Mesh_Mesh_0=function(){return(Ga=a._emscripten_bind_Mesh_Mesh_0=a.asm.P).apply(null,arguments)},xb=a._emscripten_bind_Mesh_num_faces_0=function(){return(xb=a._emscripten_bind_Mesh_num_faces_0=a.asm.Q).apply(null,arguments)},yb=a._emscripten_bind_Mesh_num_attributes_0=function(){return(yb=a._emscripten_bind_Mesh_num_attributes_0=
51 | a.asm.R).apply(null,arguments)},zb=a._emscripten_bind_Mesh_num_points_0=function(){return(zb=a._emscripten_bind_Mesh_num_points_0=a.asm.S).apply(null,arguments)},Ab=a._emscripten_bind_Mesh___destroy___0=function(){return(Ab=a._emscripten_bind_Mesh___destroy___0=a.asm.T).apply(null,arguments)},Ha=a._emscripten_bind_Metadata_Metadata_0=function(){return(Ha=a._emscripten_bind_Metadata_Metadata_0=a.asm.U).apply(null,arguments)},Bb=a._emscripten_bind_Metadata___destroy___0=function(){return(Bb=a._emscripten_bind_Metadata___destroy___0=
52 | a.asm.V).apply(null,arguments)},Cb=a._emscripten_bind_Status_code_0=function(){return(Cb=a._emscripten_bind_Status_code_0=a.asm.W).apply(null,arguments)},Db=a._emscripten_bind_Status_ok_0=function(){return(Db=a._emscripten_bind_Status_ok_0=a.asm.X).apply(null,arguments)},Eb=a._emscripten_bind_Status_error_msg_0=function(){return(Eb=a._emscripten_bind_Status_error_msg_0=a.asm.Y).apply(null,arguments)},Fb=a._emscripten_bind_Status___destroy___0=function(){return(Fb=a._emscripten_bind_Status___destroy___0=
53 | a.asm.Z).apply(null,arguments)},Ia=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=function(){return(Ia=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=a.asm._).apply(null,arguments)},Gb=a._emscripten_bind_DracoFloat32Array_GetValue_1=function(){return(Gb=a._emscripten_bind_DracoFloat32Array_GetValue_1=a.asm.$).apply(null,arguments)},Hb=a._emscripten_bind_DracoFloat32Array_size_0=function(){return(Hb=a._emscripten_bind_DracoFloat32Array_size_0=a.asm.aa).apply(null,arguments)},Ib=
54 | a._emscripten_bind_DracoFloat32Array___destroy___0=function(){return(Ib=a._emscripten_bind_DracoFloat32Array___destroy___0=a.asm.ba).apply(null,arguments)},Ja=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=function(){return(Ja=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=a.asm.ca).apply(null,arguments)},Jb=a._emscripten_bind_DracoInt8Array_GetValue_1=function(){return(Jb=a._emscripten_bind_DracoInt8Array_GetValue_1=a.asm.da).apply(null,arguments)},Kb=a._emscripten_bind_DracoInt8Array_size_0=
55 | function(){return(Kb=a._emscripten_bind_DracoInt8Array_size_0=a.asm.ea).apply(null,arguments)},Lb=a._emscripten_bind_DracoInt8Array___destroy___0=function(){return(Lb=a._emscripten_bind_DracoInt8Array___destroy___0=a.asm.fa).apply(null,arguments)},Ka=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=function(){return(Ka=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=a.asm.ga).apply(null,arguments)},Mb=a._emscripten_bind_DracoUInt8Array_GetValue_1=function(){return(Mb=a._emscripten_bind_DracoUInt8Array_GetValue_1=
56 | a.asm.ha).apply(null,arguments)},Nb=a._emscripten_bind_DracoUInt8Array_size_0=function(){return(Nb=a._emscripten_bind_DracoUInt8Array_size_0=a.asm.ia).apply(null,arguments)},Ob=a._emscripten_bind_DracoUInt8Array___destroy___0=function(){return(Ob=a._emscripten_bind_DracoUInt8Array___destroy___0=a.asm.ja).apply(null,arguments)},La=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=function(){return(La=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=a.asm.ka).apply(null,arguments)},Pb=a._emscripten_bind_DracoInt16Array_GetValue_1=
57 | function(){return(Pb=a._emscripten_bind_DracoInt16Array_GetValue_1=a.asm.la).apply(null,arguments)},Qb=a._emscripten_bind_DracoInt16Array_size_0=function(){return(Qb=a._emscripten_bind_DracoInt16Array_size_0=a.asm.ma).apply(null,arguments)},Rb=a._emscripten_bind_DracoInt16Array___destroy___0=function(){return(Rb=a._emscripten_bind_DracoInt16Array___destroy___0=a.asm.na).apply(null,arguments)},Ma=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=function(){return(Ma=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=
58 | a.asm.oa).apply(null,arguments)},Sb=a._emscripten_bind_DracoUInt16Array_GetValue_1=function(){return(Sb=a._emscripten_bind_DracoUInt16Array_GetValue_1=a.asm.pa).apply(null,arguments)},Tb=a._emscripten_bind_DracoUInt16Array_size_0=function(){return(Tb=a._emscripten_bind_DracoUInt16Array_size_0=a.asm.qa).apply(null,arguments)},Ub=a._emscripten_bind_DracoUInt16Array___destroy___0=function(){return(Ub=a._emscripten_bind_DracoUInt16Array___destroy___0=a.asm.ra).apply(null,arguments)},Na=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=
59 | function(){return(Na=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=a.asm.sa).apply(null,arguments)},Vb=a._emscripten_bind_DracoInt32Array_GetValue_1=function(){return(Vb=a._emscripten_bind_DracoInt32Array_GetValue_1=a.asm.ta).apply(null,arguments)},Wb=a._emscripten_bind_DracoInt32Array_size_0=function(){return(Wb=a._emscripten_bind_DracoInt32Array_size_0=a.asm.ua).apply(null,arguments)},Xb=a._emscripten_bind_DracoInt32Array___destroy___0=function(){return(Xb=a._emscripten_bind_DracoInt32Array___destroy___0=
60 | a.asm.va).apply(null,arguments)},Oa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=function(){return(Oa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=a.asm.wa).apply(null,arguments)},Yb=a._emscripten_bind_DracoUInt32Array_GetValue_1=function(){return(Yb=a._emscripten_bind_DracoUInt32Array_GetValue_1=a.asm.xa).apply(null,arguments)},Zb=a._emscripten_bind_DracoUInt32Array_size_0=function(){return(Zb=a._emscripten_bind_DracoUInt32Array_size_0=a.asm.ya).apply(null,arguments)},$b=a._emscripten_bind_DracoUInt32Array___destroy___0=
61 | function(){return($b=a._emscripten_bind_DracoUInt32Array___destroy___0=a.asm.za).apply(null,arguments)},Pa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=function(){return(Pa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=a.asm.Aa).apply(null,arguments)},ac=a._emscripten_bind_MetadataQuerier_HasEntry_2=function(){return(ac=a._emscripten_bind_MetadataQuerier_HasEntry_2=a.asm.Ba).apply(null,arguments)},bc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=function(){return(bc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=
62 | a.asm.Ca).apply(null,arguments)},cc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=function(){return(cc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=a.asm.Da).apply(null,arguments)},dc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=function(){return(dc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=a.asm.Ea).apply(null,arguments)},ec=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=function(){return(ec=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=a.asm.Fa).apply(null,
63 | arguments)},fc=a._emscripten_bind_MetadataQuerier_NumEntries_1=function(){return(fc=a._emscripten_bind_MetadataQuerier_NumEntries_1=a.asm.Ga).apply(null,arguments)},gc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=function(){return(gc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=a.asm.Ha).apply(null,arguments)},hc=a._emscripten_bind_MetadataQuerier___destroy___0=function(){return(hc=a._emscripten_bind_MetadataQuerier___destroy___0=a.asm.Ia).apply(null,arguments)},Qa=a._emscripten_bind_Decoder_Decoder_0=
64 | function(){return(Qa=a._emscripten_bind_Decoder_Decoder_0=a.asm.Ja).apply(null,arguments)},ic=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=function(){return(ic=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=a.asm.Ka).apply(null,arguments)},jc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=function(){return(jc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=a.asm.La).apply(null,arguments)},kc=a._emscripten_bind_Decoder_GetAttributeId_2=function(){return(kc=a._emscripten_bind_Decoder_GetAttributeId_2=
65 | a.asm.Ma).apply(null,arguments)},lc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=function(){return(lc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=a.asm.Na).apply(null,arguments)},mc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=function(){return(mc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=a.asm.Oa).apply(null,arguments)},nc=a._emscripten_bind_Decoder_GetAttribute_2=function(){return(nc=a._emscripten_bind_Decoder_GetAttribute_2=a.asm.Pa).apply(null,arguments)},
66 | oc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=function(){return(oc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=a.asm.Qa).apply(null,arguments)},pc=a._emscripten_bind_Decoder_GetMetadata_1=function(){return(pc=a._emscripten_bind_Decoder_GetMetadata_1=a.asm.Ra).apply(null,arguments)},qc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=function(){return(qc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=a.asm.Sa).apply(null,arguments)},rc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=
67 | function(){return(rc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=a.asm.Ta).apply(null,arguments)},sc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=function(){return(sc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=a.asm.Ua).apply(null,arguments)},tc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=function(){return(tc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=a.asm.Va).apply(null,arguments)},uc=a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=function(){return(uc=
68 | a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=a.asm.Wa).apply(null,arguments)},vc=a._emscripten_bind_Decoder_GetAttributeFloat_3=function(){return(vc=a._emscripten_bind_Decoder_GetAttributeFloat_3=a.asm.Xa).apply(null,arguments)},wc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=function(){return(wc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=a.asm.Ya).apply(null,arguments)},xc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=function(){return(xc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=
69 | a.asm.Za).apply(null,arguments)},yc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=function(){return(yc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=a.asm._a).apply(null,arguments)},zc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=function(){return(zc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=a.asm.$a).apply(null,arguments)},Ac=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=function(){return(Ac=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=
70 | a.asm.ab).apply(null,arguments)},Bc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=function(){return(Bc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=a.asm.bb).apply(null,arguments)},Cc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=function(){return(Cc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=a.asm.cb).apply(null,arguments)},Dc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=function(){return(Dc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=
71 | a.asm.db).apply(null,arguments)},Ec=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=function(){return(Ec=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=a.asm.eb).apply(null,arguments)},Fc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=function(){return(Fc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=a.asm.fb).apply(null,arguments)},Gc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=function(){return(Gc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=
72 | a.asm.gb).apply(null,arguments)},Hc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=function(){return(Hc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=a.asm.hb).apply(null,arguments)},Ic=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=function(){return(Ic=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=a.asm.ib).apply(null,arguments)},Jc=a._emscripten_bind_Decoder___destroy___0=function(){return(Jc=a._emscripten_bind_Decoder___destroy___0=a.asm.jb).apply(null,arguments)},Kc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=
73 | function(){return(Kc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=a.asm.kb).apply(null,arguments)},Lc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=function(){return(Lc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=a.asm.lb).apply(null,arguments)},Mc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=function(){return(Mc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=
74 | a.asm.mb).apply(null,arguments)},Nc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=function(){return(Nc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=a.asm.nb).apply(null,arguments)},Oc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=function(){return(Oc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=a.asm.ob).apply(null,arguments)},Pc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=function(){return(Pc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=
75 | a.asm.pb).apply(null,arguments)},Qc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=function(){return(Qc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=a.asm.qb).apply(null,arguments)},Rc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=function(){return(Rc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=a.asm.rb).apply(null,arguments)},Sc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=function(){return(Sc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=
76 | a.asm.sb).apply(null,arguments)},Tc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=function(){return(Tc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=a.asm.tb).apply(null,arguments)},Uc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=function(){return(Uc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=a.asm.ub).apply(null,arguments)},Vc=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=function(){return(Vc=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=
77 | a.asm.vb).apply(null,arguments)},Wc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=function(){return(Wc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=a.asm.wb).apply(null,arguments)},Xc=a._emscripten_enum_draco_DataType_DT_INVALID=function(){return(Xc=a._emscripten_enum_draco_DataType_DT_INVALID=a.asm.xb).apply(null,arguments)},Yc=a._emscripten_enum_draco_DataType_DT_INT8=function(){return(Yc=a._emscripten_enum_draco_DataType_DT_INT8=a.asm.yb).apply(null,arguments)},Zc=
78 | a._emscripten_enum_draco_DataType_DT_UINT8=function(){return(Zc=a._emscripten_enum_draco_DataType_DT_UINT8=a.asm.zb).apply(null,arguments)},$c=a._emscripten_enum_draco_DataType_DT_INT16=function(){return($c=a._emscripten_enum_draco_DataType_DT_INT16=a.asm.Ab).apply(null,arguments)},ad=a._emscripten_enum_draco_DataType_DT_UINT16=function(){return(ad=a._emscripten_enum_draco_DataType_DT_UINT16=a.asm.Bb).apply(null,arguments)},bd=a._emscripten_enum_draco_DataType_DT_INT32=function(){return(bd=a._emscripten_enum_draco_DataType_DT_INT32=
79 | a.asm.Cb).apply(null,arguments)},cd=a._emscripten_enum_draco_DataType_DT_UINT32=function(){return(cd=a._emscripten_enum_draco_DataType_DT_UINT32=a.asm.Db).apply(null,arguments)},dd=a._emscripten_enum_draco_DataType_DT_INT64=function(){return(dd=a._emscripten_enum_draco_DataType_DT_INT64=a.asm.Eb).apply(null,arguments)},ed=a._emscripten_enum_draco_DataType_DT_UINT64=function(){return(ed=a._emscripten_enum_draco_DataType_DT_UINT64=a.asm.Fb).apply(null,arguments)},fd=a._emscripten_enum_draco_DataType_DT_FLOAT32=
80 | function(){return(fd=a._emscripten_enum_draco_DataType_DT_FLOAT32=a.asm.Gb).apply(null,arguments)},gd=a._emscripten_enum_draco_DataType_DT_FLOAT64=function(){return(gd=a._emscripten_enum_draco_DataType_DT_FLOAT64=a.asm.Hb).apply(null,arguments)},hd=a._emscripten_enum_draco_DataType_DT_BOOL=function(){return(hd=a._emscripten_enum_draco_DataType_DT_BOOL=a.asm.Ib).apply(null,arguments)},id=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=function(){return(id=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=
81 | a.asm.Jb).apply(null,arguments)},jd=a._emscripten_enum_draco_StatusCode_OK=function(){return(jd=a._emscripten_enum_draco_StatusCode_OK=a.asm.Kb).apply(null,arguments)},kd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=function(){return(kd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=a.asm.Lb).apply(null,arguments)},ld=a._emscripten_enum_draco_StatusCode_IO_ERROR=function(){return(ld=a._emscripten_enum_draco_StatusCode_IO_ERROR=a.asm.Mb).apply(null,arguments)},md=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=
82 | function(){return(md=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=a.asm.Nb).apply(null,arguments)},nd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=function(){return(nd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=a.asm.Ob).apply(null,arguments)},od=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=function(){return(od=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=a.asm.Pb).apply(null,arguments)};a._malloc=function(){return(a._malloc=a.asm.Qb).apply(null,arguments)};
83 | a._free=function(){return(a._free=a.asm.Rb).apply(null,arguments)};var ua=function(){return(ua=a.asm.Sb).apply(null,arguments)};a.___start_em_js=11660;a.___stop_em_js=11758;var la;ha=function b(){la||F();la||(ha=b)};if(a.preInit)for("function"==typeof a.preInit&&(a.preInit=[a.preInit]);0=r.size?(0>>=0;switch(c.BYTES_PER_ELEMENT){case 2:d>>>=1;break;case 4:d>>>=2;break;case 8:d>>>=3}for(var g=0;gb.byteLength)return a.INVALID_GEOMETRY_TYPE;switch(b[7]){case 0:return a.POINT_CLOUD;case 1:return a.TRIANGULAR_MESH;default:return a.INVALID_GEOMETRY_TYPE}};return n.ready}}();"object"===typeof exports&&"object"===typeof module?module.exports=DracoDecoderModule:"function"===typeof define&&define.amd?define([],function(){return DracoDecoderModule}):"object"===typeof exports&&(exports.DracoDecoderModule=DracoDecoderModule);
117 |
--------------------------------------------------------------------------------
/dist/uvGrid.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/dist/uvGrid.jpg
--------------------------------------------------------------------------------
/dist/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import reactHooks from 'eslint-plugin-react-hooks'
4 | import reactRefresh from 'eslint-plugin-react-refresh'
5 | import tseslint from 'typescript-eslint'
6 |
7 | export default tseslint.config(
8 | { ignores: ['dist'] },
9 | {
10 | extends: [js.configs.recommended, ...tseslint.configs.recommended],
11 | files: ['**/*.{ts,tsx}'],
12 | languageOptions: {
13 | ecmaVersion: 2020,
14 | globals: globals.browser,
15 | },
16 | plugins: {
17 | 'react-hooks': reactHooks,
18 | 'react-refresh': reactRefresh,
19 | },
20 | rules: {
21 | ...reactHooks.configs.recommended.rules,
22 | "@typescript-eslint/no-explicit-any": "off",
23 | "@typescript-eslint/no-unused-vars": "off",
24 | "@typescript-eslint/ban-ts-comment": "off",
25 | 'react-refresh/only-export-components': [
26 | 'warn',
27 | { allowConstantExport: true },
28 | ],
29 | },
30 | },
31 | )
32 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | ThreeJS Offscreen Canvas
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "offscreen-canvas",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc -b && vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "detect-gpu": "^5.0.57",
14 | "postprocessing": "^6.36.4",
15 | "react": "^18.3.1",
16 | "react-dom": "^18.3.1",
17 | "stats-gl": "^3.6.0",
18 | "three": "^0.170.0"
19 | },
20 | "devDependencies": {
21 | "@eslint/js": "^9.13.0",
22 | "@types/react": "^18.3.12",
23 | "@types/react-dom": "^18.3.1",
24 | "@types/three": "^0.170.0",
25 | "@vitejs/plugin-react": "^4.3.3",
26 | "eslint": "^9.13.0",
27 | "eslint-plugin-react-hooks": "^5.0.0",
28 | "eslint-plugin-react-refresh": "^0.4.14",
29 | "globals": "^15.11.0",
30 | "typescript": "~5.6.2",
31 | "typescript-eslint": "^8.11.0",
32 | "vite": "^5.4.10"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/public/Horse.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/public/Horse.glb
--------------------------------------------------------------------------------
/public/Idle.fbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/public/Idle.fbx
--------------------------------------------------------------------------------
/public/cube/nx.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/public/cube/nx.png
--------------------------------------------------------------------------------
/public/cube/ny.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/public/cube/ny.png
--------------------------------------------------------------------------------
/public/cube/nz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/public/cube/nz.png
--------------------------------------------------------------------------------
/public/cube/px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/public/cube/px.png
--------------------------------------------------------------------------------
/public/cube/py.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/public/cube/py.png
--------------------------------------------------------------------------------
/public/cube/pz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/public/cube/pz.png
--------------------------------------------------------------------------------
/public/libs/draco/README.md:
--------------------------------------------------------------------------------
1 | # Draco 3D Data Compression
2 |
3 | Draco is an open-source library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.
4 |
5 | [Website](https://google.github.io/draco/) | [GitHub](https://github.com/google/draco)
6 |
7 | ## Contents
8 |
9 | This folder contains three utilities:
10 |
11 | * `draco_decoder.js` — Emscripten-compiled decoder, compatible with any modern browser.
12 | * `draco_decoder.wasm` — WebAssembly decoder, compatible with newer browsers and devices.
13 | * `draco_wasm_wrapper.js` — JavaScript wrapper for the WASM decoder.
14 |
15 | Each file is provided in two variations:
16 |
17 | * **Default:** Latest stable builds, tracking the project's [master branch](https://github.com/google/draco).
18 | * **glTF:** Builds targeted by the [glTF mesh compression extension](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression), tracking the [corresponding Draco branch](https://github.com/google/draco/tree/gltf_2.0_draco_extension).
19 |
20 | Either variation may be used with `THREE.DRACOLoader`:
21 |
22 | ```js
23 | var dracoLoader = new THREE.DRACOLoader();
24 | dracoLoader.setDecoderPath('path/to/decoders/');
25 | dracoLoader.setDecoderConfig({type: 'js'}); // (Optional) Override detection of WASM support.
26 | ```
27 |
28 | Further [documentation on GitHub](https://github.com/google/draco/tree/master/javascript/example#static-loading-javascript-decoder).
29 |
30 | ## License
31 |
32 | [Apache License 2.0](https://github.com/google/draco/blob/master/LICENSE)
33 |
--------------------------------------------------------------------------------
/public/libs/draco/draco_decoder.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/public/libs/draco/draco_decoder.wasm
--------------------------------------------------------------------------------
/public/libs/draco/gltf/draco_decoder.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/public/libs/draco/gltf/draco_decoder.wasm
--------------------------------------------------------------------------------
/public/libs/draco/gltf/draco_wasm_wrapper.js:
--------------------------------------------------------------------------------
1 | var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(h){var n=0;return function(){return n>>0,$jscomp.propertyToPolyfillSymbol[l]=$jscomp.IS_SYMBOL_NATIVE?
7 | $jscomp.global.Symbol(l):$jscomp.POLYFILL_PREFIX+k+"$"+l),$jscomp.defineProperty(p,$jscomp.propertyToPolyfillSymbol[l],{configurable:!0,writable:!0,value:n})))};
8 | $jscomp.polyfill("Promise",function(h){function n(){this.batch_=null}function k(f){return f instanceof l?f:new l(function(q,u){q(f)})}if(h&&(!($jscomp.FORCE_POLYFILL_PROMISE||$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION&&"undefined"===typeof $jscomp.global.PromiseRejectionEvent)||!$jscomp.global.Promise||-1===$jscomp.global.Promise.toString().indexOf("[native code]")))return h;n.prototype.asyncExecute=function(f){if(null==this.batch_){this.batch_=[];var q=this;this.asyncExecuteFunction(function(){q.executeBatch_()})}this.batch_.push(f)};
9 | var p=$jscomp.global.setTimeout;n.prototype.asyncExecuteFunction=function(f){p(f,0)};n.prototype.executeBatch_=function(){for(;this.batch_&&this.batch_.length;){var f=this.batch_;this.batch_=[];for(var q=0;q=y}},"es6","es3");
19 | $jscomp.polyfill("Array.prototype.copyWithin",function(h){function n(k){k=Number(k);return Infinity===k||-Infinity===k?k:k|0}return h?h:function(k,p,l){var y=this.length;k=n(k);p=n(p);l=void 0===l?y:n(l);k=0>k?Math.max(y+k,0):Math.min(k,y);p=0>p?Math.max(y+p,0):Math.min(p,y);l=0>l?Math.max(y+l,0):Math.min(l,y);if(kp;)--l in this?this[--k]=this[l]:delete this[--k];return this}},"es6","es3");
20 | $jscomp.typedArrayCopyWithin=function(h){return h?h:Array.prototype.copyWithin};$jscomp.polyfill("Int8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8ClampedArray.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
21 | $jscomp.polyfill("Uint16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float64Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
22 | var DracoDecoderModule=function(){var h="undefined"!==typeof document&&document.currentScript?document.currentScript.src:void 0;"undefined"!==typeof __filename&&(h=h||__filename);return function(n){function k(e){return a.locateFile?a.locateFile(e,U):U+e}function p(e,b){if(e){var c=ia;var d=e+b;for(b=e;c[b]&&!(b>=d);)++b;if(16g?d+=String.fromCharCode(g):(g-=65536,d+=String.fromCharCode(55296|g>>10,56320|g&1023))}}else d+=String.fromCharCode(g)}c=d}}else c="";return c}function l(){var e=ja.buffer;a.HEAP8=W=new Int8Array(e);a.HEAP16=new Int16Array(e);a.HEAP32=ca=new Int32Array(e);a.HEAPU8=ia=new Uint8Array(e);a.HEAPU16=new Uint16Array(e);a.HEAPU32=Y=new Uint32Array(e);a.HEAPF32=new Float32Array(e);a.HEAPF64=new Float64Array(e)}function y(e){if(a.onAbort)a.onAbort(e);
24 | e="Aborted("+e+")";da(e);sa=!0;e=new WebAssembly.RuntimeError(e+". Build with -sASSERTIONS for more info.");ka(e);throw e;}function f(e){try{if(e==P&&ea)return new Uint8Array(ea);if(ma)return ma(e);throw"both async and sync fetching of the wasm failed";}catch(b){y(b)}}function q(){if(!ea&&(ta||fa)){if("function"==typeof fetch&&!P.startsWith("file://"))return fetch(P,{credentials:"same-origin"}).then(function(e){if(!e.ok)throw"failed to load wasm binary file at '"+P+"'";return e.arrayBuffer()}).catch(function(){return f(P)});
25 | if(na)return new Promise(function(e,b){na(P,function(c){e(new Uint8Array(c))},b)})}return Promise.resolve().then(function(){return f(P)})}function u(e){for(;0>2]=b};this.get_type=function(){return Y[this.ptr+4>>2]};this.set_destructor=function(b){Y[this.ptr+8>>2]=b};this.get_destructor=function(){return Y[this.ptr+8>>2]};this.set_refcount=function(b){ca[this.ptr>>2]=b};this.set_caught=function(b){W[this.ptr+
26 | 12>>0]=b?1:0};this.get_caught=function(){return 0!=W[this.ptr+12>>0]};this.set_rethrown=function(b){W[this.ptr+13>>0]=b?1:0};this.get_rethrown=function(){return 0!=W[this.ptr+13>>0]};this.init=function(b,c){this.set_adjusted_ptr(0);this.set_type(b);this.set_destructor(c);this.set_refcount(0);this.set_caught(!1);this.set_rethrown(!1)};this.add_ref=function(){ca[this.ptr>>2]+=1};this.release_ref=function(){var b=ca[this.ptr>>2];ca[this.ptr>>2]=b-1;return 1===b};this.set_adjusted_ptr=function(b){Y[this.ptr+
27 | 16>>2]=b};this.get_adjusted_ptr=function(){return Y[this.ptr+16>>2]};this.get_exception_ptr=function(){if(ua(this.get_type()))return Y[this.excPtr>>2];var b=this.get_adjusted_ptr();return 0!==b?b:this.excPtr}}function F(){function e(){if(!la&&(la=!0,a.calledRun=!0,!sa)){va=!0;u(oa);wa(a);if(a.onRuntimeInitialized)a.onRuntimeInitialized();if(a.postRun)for("function"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;)xa.unshift(a.postRun.shift());u(xa)}}if(!(0=d?b++:2047>=d?b+=2:55296<=d&&57343>=
29 | d?(b+=4,++c):b+=3}b=Array(b+1);c=0;d=b.length;if(0=t){var aa=e.charCodeAt(++g);t=65536+((t&1023)<<10)|aa&1023}if(127>=t){if(c>=d)break;b[c++]=t}else{if(2047>=t){if(c+1>=d)break;b[c++]=192|t>>6}else{if(65535>=t){if(c+2>=d)break;b[c++]=224|t>>12}else{if(c+3>=d)break;b[c++]=240|t>>18;b[c++]=128|t>>12&63}b[c++]=128|t>>6&63}b[c++]=128|t&63}}b[c]=0}e=r.alloc(b,W);r.copy(b,W,e);return e}return e}function Z(e){if("object"===
30 | typeof e){var b=r.alloc(e,W);r.copy(e,W,b);return b}return e}function X(){throw"cannot construct a VoidPtr, no constructor in IDL";}function S(){this.ptr=za();w(S)[this.ptr]=this}function Q(){this.ptr=Aa();w(Q)[this.ptr]=this}function V(){this.ptr=Ba();w(V)[this.ptr]=this}function x(){this.ptr=Ca();w(x)[this.ptr]=this}function D(){this.ptr=Da();w(D)[this.ptr]=this}function G(){this.ptr=Ea();w(G)[this.ptr]=this}function H(){this.ptr=Fa();w(H)[this.ptr]=this}function E(){this.ptr=Ga();w(E)[this.ptr]=
31 | this}function T(){this.ptr=Ha();w(T)[this.ptr]=this}function C(){throw"cannot construct a Status, no constructor in IDL";}function I(){this.ptr=Ia();w(I)[this.ptr]=this}function J(){this.ptr=Ja();w(J)[this.ptr]=this}function K(){this.ptr=Ka();w(K)[this.ptr]=this}function L(){this.ptr=La();w(L)[this.ptr]=this}function M(){this.ptr=Ma();w(M)[this.ptr]=this}function N(){this.ptr=Na();w(N)[this.ptr]=this}function O(){this.ptr=Oa();w(O)[this.ptr]=this}function z(){this.ptr=Pa();w(z)[this.ptr]=this}function m(){this.ptr=
32 | Qa();w(m)[this.ptr]=this}n=void 0===n?{}:n;var a="undefined"!=typeof n?n:{},wa,ka;a.ready=new Promise(function(e,b){wa=e;ka=b});var Ra=!1,Sa=!1;a.onRuntimeInitialized=function(){Ra=!0;if(Sa&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.onModuleParsed=function(){Sa=!0;if(Ra&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.isVersionSupported=function(e){if("string"!==typeof e)return!1;e=e.split(".");return 2>e.length||3=e[1]?!0:0!=e[0]||10<
33 | e[1]?!1:!0};var Ta=Object.assign({},a),ta="object"==typeof window,fa="function"==typeof importScripts,Ua="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,U="";if(Ua){var Va=require("fs"),pa=require("path");U=fa?pa.dirname(U)+"/":__dirname+"/";var Wa=function(e,b){e=e.startsWith("file://")?new URL(e):pa.normalize(e);return Va.readFileSync(e,b?void 0:"utf8")};var ma=function(e){e=Wa(e,!0);e.buffer||(e=new Uint8Array(e));return e};var na=function(e,
34 | b,c){e=e.startsWith("file://")?new URL(e):pa.normalize(e);Va.readFile(e,function(d,g){d?c(d):b(g.buffer)})};1>>=0;if(2147483648=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,e+100663296);var g=Math;d=Math.max(e,d);g=g.min.call(g,2147483648,d+(65536-d%65536)%65536);a:{d=ja.buffer;try{ja.grow(g-d.byteLength+65535>>>16);l();var t=1;break a}catch(aa){}t=void 0}if(t)return!0}return!1}};(function(){function e(g,t){a.asm=g.exports;ja=a.asm.e;l();oa.unshift(a.asm.f);ba--;a.monitorRunDependencies&&a.monitorRunDependencies(ba);0==ba&&(null!==qa&&(clearInterval(qa),qa=null),ha&&(g=ha,ha=null,g()))}function b(g){e(g.instance)}
38 | function c(g){return q().then(function(t){return WebAssembly.instantiate(t,d)}).then(function(t){return t}).then(g,function(t){da("failed to asynchronously prepare wasm: "+t);y(t)})}var d={a:qd};ba++;a.monitorRunDependencies&&a.monitorRunDependencies(ba);if(a.instantiateWasm)try{return a.instantiateWasm(d,e)}catch(g){da("Module.instantiateWasm callback failed with error: "+g),ka(g)}(function(){return ea||"function"!=typeof WebAssembly.instantiateStreaming||P.startsWith("data:application/octet-stream;base64,")||
39 | P.startsWith("file://")||Ua||"function"!=typeof fetch?c(b):fetch(P,{credentials:"same-origin"}).then(function(g){return WebAssembly.instantiateStreaming(g,d).then(b,function(t){da("wasm streaming compile failed: "+t);da("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(ka);return{}})();var Xa=a._emscripten_bind_VoidPtr___destroy___0=function(){return(Xa=a._emscripten_bind_VoidPtr___destroy___0=a.asm.h).apply(null,arguments)},za=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=
40 | function(){return(za=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=a.asm.i).apply(null,arguments)},Ya=a._emscripten_bind_DecoderBuffer_Init_2=function(){return(Ya=a._emscripten_bind_DecoderBuffer_Init_2=a.asm.j).apply(null,arguments)},Za=a._emscripten_bind_DecoderBuffer___destroy___0=function(){return(Za=a._emscripten_bind_DecoderBuffer___destroy___0=a.asm.k).apply(null,arguments)},Aa=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=function(){return(Aa=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=
41 | a.asm.l).apply(null,arguments)},$a=a._emscripten_bind_AttributeTransformData_transform_type_0=function(){return($a=a._emscripten_bind_AttributeTransformData_transform_type_0=a.asm.m).apply(null,arguments)},ab=a._emscripten_bind_AttributeTransformData___destroy___0=function(){return(ab=a._emscripten_bind_AttributeTransformData___destroy___0=a.asm.n).apply(null,arguments)},Ba=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=function(){return(Ba=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=
42 | a.asm.o).apply(null,arguments)},bb=a._emscripten_bind_GeometryAttribute___destroy___0=function(){return(bb=a._emscripten_bind_GeometryAttribute___destroy___0=a.asm.p).apply(null,arguments)},Ca=a._emscripten_bind_PointAttribute_PointAttribute_0=function(){return(Ca=a._emscripten_bind_PointAttribute_PointAttribute_0=a.asm.q).apply(null,arguments)},cb=a._emscripten_bind_PointAttribute_size_0=function(){return(cb=a._emscripten_bind_PointAttribute_size_0=a.asm.r).apply(null,arguments)},db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=
43 | function(){return(db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=a.asm.s).apply(null,arguments)},eb=a._emscripten_bind_PointAttribute_attribute_type_0=function(){return(eb=a._emscripten_bind_PointAttribute_attribute_type_0=a.asm.t).apply(null,arguments)},fb=a._emscripten_bind_PointAttribute_data_type_0=function(){return(fb=a._emscripten_bind_PointAttribute_data_type_0=a.asm.u).apply(null,arguments)},gb=a._emscripten_bind_PointAttribute_num_components_0=function(){return(gb=a._emscripten_bind_PointAttribute_num_components_0=
44 | a.asm.v).apply(null,arguments)},hb=a._emscripten_bind_PointAttribute_normalized_0=function(){return(hb=a._emscripten_bind_PointAttribute_normalized_0=a.asm.w).apply(null,arguments)},ib=a._emscripten_bind_PointAttribute_byte_stride_0=function(){return(ib=a._emscripten_bind_PointAttribute_byte_stride_0=a.asm.x).apply(null,arguments)},jb=a._emscripten_bind_PointAttribute_byte_offset_0=function(){return(jb=a._emscripten_bind_PointAttribute_byte_offset_0=a.asm.y).apply(null,arguments)},kb=a._emscripten_bind_PointAttribute_unique_id_0=
45 | function(){return(kb=a._emscripten_bind_PointAttribute_unique_id_0=a.asm.z).apply(null,arguments)},lb=a._emscripten_bind_PointAttribute___destroy___0=function(){return(lb=a._emscripten_bind_PointAttribute___destroy___0=a.asm.A).apply(null,arguments)},Da=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=function(){return(Da=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=a.asm.B).apply(null,arguments)},mb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=
46 | function(){return(mb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=a.asm.C).apply(null,arguments)},nb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=function(){return(nb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=a.asm.D).apply(null,arguments)},ob=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=function(){return(ob=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=a.asm.E).apply(null,arguments)},pb=
47 | a._emscripten_bind_AttributeQuantizationTransform_range_0=function(){return(pb=a._emscripten_bind_AttributeQuantizationTransform_range_0=a.asm.F).apply(null,arguments)},qb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=function(){return(qb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=a.asm.G).apply(null,arguments)},Ea=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=function(){return(Ea=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=
48 | a.asm.H).apply(null,arguments)},rb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=function(){return(rb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=a.asm.I).apply(null,arguments)},sb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=function(){return(sb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=a.asm.J).apply(null,arguments)},tb=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=function(){return(tb=
49 | a._emscripten_bind_AttributeOctahedronTransform___destroy___0=a.asm.K).apply(null,arguments)},Fa=a._emscripten_bind_PointCloud_PointCloud_0=function(){return(Fa=a._emscripten_bind_PointCloud_PointCloud_0=a.asm.L).apply(null,arguments)},ub=a._emscripten_bind_PointCloud_num_attributes_0=function(){return(ub=a._emscripten_bind_PointCloud_num_attributes_0=a.asm.M).apply(null,arguments)},vb=a._emscripten_bind_PointCloud_num_points_0=function(){return(vb=a._emscripten_bind_PointCloud_num_points_0=a.asm.N).apply(null,
50 | arguments)},wb=a._emscripten_bind_PointCloud___destroy___0=function(){return(wb=a._emscripten_bind_PointCloud___destroy___0=a.asm.O).apply(null,arguments)},Ga=a._emscripten_bind_Mesh_Mesh_0=function(){return(Ga=a._emscripten_bind_Mesh_Mesh_0=a.asm.P).apply(null,arguments)},xb=a._emscripten_bind_Mesh_num_faces_0=function(){return(xb=a._emscripten_bind_Mesh_num_faces_0=a.asm.Q).apply(null,arguments)},yb=a._emscripten_bind_Mesh_num_attributes_0=function(){return(yb=a._emscripten_bind_Mesh_num_attributes_0=
51 | a.asm.R).apply(null,arguments)},zb=a._emscripten_bind_Mesh_num_points_0=function(){return(zb=a._emscripten_bind_Mesh_num_points_0=a.asm.S).apply(null,arguments)},Ab=a._emscripten_bind_Mesh___destroy___0=function(){return(Ab=a._emscripten_bind_Mesh___destroy___0=a.asm.T).apply(null,arguments)},Ha=a._emscripten_bind_Metadata_Metadata_0=function(){return(Ha=a._emscripten_bind_Metadata_Metadata_0=a.asm.U).apply(null,arguments)},Bb=a._emscripten_bind_Metadata___destroy___0=function(){return(Bb=a._emscripten_bind_Metadata___destroy___0=
52 | a.asm.V).apply(null,arguments)},Cb=a._emscripten_bind_Status_code_0=function(){return(Cb=a._emscripten_bind_Status_code_0=a.asm.W).apply(null,arguments)},Db=a._emscripten_bind_Status_ok_0=function(){return(Db=a._emscripten_bind_Status_ok_0=a.asm.X).apply(null,arguments)},Eb=a._emscripten_bind_Status_error_msg_0=function(){return(Eb=a._emscripten_bind_Status_error_msg_0=a.asm.Y).apply(null,arguments)},Fb=a._emscripten_bind_Status___destroy___0=function(){return(Fb=a._emscripten_bind_Status___destroy___0=
53 | a.asm.Z).apply(null,arguments)},Ia=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=function(){return(Ia=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=a.asm._).apply(null,arguments)},Gb=a._emscripten_bind_DracoFloat32Array_GetValue_1=function(){return(Gb=a._emscripten_bind_DracoFloat32Array_GetValue_1=a.asm.$).apply(null,arguments)},Hb=a._emscripten_bind_DracoFloat32Array_size_0=function(){return(Hb=a._emscripten_bind_DracoFloat32Array_size_0=a.asm.aa).apply(null,arguments)},Ib=
54 | a._emscripten_bind_DracoFloat32Array___destroy___0=function(){return(Ib=a._emscripten_bind_DracoFloat32Array___destroy___0=a.asm.ba).apply(null,arguments)},Ja=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=function(){return(Ja=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=a.asm.ca).apply(null,arguments)},Jb=a._emscripten_bind_DracoInt8Array_GetValue_1=function(){return(Jb=a._emscripten_bind_DracoInt8Array_GetValue_1=a.asm.da).apply(null,arguments)},Kb=a._emscripten_bind_DracoInt8Array_size_0=
55 | function(){return(Kb=a._emscripten_bind_DracoInt8Array_size_0=a.asm.ea).apply(null,arguments)},Lb=a._emscripten_bind_DracoInt8Array___destroy___0=function(){return(Lb=a._emscripten_bind_DracoInt8Array___destroy___0=a.asm.fa).apply(null,arguments)},Ka=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=function(){return(Ka=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=a.asm.ga).apply(null,arguments)},Mb=a._emscripten_bind_DracoUInt8Array_GetValue_1=function(){return(Mb=a._emscripten_bind_DracoUInt8Array_GetValue_1=
56 | a.asm.ha).apply(null,arguments)},Nb=a._emscripten_bind_DracoUInt8Array_size_0=function(){return(Nb=a._emscripten_bind_DracoUInt8Array_size_0=a.asm.ia).apply(null,arguments)},Ob=a._emscripten_bind_DracoUInt8Array___destroy___0=function(){return(Ob=a._emscripten_bind_DracoUInt8Array___destroy___0=a.asm.ja).apply(null,arguments)},La=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=function(){return(La=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=a.asm.ka).apply(null,arguments)},Pb=a._emscripten_bind_DracoInt16Array_GetValue_1=
57 | function(){return(Pb=a._emscripten_bind_DracoInt16Array_GetValue_1=a.asm.la).apply(null,arguments)},Qb=a._emscripten_bind_DracoInt16Array_size_0=function(){return(Qb=a._emscripten_bind_DracoInt16Array_size_0=a.asm.ma).apply(null,arguments)},Rb=a._emscripten_bind_DracoInt16Array___destroy___0=function(){return(Rb=a._emscripten_bind_DracoInt16Array___destroy___0=a.asm.na).apply(null,arguments)},Ma=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=function(){return(Ma=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=
58 | a.asm.oa).apply(null,arguments)},Sb=a._emscripten_bind_DracoUInt16Array_GetValue_1=function(){return(Sb=a._emscripten_bind_DracoUInt16Array_GetValue_1=a.asm.pa).apply(null,arguments)},Tb=a._emscripten_bind_DracoUInt16Array_size_0=function(){return(Tb=a._emscripten_bind_DracoUInt16Array_size_0=a.asm.qa).apply(null,arguments)},Ub=a._emscripten_bind_DracoUInt16Array___destroy___0=function(){return(Ub=a._emscripten_bind_DracoUInt16Array___destroy___0=a.asm.ra).apply(null,arguments)},Na=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=
59 | function(){return(Na=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=a.asm.sa).apply(null,arguments)},Vb=a._emscripten_bind_DracoInt32Array_GetValue_1=function(){return(Vb=a._emscripten_bind_DracoInt32Array_GetValue_1=a.asm.ta).apply(null,arguments)},Wb=a._emscripten_bind_DracoInt32Array_size_0=function(){return(Wb=a._emscripten_bind_DracoInt32Array_size_0=a.asm.ua).apply(null,arguments)},Xb=a._emscripten_bind_DracoInt32Array___destroy___0=function(){return(Xb=a._emscripten_bind_DracoInt32Array___destroy___0=
60 | a.asm.va).apply(null,arguments)},Oa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=function(){return(Oa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=a.asm.wa).apply(null,arguments)},Yb=a._emscripten_bind_DracoUInt32Array_GetValue_1=function(){return(Yb=a._emscripten_bind_DracoUInt32Array_GetValue_1=a.asm.xa).apply(null,arguments)},Zb=a._emscripten_bind_DracoUInt32Array_size_0=function(){return(Zb=a._emscripten_bind_DracoUInt32Array_size_0=a.asm.ya).apply(null,arguments)},$b=a._emscripten_bind_DracoUInt32Array___destroy___0=
61 | function(){return($b=a._emscripten_bind_DracoUInt32Array___destroy___0=a.asm.za).apply(null,arguments)},Pa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=function(){return(Pa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=a.asm.Aa).apply(null,arguments)},ac=a._emscripten_bind_MetadataQuerier_HasEntry_2=function(){return(ac=a._emscripten_bind_MetadataQuerier_HasEntry_2=a.asm.Ba).apply(null,arguments)},bc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=function(){return(bc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=
62 | a.asm.Ca).apply(null,arguments)},cc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=function(){return(cc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=a.asm.Da).apply(null,arguments)},dc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=function(){return(dc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=a.asm.Ea).apply(null,arguments)},ec=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=function(){return(ec=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=a.asm.Fa).apply(null,
63 | arguments)},fc=a._emscripten_bind_MetadataQuerier_NumEntries_1=function(){return(fc=a._emscripten_bind_MetadataQuerier_NumEntries_1=a.asm.Ga).apply(null,arguments)},gc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=function(){return(gc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=a.asm.Ha).apply(null,arguments)},hc=a._emscripten_bind_MetadataQuerier___destroy___0=function(){return(hc=a._emscripten_bind_MetadataQuerier___destroy___0=a.asm.Ia).apply(null,arguments)},Qa=a._emscripten_bind_Decoder_Decoder_0=
64 | function(){return(Qa=a._emscripten_bind_Decoder_Decoder_0=a.asm.Ja).apply(null,arguments)},ic=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=function(){return(ic=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=a.asm.Ka).apply(null,arguments)},jc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=function(){return(jc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=a.asm.La).apply(null,arguments)},kc=a._emscripten_bind_Decoder_GetAttributeId_2=function(){return(kc=a._emscripten_bind_Decoder_GetAttributeId_2=
65 | a.asm.Ma).apply(null,arguments)},lc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=function(){return(lc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=a.asm.Na).apply(null,arguments)},mc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=function(){return(mc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=a.asm.Oa).apply(null,arguments)},nc=a._emscripten_bind_Decoder_GetAttribute_2=function(){return(nc=a._emscripten_bind_Decoder_GetAttribute_2=a.asm.Pa).apply(null,arguments)},
66 | oc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=function(){return(oc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=a.asm.Qa).apply(null,arguments)},pc=a._emscripten_bind_Decoder_GetMetadata_1=function(){return(pc=a._emscripten_bind_Decoder_GetMetadata_1=a.asm.Ra).apply(null,arguments)},qc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=function(){return(qc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=a.asm.Sa).apply(null,arguments)},rc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=
67 | function(){return(rc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=a.asm.Ta).apply(null,arguments)},sc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=function(){return(sc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=a.asm.Ua).apply(null,arguments)},tc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=function(){return(tc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=a.asm.Va).apply(null,arguments)},uc=a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=function(){return(uc=
68 | a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=a.asm.Wa).apply(null,arguments)},vc=a._emscripten_bind_Decoder_GetAttributeFloat_3=function(){return(vc=a._emscripten_bind_Decoder_GetAttributeFloat_3=a.asm.Xa).apply(null,arguments)},wc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=function(){return(wc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=a.asm.Ya).apply(null,arguments)},xc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=function(){return(xc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=
69 | a.asm.Za).apply(null,arguments)},yc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=function(){return(yc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=a.asm._a).apply(null,arguments)},zc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=function(){return(zc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=a.asm.$a).apply(null,arguments)},Ac=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=function(){return(Ac=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=
70 | a.asm.ab).apply(null,arguments)},Bc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=function(){return(Bc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=a.asm.bb).apply(null,arguments)},Cc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=function(){return(Cc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=a.asm.cb).apply(null,arguments)},Dc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=function(){return(Dc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=
71 | a.asm.db).apply(null,arguments)},Ec=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=function(){return(Ec=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=a.asm.eb).apply(null,arguments)},Fc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=function(){return(Fc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=a.asm.fb).apply(null,arguments)},Gc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=function(){return(Gc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=
72 | a.asm.gb).apply(null,arguments)},Hc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=function(){return(Hc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=a.asm.hb).apply(null,arguments)},Ic=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=function(){return(Ic=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=a.asm.ib).apply(null,arguments)},Jc=a._emscripten_bind_Decoder___destroy___0=function(){return(Jc=a._emscripten_bind_Decoder___destroy___0=a.asm.jb).apply(null,arguments)},Kc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=
73 | function(){return(Kc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=a.asm.kb).apply(null,arguments)},Lc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=function(){return(Lc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=a.asm.lb).apply(null,arguments)},Mc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=function(){return(Mc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=
74 | a.asm.mb).apply(null,arguments)},Nc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=function(){return(Nc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=a.asm.nb).apply(null,arguments)},Oc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=function(){return(Oc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=a.asm.ob).apply(null,arguments)},Pc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=function(){return(Pc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=
75 | a.asm.pb).apply(null,arguments)},Qc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=function(){return(Qc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=a.asm.qb).apply(null,arguments)},Rc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=function(){return(Rc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=a.asm.rb).apply(null,arguments)},Sc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=function(){return(Sc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=
76 | a.asm.sb).apply(null,arguments)},Tc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=function(){return(Tc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=a.asm.tb).apply(null,arguments)},Uc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=function(){return(Uc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=a.asm.ub).apply(null,arguments)},Vc=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=function(){return(Vc=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=
77 | a.asm.vb).apply(null,arguments)},Wc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=function(){return(Wc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=a.asm.wb).apply(null,arguments)},Xc=a._emscripten_enum_draco_DataType_DT_INVALID=function(){return(Xc=a._emscripten_enum_draco_DataType_DT_INVALID=a.asm.xb).apply(null,arguments)},Yc=a._emscripten_enum_draco_DataType_DT_INT8=function(){return(Yc=a._emscripten_enum_draco_DataType_DT_INT8=a.asm.yb).apply(null,arguments)},Zc=
78 | a._emscripten_enum_draco_DataType_DT_UINT8=function(){return(Zc=a._emscripten_enum_draco_DataType_DT_UINT8=a.asm.zb).apply(null,arguments)},$c=a._emscripten_enum_draco_DataType_DT_INT16=function(){return($c=a._emscripten_enum_draco_DataType_DT_INT16=a.asm.Ab).apply(null,arguments)},ad=a._emscripten_enum_draco_DataType_DT_UINT16=function(){return(ad=a._emscripten_enum_draco_DataType_DT_UINT16=a.asm.Bb).apply(null,arguments)},bd=a._emscripten_enum_draco_DataType_DT_INT32=function(){return(bd=a._emscripten_enum_draco_DataType_DT_INT32=
79 | a.asm.Cb).apply(null,arguments)},cd=a._emscripten_enum_draco_DataType_DT_UINT32=function(){return(cd=a._emscripten_enum_draco_DataType_DT_UINT32=a.asm.Db).apply(null,arguments)},dd=a._emscripten_enum_draco_DataType_DT_INT64=function(){return(dd=a._emscripten_enum_draco_DataType_DT_INT64=a.asm.Eb).apply(null,arguments)},ed=a._emscripten_enum_draco_DataType_DT_UINT64=function(){return(ed=a._emscripten_enum_draco_DataType_DT_UINT64=a.asm.Fb).apply(null,arguments)},fd=a._emscripten_enum_draco_DataType_DT_FLOAT32=
80 | function(){return(fd=a._emscripten_enum_draco_DataType_DT_FLOAT32=a.asm.Gb).apply(null,arguments)},gd=a._emscripten_enum_draco_DataType_DT_FLOAT64=function(){return(gd=a._emscripten_enum_draco_DataType_DT_FLOAT64=a.asm.Hb).apply(null,arguments)},hd=a._emscripten_enum_draco_DataType_DT_BOOL=function(){return(hd=a._emscripten_enum_draco_DataType_DT_BOOL=a.asm.Ib).apply(null,arguments)},id=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=function(){return(id=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=
81 | a.asm.Jb).apply(null,arguments)},jd=a._emscripten_enum_draco_StatusCode_OK=function(){return(jd=a._emscripten_enum_draco_StatusCode_OK=a.asm.Kb).apply(null,arguments)},kd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=function(){return(kd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=a.asm.Lb).apply(null,arguments)},ld=a._emscripten_enum_draco_StatusCode_IO_ERROR=function(){return(ld=a._emscripten_enum_draco_StatusCode_IO_ERROR=a.asm.Mb).apply(null,arguments)},md=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=
82 | function(){return(md=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=a.asm.Nb).apply(null,arguments)},nd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=function(){return(nd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=a.asm.Ob).apply(null,arguments)},od=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=function(){return(od=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=a.asm.Pb).apply(null,arguments)};a._malloc=function(){return(a._malloc=a.asm.Qb).apply(null,arguments)};
83 | a._free=function(){return(a._free=a.asm.Rb).apply(null,arguments)};var ua=function(){return(ua=a.asm.Sb).apply(null,arguments)};a.___start_em_js=11660;a.___stop_em_js=11758;var la;ha=function b(){la||F();la||(ha=b)};if(a.preInit)for("function"==typeof a.preInit&&(a.preInit=[a.preInit]);0=r.size?(0>>=0;switch(c.BYTES_PER_ELEMENT){case 2:d>>>=1;break;case 4:d>>>=2;break;case 8:d>>>=3}for(var g=0;gb.byteLength)return a.INVALID_GEOMETRY_TYPE;switch(b[7]){case 0:return a.POINT_CLOUD;case 1:return a.TRIANGULAR_MESH;default:return a.INVALID_GEOMETRY_TYPE}};return n.ready}}();"object"===typeof exports&&"object"===typeof module?module.exports=DracoDecoderModule:"function"===typeof define&&define.amd?define([],function(){return DracoDecoderModule}):"object"===typeof exports&&(exports.DracoDecoderModule=DracoDecoderModule);
117 |
--------------------------------------------------------------------------------
/public/uvGrid.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomorrowevening/three-offscreen/785a96a2967e59f484efd97dea4e2cdd08468d2d/public/uvGrid.jpg
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Wrapper.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from 'react'
2 | import { getGPUTier, TierResult } from 'detect-gpu'
3 | import Workers from './webworker/workers'
4 | import CanvasComponent from './canvas/CanvasComponent'
5 | import Loader from './components/Loader'
6 | import Settings from './global/settings'
7 | import { QualityType } from './types'
8 |
9 | export default function Wrapper() {
10 | const canvasRef = useRef(null)
11 | const [ready, setReady] = useState(false)
12 |
13 | useEffect(() => {
14 | getGPUTier().then((gpuTier: TierResult) => {
15 | // Detect Support
16 | let supportOffScreenWebGL = false
17 | if (canvasRef.current !== null) {
18 | supportOffScreenWebGL = 'transferControlToOffscreen' in canvasRef.current
19 |
20 | // If it's Safari, then check the version because Safari < 17 doesn't support OffscreenCanvas with a WebGL context.
21 | const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
22 | if (isSafari) {
23 | const versionMatch = navigator.userAgent.match( /version\/(\d+)/i )
24 | const safariVersion = versionMatch ? parseInt( versionMatch[ 1 ] ) : 0
25 | supportOffScreenWebGL = safariVersion >= 17
26 | }
27 |
28 | // Override setting
29 | if (location.hash.search('regular') > -1) supportOffScreenWebGL = false
30 | }
31 |
32 | // Update Settings
33 | Settings.dpr = devicePixelRatio
34 | if (gpuTier.fps !== undefined) Settings.fps = Math.min(gpuTier.fps, 60) // cap FPS to 60
35 | if (gpuTier.isMobile !== undefined) Settings.mobile = gpuTier.isMobile
36 | if (gpuTier.tier === 3) Settings.quality = QualityType.High
37 | else if (gpuTier.tier === 2) Settings.quality = QualityType.Medium
38 | Settings.supportOffScreenCanvas = supportOffScreenWebGL
39 | Settings.width = innerWidth
40 | Settings.height = innerHeight
41 |
42 | Workers.init()
43 | setReady(true)
44 | })
45 | return () => {
46 | Workers.dispose()
47 | }
48 | }, [])
49 |
50 | return (
51 | <>
52 |
53 | {ready && canvasRef.current !== null && (
54 | <>
55 |
56 |
57 | >
58 | )}
59 | >
60 | )
61 | }
62 |
--------------------------------------------------------------------------------
/src/canvas/CanvasComponent.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from 'react'
2 | import Stats from 'stats-gl'
3 | import OffscreenWay from './OffscreenWay'
4 | import StandardWay from './StandardWay'
5 | import Settings from '../global/settings'
6 |
7 | let interval: number | null = null
8 |
9 | type CanvasComponentProps = {
10 | canvas: HTMLCanvasElement
11 | }
12 |
13 | export default function CanvasComponent(props: CanvasComponentProps) {
14 | // Refs
15 | const buttonRef = useRef(null)
16 | const resultRef = useRef(null)
17 |
18 | function jank() {
19 | let number = 0;
20 | for ( let i = 0; i < 10000000; i ++ ) {
21 | number += Math.random();
22 | }
23 |
24 | if (resultRef.current) {
25 | resultRef.current.innerHTML = number.toString()
26 | }
27 | }
28 |
29 | function clickButton() {
30 | if ( interval === null ) {
31 | interval = setInterval( jank, 1000 / 60 )
32 | buttonRef.current!.innerHTML = 'STOP JANK'
33 | } else {
34 | clearInterval( interval )
35 | interval = null
36 | buttonRef.current!.innerHTML = 'START JANK'
37 | resultRef.current!.innerHTML = ''
38 | }
39 | }
40 |
41 | useEffect(() => {
42 | const stats = new Stats({})
43 | document.body.appendChild(stats.dom)
44 |
45 | let rafID = -1
46 | const onUpdate = () => {
47 | stats.update()
48 | rafID = requestAnimationFrame(onUpdate)
49 | }
50 | onUpdate()
51 |
52 | return () => {
53 | cancelAnimationFrame(rafID)
54 | rafID = -1
55 | }
56 | }, [])
57 |
58 | return (
59 | <>
60 | 0
61 | Jank
62 | {Settings.supportOffScreenCanvas ? (
63 |
64 | ) : (
65 |
66 | )}
67 | >
68 | )
69 | }
70 |
--------------------------------------------------------------------------------
/src/canvas/OffscreenWay.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { MethodProps } from '../types'
3 | import Settings from '../global/settings';
4 | import Workers from '../webworker/workers'
5 | import { ElementProxy, eventHandlers } from '../webworker/EventHandling';
6 |
7 | // Component
8 |
9 | export default function OffscreenWay(props: MethodProps) {
10 | useEffect(() => {
11 | console.log('Offscreen Canvas')
12 |
13 | props.canvas.focus()
14 |
15 | if (Workers.canvas) {
16 | const proxy = new ElementProxy(props.canvas, Workers.canvas, eventHandlers)
17 |
18 | // App
19 | const offscreenCanvas = props.canvas.transferControlToOffscreen()
20 | const message = {
21 | ...{
22 | type: 'init',
23 | canvas: offscreenCanvas,
24 | canvasId: proxy.id,
25 | },
26 | ...Settings,
27 | }
28 | Workers.canvas.postMessage(message, [offscreenCanvas])
29 | }
30 | }, [props])
31 |
32 | return null
33 | }
34 |
--------------------------------------------------------------------------------
/src/canvas/StandardWay.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import ThreeApp from '../webgl/ThreeApp'
3 | import { MethodProps } from '../types'
4 | import { dispatcher, Events } from '../global/constants'
5 | import Settings from '../global/settings'
6 |
7 | export default function StandardWay(props: MethodProps) {
8 | useEffect(() => {
9 | console.log('Regular Canvas')
10 |
11 | // App
12 | const newApp = new ThreeApp(props.canvas, props.canvas, Settings)
13 | newApp.play()
14 |
15 | function onLoad(event: any) {
16 | dispatcher.removeEventListener(Events.LoadComplete, onLoad)
17 | newApp.onLoad(event.value)
18 | }
19 | dispatcher.addEventListener(Events.LoadComplete, onLoad)
20 |
21 | return () => {
22 | dispatcher.removeEventListener(Events.LoadComplete, onLoad)
23 | newApp.dispose()
24 | }
25 | }, [props])
26 |
27 | return null
28 | }
--------------------------------------------------------------------------------
/src/components/Loader.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from 'react';
2 | import { assetList, dispatcher, Events } from '../global/constants';
3 |
4 | export default function Loader() {
5 | const pRef = useRef(null)
6 | const [loaded, setLoaded] = useState(false)
7 |
8 | useEffect(() => {
9 | function onLoad() {
10 | dispatcher.removeEventListener(Events.LoadComplete, onLoad)
11 | setLoaded(true)
12 | }
13 |
14 | dispatcher.addEventListener(Events.LoadComplete, onLoad)
15 | dispatcher.dispatchEvent({ type: Events.LoadStart, value: assetList })
16 | return () => {
17 | dispatcher.removeEventListener(Events.LoadComplete, onLoad)
18 | }
19 | }, [])
20 |
21 | return (
22 | <>
23 | {loaded ? null : 0%
}
24 | >
25 | )
26 | }
--------------------------------------------------------------------------------
/src/global/constants.ts:
--------------------------------------------------------------------------------
1 | import { EventDispatcher } from 'three'
2 | import { File } from '../types'
3 |
4 | export enum Events {
5 | LoadStart = 'LoadStart',
6 | LoadComplete = 'LoadComplete',
7 | }
8 |
9 | export type WebGLEvent = {
10 | [key in Events]: { value?: unknown }
11 | }
12 |
13 | export const dispatcher = new EventDispatcher()
14 |
15 | export const assetList: File[] = [
16 | {
17 | type: 'image',
18 | name: 'uvGrid',
19 | file: '/uvGrid.jpg',
20 | },
21 | {
22 | type: 'image',
23 | name: 'nx',
24 | file: '/cube/nx.png',
25 | },
26 | {
27 | type: 'image',
28 | name: 'ny',
29 | file: '/cube/ny.png',
30 | },
31 | {
32 | type: 'image',
33 | name: 'nz',
34 | file: '/cube/nz.png',
35 | },
36 | {
37 | type: 'image',
38 | name: 'px',
39 | file: '/cube/px.png',
40 | },
41 | {
42 | type: 'image',
43 | name: 'py',
44 | file: '/cube/py.png',
45 | },
46 | {
47 | type: 'image',
48 | name: 'pz',
49 | file: '/cube/pz.png',
50 | },
51 | {
52 | type: 'gltf',
53 | name: 'Horse',
54 | file: '/Horse.glb',
55 | },
56 | {
57 | type: 'fbx',
58 | name: 'Idle',
59 | file: '/Idle.fbx',
60 | },
61 | ]
62 |
--------------------------------------------------------------------------------
/src/global/settings.ts:
--------------------------------------------------------------------------------
1 | import { AppSettings, QualityType } from '../types';
2 |
3 | const Settings: AppSettings = {
4 | dpr: 1,
5 | fps: 30,
6 | width: 100,
7 | height: 100,
8 | mobile: false,
9 | supportOffScreenCanvas: false,
10 | quality: QualityType.Low,
11 | }
12 | export default Settings
13 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
4 | font-weight: 400;
5 |
6 | color-scheme: light dark;
7 | color: rgba(255, 255, 255, 0.87);
8 | background-color: #242424;
9 |
10 | font-synthesis: none;
11 | text-rendering: optimizeLegibility;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | }
15 |
16 | a {
17 | font-weight: 500;
18 | color: #646cff;
19 | text-decoration: inherit;
20 | }
21 | a:hover {
22 | color: #535bf2;
23 | }
24 |
25 | html, body {
26 | margin: 0;
27 | padding: 0;
28 | min-width: 100%;
29 | min-height: 100%;
30 | width: 100%;
31 | height: 100%;
32 | overflow: hidden;
33 | }
34 |
35 | #root {
36 | position: absolute;
37 | left: 0;
38 | right: 0;
39 | top: 0;
40 | bottom: 0;
41 | }
42 |
43 | canvas {
44 | max-width: 100%;
45 | max-height: 100%;
46 | }
47 |
48 | h1 {
49 | font-size: 3.2em;
50 | line-height: 1.1;
51 | }
52 |
53 | button {
54 | border-radius: 8px;
55 | border: 1px solid transparent;
56 | padding: 0.6em 1.2em;
57 | font-size: 1em;
58 | font-weight: 500;
59 | font-family: inherit;
60 | background-color: #1a1a1a;
61 | cursor: pointer;
62 | position: absolute;
63 | left: 50%;
64 | top: 0;
65 | transform: translateX(-50%);
66 | }
67 | button:hover {
68 | border-color: #646cff;
69 | }
70 | button:focus,
71 | button:focus-visible {
72 | outline: 4px auto -webkit-focus-ring-color;
73 | }
74 |
75 | p {
76 | color: white;
77 | position: absolute;
78 | left: 50%;
79 | top: 50px;
80 | transform: translateX(-50%);
81 | }
82 |
83 | @media (prefers-color-scheme: light) {
84 | :root {
85 | color: #213547;
86 | background-color: #ffffff;
87 | }
88 | a:hover {
89 | color: #747bff;
90 | }
91 | button {
92 | background-color: #f9f9f9;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main.tsx:
--------------------------------------------------------------------------------
1 | import { StrictMode } from 'react'
2 | import { createRoot } from 'react-dom/client'
3 | import './index.css'
4 | import Wrapper from './Wrapper'
5 |
6 | export const IS_DEV = import.meta.env.MODE === 'development'
7 |
8 | createRoot(document.getElementById('root')!).render(
9 | <>
10 | {IS_DEV ? (
11 | <>
12 |
13 | >
14 | ) : (
15 |
16 |
17 |
18 | )}
19 | >
20 | )
21 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | import { AnimationClip, Object3DJSON } from 'three'
2 |
3 | export type MethodProps = {
4 | canvas: HTMLCanvasElement
5 | }
6 |
7 | export type FileType = 'audio' | 'blob' | 'buffer' | 'fbx' | 'gltf' | 'image' | 'json' | 'video'
8 |
9 | export type File = {
10 | name: string
11 | file: string
12 | type: FileType
13 | }
14 |
15 | export type Assets = {
16 | audio: Map
17 | blob: Map
18 | buffer: Map
19 | image: Map
20 | json: Map
21 | model: Map
22 | video: Map
23 | }
24 |
25 | export type ModelInfo = {
26 | animations: AnimationClip[]
27 | cameras?: Object3DJSON[]
28 | scene: Object3DJSON
29 | }
30 |
31 | export enum QualityType {
32 | 'High',
33 | 'Medium',
34 | 'Low',
35 | }
36 |
37 | export type AppSettings = {
38 | dpr: number
39 | fps: number
40 | width: number
41 | height: number
42 | mobile: boolean
43 | supportOffScreenCanvas: boolean
44 | quality: QualityType
45 | }
46 |
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/webgl/ThreeApp.ts:
--------------------------------------------------------------------------------
1 | import { Clock, WebGLRenderer } from 'three'
2 | import ThreeScene from './ThreeScene'
3 | import { AppSettings, Assets } from '../types'
4 | import { dispose } from './threeUtils'
5 |
6 | export default class ThreeApp {
7 | canvas: HTMLCanvasElement
8 | renderer: WebGLRenderer
9 | scene: ThreeScene
10 | settings: AppSettings
11 |
12 | private inputElement: any
13 | private raf = -1
14 | private clock = new Clock()
15 |
16 | constructor(canvas: HTMLCanvasElement, inputElement: any, settings: AppSettings) {
17 | console.log('Settings:', settings)
18 | this.canvas = canvas
19 | this.inputElement = inputElement
20 | this.settings = settings
21 |
22 | this.renderer = new WebGLRenderer({ canvas })
23 | this.renderer.setPixelRatio(settings.dpr)
24 |
25 | // Scene
26 |
27 | this.scene = new ThreeScene(this.renderer, inputElement, settings.width, settings.height)
28 |
29 | // Begin App
30 |
31 | this.clock.start()
32 |
33 | inputElement.addEventListener('resize', this.onResize)
34 | this.resize(settings.width, settings.height)
35 | }
36 |
37 | dispose() {
38 | this.pause()
39 | this.inputElement.removeEventListener('resize', this.onResize)
40 | dispose(this.scene)
41 | this.renderer.dispose()
42 | }
43 |
44 | async onLoad(assets: Assets) {
45 | return this.scene.onLoad(assets);
46 | }
47 |
48 | play() {
49 | this.onUpdate()
50 | }
51 |
52 | pause() {
53 | cancelAnimationFrame(this.raf)
54 | this.raf = -1
55 | }
56 |
57 | update() {
58 | const delta = this.clock.getDelta()
59 | this.scene.update(delta)
60 | }
61 |
62 | draw() {
63 | this.scene.draw()
64 | }
65 |
66 | onUpdate = () => {
67 | this.update()
68 | this.draw()
69 | this.raf = requestAnimationFrame(this.onUpdate)
70 | }
71 |
72 | resize(width: number, height: number) {
73 | this.scene.resize(width, height, !this.settings.supportOffScreenCanvas);
74 |
75 | if (this.settings.supportOffScreenCanvas) {
76 | this.inputElement.clientWidth = width
77 | this.inputElement.clientHeight = height
78 | this.inputElement.width = width
79 | this.inputElement.height = height
80 | }
81 | }
82 |
83 | // Handlers
84 |
85 | private onResize = (evt: any) => {
86 | const { width, height } = evt
87 | this.resize(width, height)
88 | }
89 | }
--------------------------------------------------------------------------------
/src/webgl/ThreeScene.ts:
--------------------------------------------------------------------------------
1 | import {
2 | AmbientLight,
3 | AnimationMixer,
4 | BoxGeometry,
5 | CubeReflectionMapping,
6 | CubeTexture,
7 | DirectionalLight,
8 | DoubleSide,
9 | HalfFloatType,
10 | Mesh,
11 | MeshBasicMaterial,
12 | MeshStandardMaterial,
13 | PerspectiveCamera,
14 | PlaneGeometry,
15 | Scene,
16 | Texture,
17 | WebGLRenderer,
18 | } from 'three'
19 | import { OrbitControls } from 'three/examples/jsm/Addons.js'
20 | import { EffectComposer, EffectPass, FXAAEffect, RenderPass, VignetteEffect } from 'postprocessing'
21 | import { createModel } from './threeUtils'
22 | import { Assets } from '../types'
23 |
24 | export default class ThreeScene extends Scene {
25 | camera: PerspectiveCamera
26 | cube: Mesh
27 | private composer: EffectComposer
28 | private controls?: OrbitControls
29 | private fbxMixer?: AnimationMixer
30 | private gltfMixer?: AnimationMixer
31 |
32 | constructor(renderer: WebGLRenderer, inputElement: any, width: number, height: number) {
33 | super();
34 | this.name = 'ThreeScene';
35 |
36 | this.camera = new PerspectiveCamera(60, width / height, 0.1, 100)
37 | this.camera.position.z = 12
38 |
39 | this.cube = new Mesh(new BoxGeometry(), new MeshStandardMaterial({ roughness: 0.1, metalness: 0.75 }))
40 | this.add(this.cube);
41 |
42 | const light = new DirectionalLight()
43 | light.position.set(3, 5, 5)
44 | this.add(light)
45 |
46 | const ambient = new AmbientLight(0xffffff, 0.1)
47 | this.add(ambient)
48 |
49 | // Post
50 | this.composer = new EffectComposer(renderer, { frameBufferType: HalfFloatType })
51 | this.composer.addPass(new RenderPass(this, this.camera))
52 | this.composer.addPass(new EffectPass(this.camera, new FXAAEffect(), new VignetteEffect()))
53 |
54 | // Orbit
55 | // @ts-ignore
56 | this.controls = new OrbitControls(this.camera, inputElement)
57 | this.controls.target.set( 0, 0, 0 );
58 | this.controls.enableDamping = true
59 | this.controls.maxDistance = 20
60 | this.controls.minDistance = 4
61 | this.controls.update()
62 | }
63 |
64 | dispose() {
65 | this.controls?.dispose();
66 | }
67 |
68 | update(delta: number) {
69 | this.cube.rotation.x += delta
70 | this.fbxMixer?.update(delta)
71 | this.gltfMixer?.update(delta)
72 | this.controls?.update(delta)
73 | }
74 |
75 | draw() {
76 | this.composer.render()
77 | }
78 |
79 | resize(width: number, height: number, updateStyle: boolean) {
80 | this.camera.aspect = width / height
81 | this.camera.updateProjectionMatrix()
82 | this.composer.setSize(width, height, updateStyle)
83 | }
84 |
85 | async onLoad(assets: Assets) {
86 | // Cube Texture
87 | const cubeTexture = new CubeTexture([
88 | assets.image.get('px'),
89 | assets.image.get('nx'),
90 | assets.image.get('py'),
91 | assets.image.get('ny'),
92 | assets.image.get('pz'),
93 | assets.image.get('nz'),
94 | ], CubeReflectionMapping)
95 | cubeTexture.needsUpdate = true
96 | this.background = cubeTexture
97 |
98 | // Image
99 | const texture = new Texture(assets.image.get('uvGrid'))
100 | texture.needsUpdate = true
101 | const material = new MeshBasicMaterial({ map: texture, side: DoubleSide })
102 | const mesh = new Mesh(new PlaneGeometry(), material)
103 | mesh.position.z = -5
104 | mesh.scale.setScalar(6)
105 | mesh.scale.y *= -1
106 | this.add(mesh)
107 |
108 | // FBX
109 | const fbx = await createModel(assets.model.get('Idle')!)
110 | fbx.model.position.set(-1.5, -1, 0)
111 | fbx.model.scale.setScalar(0.01)
112 | this.add(fbx.model)
113 | this.fbxMixer = fbx.mixer
114 |
115 | // GLTF
116 | const gltf = await createModel(assets.model.get('Horse')!)
117 | gltf.model.position.set(1.5, -1, 0)
118 | gltf.model.scale.setScalar(0.01)
119 | this.add(gltf.model)
120 | this.gltfMixer = gltf.mixer
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/webgl/threeUtils.ts:
--------------------------------------------------------------------------------
1 | import {
2 | AnimationClip,
3 | AnimationMixer,
4 | Audio,
5 | Material,
6 | Mesh,
7 | Object3D,
8 | Object3DEventMap,
9 | ObjectLoader,
10 | Texture,
11 | } from 'three';
12 | import { ModelInfo } from '../types'
13 |
14 | type ParsedModel = {
15 | model: Object3D
16 | mixer: AnimationMixer
17 | cameras: Object3D[]
18 | }
19 |
20 | export function createModel(model: ModelInfo): Promise {
21 | return new Promise((resolve) => {
22 | const loader = new ObjectLoader();
23 | loader.parseAsync(model.scene).then((scene: Object3D) => {
24 | // Load animations
25 | const mixer = new AnimationMixer(scene);
26 | if (model.animations.length > 0) {
27 | // @ts-ignore
28 | const animations = model.animations.map(data => AnimationClip.parse(data));
29 | // Play the first animation
30 | const action = mixer.clipAction(animations[0]);
31 | action.play();
32 | }
33 |
34 | const cameras: Object3D[] = []
35 | if (model.cameras && model.cameras.length > 0) {
36 | model.cameras.forEach((value: unknown) => {
37 | loader.parseAsync(value).then((camera) => {
38 | cameras.push(camera)
39 | })
40 | })
41 | }
42 |
43 | resolve({
44 | model: scene,
45 | mixer,
46 | cameras,
47 | });
48 | })
49 | })
50 | }
51 |
52 | export const disposeTexture = (texture?: Texture): void => {
53 | texture?.dispose();
54 | };
55 |
56 | export const disposeMaterial = (material?: Material | Material[]): void => {
57 | if (!material) return;
58 |
59 | if (Array.isArray(material)) {
60 | material.forEach((mat: Material) => mat.dispose());
61 | } else {
62 | material.dispose();
63 | }
64 | };
65 |
66 | export const dispose = (object: Object3D): void => {
67 | if (!object) return;
68 |
69 | // Dispose children
70 | while (object.children.length > 0) {
71 | const child = object.children[0];
72 | if (child.type === 'Audio') {
73 | (child as Audio).pause();
74 | if (child.parent) {
75 | child.parent.remove(child);
76 | }
77 | } else {
78 | dispose(child);
79 | }
80 | }
81 |
82 | // Dispose object
83 | if (object.parent) object.parent.remove(object);
84 | // @ts-ignore
85 | if (object.isMesh) {
86 | const mesh = object as Mesh;
87 | mesh.geometry?.dispose();
88 | disposeMaterial(mesh.material);
89 | }
90 |
91 | // @ts-ignore
92 | if (object.dispose !== undefined) object.dispose();
93 | };
94 |
--------------------------------------------------------------------------------
/src/webworker/CanvasWorker.ts:
--------------------------------------------------------------------------------
1 | import { ProxyManager } from './ProxyManager';
2 | import ThreeApp from '../webgl/ThreeApp'
3 |
4 | let app: ThreeApp
5 | const proxyManager = new ProxyManager();
6 |
7 | function createApp(data: any) {
8 | const canvas = data.canvas as HTMLCanvasElement
9 | if (!(canvas instanceof OffscreenCanvas)) {
10 | console.log(`Doesn't support offscreen`)
11 | return
12 | }
13 |
14 | const proxy = proxyManager.getProxy(data.canvasId);
15 | app = new ThreeApp(canvas, proxy, data)
16 | app.play()
17 | }
18 |
19 | self.onmessage = (event) => {
20 | const type = event.data.type
21 | switch (type) {
22 | case 'init':
23 | createApp(event.data)
24 | break
25 | case 'loadComplete':
26 | app.onLoad(event.data.data)
27 | break
28 | case 'event':
29 | proxyManager.handleEvent(event.data)
30 | break
31 | case 'makeProxy':
32 | proxyManager.makeProxy(event.data)
33 | break
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/webworker/EventHandling.ts:
--------------------------------------------------------------------------------
1 | // Transfer Events
2 |
3 | type EventHandler = (event: Event, sendFn: (data: any) => void) => void;
4 |
5 | const mouseEventHandler = makeSendPropertiesHandler([
6 | 'ctrlKey',
7 | 'metaKey',
8 | 'shiftKey',
9 | 'button',
10 | 'pointerId',
11 | 'pointerType',
12 | 'clientX',
13 | 'clientY',
14 | 'pageX',
15 | 'pageY',
16 | ]);
17 |
18 | const wheelEventHandlerImpl = makeSendPropertiesHandler([
19 | 'clientX',
20 | 'clientY',
21 | 'deltaX',
22 | 'deltaY',
23 | 'deltaMode',
24 | ]);
25 |
26 | const keydownEventHandler = makeSendPropertiesHandler([
27 | 'ctrlKey',
28 | 'metaKey',
29 | 'shiftKey',
30 | 'keyCode',
31 | ]);
32 |
33 | function wheelEventHandler(event: WheelEvent, sendFn: (data: any) => void): void {
34 | event.preventDefault();
35 | wheelEventHandlerImpl(event, sendFn);
36 | }
37 |
38 | function preventDefaultHandler(event: Event): void {
39 | event.preventDefault();
40 | }
41 |
42 | function copyProperties(
43 | src: Record,
44 | properties: string[],
45 | dst: Record
46 | ): void {
47 | for (const name of properties) {
48 | dst[name] = src[name];
49 | }
50 | }
51 |
52 | function makeSendPropertiesHandler(properties: string[]): EventHandler {
53 | return function sendProperties(event: Event, sendFn: (data: any) => void): void {
54 | const data: Record = { type: event.type };
55 | copyProperties(event as Record, properties, data);
56 | sendFn(data);
57 | };
58 | }
59 |
60 | function touchEventHandler(event: TouchEvent, sendFn: (data: any) => void): void {
61 | const touches: Array<{ pageX: number; pageY: number }> = [];
62 | const data = { type: event.type, touches };
63 |
64 | for (let i = 0; i < event.touches.length; ++i) {
65 | const touch = event.touches[i];
66 | touches.push({
67 | pageX: touch.pageX,
68 | pageY: touch.pageY,
69 | });
70 | }
71 |
72 | sendFn(data);
73 | }
74 |
75 | // The four arrow keys
76 | const orbitKeys: Record = {
77 | '37': true, // left
78 | '38': true, // up
79 | '39': true, // right
80 | '40': true, // down
81 | };
82 |
83 | function filteredKeydownEventHandler(
84 | event: KeyboardEvent,
85 | sendFn: (data: any) => void
86 | ): void {
87 | const { keyCode } = event;
88 | if (orbitKeys[keyCode]) {
89 | event.preventDefault();
90 | keydownEventHandler(event, sendFn);
91 | }
92 | }
93 |
94 | // Proxy
95 |
96 | export const eventHandlers: Record = {
97 | contextmenu: preventDefaultHandler,
98 | mousedown: mouseEventHandler,
99 | mousemove: mouseEventHandler,
100 | mouseup: mouseEventHandler,
101 | pointerdown: mouseEventHandler,
102 | pointermove: mouseEventHandler,
103 | pointerup: mouseEventHandler,
104 | touchstart: touchEventHandler,
105 | touchmove: touchEventHandler,
106 | touchend: touchEventHandler,
107 | wheel: wheelEventHandler,
108 | keydown: filteredKeydownEventHandler,
109 | };
110 |
111 | let nextProxyId = 0;
112 |
113 | export class ElementProxy {
114 | id: number;
115 | worker: Worker;
116 |
117 | constructor(
118 | element: HTMLElement,
119 | worker: Worker,
120 | eventHandlers: Record
121 | ) {
122 | this.id = nextProxyId++;
123 | this.worker = worker;
124 |
125 | const sendEvent = (data: any): void => {
126 | this.worker.postMessage({
127 | type: 'event',
128 | id: this.id,
129 | data,
130 | });
131 | };
132 |
133 | // Register an ID
134 | worker.postMessage({
135 | type: 'makeProxy',
136 | id: this.id,
137 | });
138 |
139 | for (const [eventName, handler] of Object.entries(eventHandlers)) {
140 | element.addEventListener(eventName, (event) => {
141 | handler(event as any, sendEvent);
142 | });
143 | }
144 |
145 | function sendSize(): void {
146 | sendEvent({
147 | type: 'resize',
148 | left: 0,
149 | top: 0,
150 | width: innerWidth,
151 | height: innerHeight,
152 | });
153 | }
154 |
155 | // Really need to use ResizeObserver
156 | window.addEventListener('resize', sendSize);
157 | sendSize();
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/src/webworker/LoadWorker.ts:
--------------------------------------------------------------------------------
1 | import { Group, Object3DEventMap } from 'three'
2 | import { FBXLoader } from 'three/examples/jsm/Addons.js'
3 | import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
4 | import { GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
5 | import { Assets, File, ModelInfo } from '../types'
6 |
7 | let loadedAssets = 0
8 |
9 | const assets: Assets = {
10 | audio: new Map(),
11 | blob: new Map(),
12 | buffer: new Map(),
13 | image: new Map(),
14 | json: new Map(),
15 | model: new Map(),
16 | video: new Map(),
17 | }
18 |
19 | // Loaders
20 |
21 | const draco = new DRACOLoader();
22 | draco.setDecoderPath('/libs/draco/');
23 | draco.preload()
24 |
25 | const fbxLoader = new FBXLoader()
26 |
27 | const gltfLoader = new GLTFLoader()
28 | gltfLoader.setDRACOLoader(draco)
29 |
30 | // Load functions
31 |
32 | async function loadBuffer(url: string): Promise {
33 | const response = await fetch(url);
34 | return await response.arrayBuffer();
35 | }
36 |
37 | async function loadBlob(url: string): Promise {
38 | const response = await fetch(url);
39 | return await response.blob();
40 | }
41 |
42 | async function loadFBX(url: string): Promise {
43 | return new Promise((resolve) => {
44 | fbxLoader.loadAsync(url)
45 | .then((value: Group) => {
46 | resolve({
47 | animations: value.animations.map(animation => animation.toJSON(animation)),
48 | scene: value.toJSON(),
49 | })
50 | })
51 | .catch((reason: any) => {
52 | console.log('FBX Error:')
53 | console.log(reason)
54 | })
55 | })
56 | }
57 |
58 | async function loadGLTF(url: string): Promise {
59 | return new Promise((resolve) => {
60 | gltfLoader.loadAsync(url)
61 | .then((value: GLTF) => {
62 | resolve({
63 | animations: value.animations.map(animation => animation.toJSON(animation)),
64 | cameras: value.cameras.map(camera => camera.toJSON()),
65 | scene: value.scene.toJSON(),
66 | })
67 | })
68 | .catch((reason: any) => {
69 | console.log('GLTF Error:')
70 | console.log(reason)
71 | })
72 | })
73 | }
74 |
75 | async function loadImage(url: string): Promise {
76 | const response = await fetch(url);
77 | const blob = await response.blob();
78 | return await createImageBitmap(blob);
79 | }
80 |
81 | async function loadJSON(url: string): Promise {
82 | const response = await fetch(url);
83 | return response.json();
84 | }
85 |
86 | // Load calls
87 |
88 | function loadStart(assetList: File[]) {
89 | assetList.forEach((item: File) => {
90 | switch (item.type) {
91 | case 'audio':
92 | loadBuffer(item.file).then((value: ArrayBuffer) => {
93 | assets.audio.set(item.name, value)
94 | onLoad(assetList)
95 | })
96 | break
97 | case 'blob':
98 | loadBlob(item.file).then((value: Blob) => {
99 | assets.blob.set(item.name, value)
100 | onLoad(assetList)
101 | })
102 | break
103 | case 'buffer':
104 | loadBuffer(item.file).then((value: ArrayBuffer) => {
105 | assets.buffer.set(item.name, value)
106 | onLoad(assetList)
107 | })
108 | break
109 | case 'fbx':
110 | loadFBX(item.file).then((value: ModelInfo) => {
111 | assets.model.set(item.name, value)
112 | onLoad(assetList)
113 | })
114 | break
115 | case 'gltf':
116 | loadGLTF(item.file).then((value: ModelInfo) => {
117 | assets.model.set(item.name, value)
118 | onLoad(assetList)
119 | })
120 | break
121 | case 'image':
122 | loadImage(item.file).then((value: ImageBitmap) => {
123 | assets.image.set(item.name, value)
124 | onLoad(assetList)
125 | })
126 | break
127 | case 'json':
128 | loadJSON(item.file).then((value: any) => {
129 | assets.json.set(item.name, value)
130 | onLoad(assetList)
131 | })
132 | break
133 | case 'video':
134 | loadBlob(item.file).then((value: Blob) => {
135 | assets.video.set(item.name, value)
136 | onLoad(assetList)
137 | })
138 | break
139 | }
140 | })
141 | }
142 |
143 | function onLoad(assetList: File[]) {
144 | loadedAssets++
145 | if (loadedAssets >= assetList.length) loadComplete()
146 | }
147 |
148 | function loadComplete() {
149 | self.postMessage({ type: 'loadComplete', data: assets })
150 | }
151 |
152 | // Worker
153 |
154 | self.onmessage = (event) => {
155 | switch (event.data.type) {
156 | case 'loadStart':
157 | loadStart(event.data.data)
158 | break;
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/src/webworker/ProxyManager.ts:
--------------------------------------------------------------------------------
1 | import { EventDispatcher } from 'three';
2 |
3 | function noop(): void {}
4 |
5 | interface SizeData {
6 | left: number;
7 | top: number;
8 | width: number;
9 | height: number;
10 | }
11 |
12 | interface EventData extends SizeData {
13 | type: string;
14 | id?: number;
15 | data?: any;
16 | preventDefault?: () => void;
17 | stopPropagation?: () => void;
18 | }
19 |
20 | export class ElementProxyReceiver extends EventDispatcher {
21 | style: Record = {};
22 | left: number = 0;
23 | top: number = 0;
24 | width: number = 0;
25 | height: number = 0;
26 | ownerDocument: any = undefined;
27 |
28 | constructor() {
29 | super()
30 | this.ownerDocument = this
31 | }
32 |
33 | get clientWidth(): number {
34 | return this.width;
35 | }
36 |
37 | set clientWidth(value: number) {
38 | this.width = value;
39 | }
40 |
41 | get clientHeight(): number {
42 | return this.height;
43 | }
44 |
45 | set clientHeight(value: number) {
46 | this.height = value;
47 | }
48 |
49 | // OrbitControls call these as of r132. Implementing as no-ops
50 | setPointerCapture(): void {}
51 | releasePointerCapture(): void {}
52 |
53 | getBoundingClientRect(): DOMRect {
54 | return {
55 | x: this.left,
56 | y: this.top,
57 | left: this.left,
58 | top: this.top,
59 | width: this.width,
60 | height: this.height,
61 | right: this.left + this.width,
62 | bottom: this.top + this.height,
63 | toJSON: () => ({}) // Satisfies the DOMRect interface
64 | };
65 | }
66 |
67 | handleEvent(data: EventData): void {
68 | if (data.type === 'size') {
69 | this.left = data.left;
70 | this.top = data.top;
71 | this.width = data.width;
72 | this.height = data.height;
73 | return;
74 | }
75 |
76 | // Extend event data to include preventDefault and stopPropagation as no-ops
77 | data.preventDefault = noop;
78 | data.stopPropagation = noop;
79 | // @ts-ignore
80 | this.dispatchEvent(data);
81 | }
82 |
83 | focus(): void {
84 | // No-op
85 | }
86 |
87 | getRootNode(): any {
88 | return this
89 | }
90 | }
91 |
92 | export class ProxyManager {
93 | targets: Record = {};
94 |
95 | constructor() {
96 | this.handleEvent = this.handleEvent.bind(this);
97 | }
98 |
99 | makeProxy(data: { id: number }): void {
100 | const { id } = data;
101 | const proxy = new ElementProxyReceiver();
102 | this.targets[id] = proxy;
103 | }
104 |
105 | getProxy(id: number): ElementProxyReceiver {
106 | return this.targets[id];
107 | }
108 |
109 | handleEvent(data: { id: number; data: EventData }): void {
110 | this.targets[data.id]?.handleEvent(data.data);
111 | }
112 | }
--------------------------------------------------------------------------------
/src/webworker/workers.ts:
--------------------------------------------------------------------------------
1 | import { dispatcher, Events } from '../global/constants'
2 | import Settings from '../global/settings'
3 |
4 | export default class Workers {
5 | static canvas: Worker | null
6 | static loader: Worker | null
7 |
8 | static init() {
9 | // Canvas
10 |
11 | if (Settings.supportOffScreenCanvas) {
12 | this.canvas = new Worker(new URL('./CanvasWorker.ts', import.meta.url), { type: 'module' })
13 | }
14 |
15 | // Loader
16 |
17 | this.loader = new Worker(new URL('./LoadWorker.ts', import.meta.url), { type: 'module' })
18 | this.loader.onmessage = (event: MessageEvent) => {
19 | if (event.data.type === 'loadComplete') {
20 | const assets = event.data.data
21 | dispatcher.dispatchEvent({ type: Events.LoadComplete, value: assets })
22 | this.canvas?.postMessage({ type: 'loadComplete', data: assets })
23 | this.loader?.terminate()
24 | this.loader = null
25 | }
26 | }
27 |
28 | const loadStart = (event: any) => {
29 | dispatcher.removeEventListener(Events.LoadStart, loadStart)
30 | this.loader?.postMessage({ type: 'loadStart', data: event.value })
31 | }
32 | dispatcher.addEventListener(Events.LoadStart, loadStart)
33 | }
34 |
35 | static dispose() {
36 | this.canvas?.terminate()
37 | this.canvas = null
38 | this.loader?.terminate()
39 | this.loader = null
40 | }
41 | }
--------------------------------------------------------------------------------
/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4 | "target": "ES2020",
5 | "useDefineForClassFields": true,
6 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
7 | "module": "ESNext",
8 | "skipLibCheck": true,
9 |
10 | /* Bundler mode */
11 | "moduleResolution": "Bundler",
12 | "allowImportingTsExtensions": true,
13 | "isolatedModules": true,
14 | "moduleDetection": "force",
15 | "noEmit": true,
16 | "jsx": "react-jsx",
17 |
18 | /* Linting */
19 | "strict": true,
20 | "noUnusedLocals": true,
21 | "noUnusedParameters": true,
22 | "noFallthroughCasesInSwitch": true,
23 | "noUncheckedSideEffectImports": true
24 | },
25 | "include": ["src"]
26 | }
27 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | { "path": "./tsconfig.app.json" },
5 | { "path": "./tsconfig.node.json" }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
4 | "target": "ES2022",
5 | "lib": ["ES2023"],
6 | "module": "ESNext",
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "Bundler",
11 | "allowImportingTsExtensions": true,
12 | "isolatedModules": true,
13 | "moduleDetection": "force",
14 | "noEmit": true,
15 |
16 | /* Linting */
17 | "strict": true,
18 | "noUnusedLocals": true,
19 | "noUnusedParameters": true,
20 | "noFallthroughCasesInSwitch": true,
21 | "noUncheckedSideEffectImports": true
22 | },
23 | "include": ["vite.config.ts"]
24 | }
25 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vite.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------