@maptalks/gpu 0.117.0 → 0.117.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @maptalks/gpu v0.117.0
2
+ * @maptalks/gpu v0.117.1
3
3
  * LICENSE : UNLICENSED
4
4
  * (c) 2016-2025 maptalks.com
5
5
  */
@@ -67,7 +67,7 @@ transcoders.getTranscoder = getTranscoder;
67
67
 
68
68
  function gltfLoaderExport(e){var t=function(){return "undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:void 0};if(t().maptalks_gltf_loader)return;
69
69
  /*!
70
- * @maptalks/gltf-loader v0.117.0
70
+ * @maptalks/gltf-loader v0.117.1
71
71
  * LICENSE : UNLICENSED
72
72
  * (c) 2016-2025 maptalks.org
73
73
  */var s="undefined"!=typeof Float32Array?Float32Array:Array;function r(e,t,s){var r=t[0],n=t[1],i=t[2],a=t[3],o=t[4],f=t[5],u=t[6],h=t[7],c=t[8],l=t[9],d=t[10],m=t[11],g=t[12],p=t[13],b=t[14],_=t[15],y=s[0],x=s[1],w=s[2],T=s[3];return e[0]=y*r+x*o+w*c+T*g,e[1]=y*n+x*f+w*l+T*p,e[2]=y*i+x*u+w*d+T*b,e[3]=y*a+x*h+w*m+T*_,y=s[4],x=s[5],w=s[6],T=s[7],e[4]=y*r+x*o+w*c+T*g,e[5]=y*n+x*f+w*l+T*p,e[6]=y*i+x*u+w*d+T*b,e[7]=y*a+x*h+w*m+T*_,y=s[8],x=s[9],w=s[10],T=s[11],e[8]=y*r+x*o+w*c+T*g,e[9]=y*n+x*f+w*l+T*p,e[10]=y*i+x*u+w*d+T*b,e[11]=y*a+x*h+w*m+T*_,y=s[12],x=s[13],w=s[14],T=s[15],e[12]=y*r+x*o+w*c+T*g,e[13]=y*n+x*f+w*l+T*p,e[14]=y*i+x*u+w*d+T*b,e[15]=y*a+x*h+w*m+T*_,e}function n(){var e=new s(3);return s!=Float32Array&&(e[0]=0,e[1]=0,e[2]=0),e}function i(e,t,r){var n=new s(3);return n[0]=e,n[1]=t,n[2]=r,n}function a(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e}function o(e,t,s,r){return e[0]=t,e[1]=s,e[2]=r,e}function f(e,t,s){return e[0]=t[0]+s[0],e[1]=t[1]+s[1],e[2]=t[2]+s[2],e}function u(e,t,s){return e[0]=t[0]*s,e[1]=t[1]*s,e[2]=t[2]*s,e}function h(e,t,s,r,n){return e[0]=t,e[1]=s,e[2]=r,e[3]=n,e}function c(e,t,s){var r=t[0],n=t[1],i=t[2],a=t[3];return e[0]=s[0]*r+s[4]*n+s[8]*i+s[12]*a,e[1]=s[1]*r+s[5]*n+s[9]*i+s[13]*a,e[2]=s[2]*r+s[6]*n+s[10]*i+s[14]*a,e[3]=s[3]*r+s[7]*n+s[11]*i+s[15]*a,e}function l(){var e=new s(4);return s!=Float32Array&&(e[0]=0,e[1]=0,e[2]=0),e[3]=1,e}Math.hypot||(Math.hypot=function(){for(var e=0,t=arguments.length;t--;)e+=arguments[t]*arguments[t];return Math.sqrt(e)}),n(),function(){var e;e=new s(4),s!=Float32Array&&(e[0]=0,e[1]=0,e[2]=0,e[3]=0);}();var d,m=function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e};n(),i(1,0,0),i(0,1,0),l(),l(),d=new s(9),s!=Float32Array&&(d[1]=0,d[2]=0,d[3]=0,d[5]=0,d[6]=0,d[7]=0),d[0]=1,d[4]=1,d[8]=1;let g=0;function p(e){return null==e}function b(e){return !p(e)}function _(e){return !p(e)&&("string"==typeof e||null!==e.constructor&&e.constructor===String)}function y(e){for(let t=1;t<arguments.length;t++){const s=arguments[t];for(const t in s)e[t]=s[t];}return e}function x(e){switch(e){case 5120:return Int8Array;case 5121:return Uint8Array;case 5122:return Int16Array;case 5123:return Uint16Array;case 5124:return Int32Array;case 5125:return Uint32Array;case 5126:return Float32Array}throw new Error("unsupported bufferView's component type: "+e)}function w(e){return 0===e.indexOf("data:")&&e.indexOf("base64,")>0}function T(e){const t=function(e){return "undefined"!=typeof self?self.atob(e):window.atob(e)}(e.substring(e.indexOf(",")+1)),s=t.length,r=new Uint8Array(s);for(let e=0;e<s;e++)r[e]=t.charCodeAt(e);return r.buffer}const E=[],O=[],I=[],R=[0,0,0],A=function(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e}([]),q=[1,1,1];function B(e,t,s,r,n,i,a){const o=x(a),f=o.BYTES_PER_ELEMENT;if((0===n||n===r*f)&&i%f==0){const n=new o(t,i,s*r);return e.set(n),e}0===n&&(n=r*f);const u=new Uint8Array(r*f);for(let a=0;a<s;a++){let s=null;const h=new Uint8Array(t,n*a+i,r*f);u.set(h),s=new o(u.buffer,0,r);for(let t=0;t<r;t++)e[a*r+t]=s[t];}return e}const N="undefined"!=typeof TextDecoder?new TextDecoder("utf-8"):null;function v(e,t,s){const r=new Uint8Array(e,t,s);return N.decode(r)}const P={get:function(e,t={},s){t||(t={});const r=new AbortController,n=r.signal,i=y({},t);i.signal=n,i.method||(i.method="GET"),i.referrerPolicy=i.referrerPolicy||"origin","undefined"==typeof window||i.referrer||(i.referrer=window.location.href),s&&(e=s(e));const a=fetch(e,i).then((e=>{const s=this._parseResponse(e,t.responseType);return s.message?s:s.then((s=>"arraybuffer"===t.responseType?{data:s,cacheControl:e.headers.get("Cache-Control"),expires:e.headers.get("Expires"),contentType:e.headers.get("Content-Type")}:s)).catch((e=>{if(!e.code||e.code!==DOMException.ABORT_ERR)throw e}))})).catch((e=>{if(!e.code||e.code!==DOMException.ABORT_ERR)throw e}));return a.xhr=r,a},_parseResponse:(e,t)=>200!==e.status?{status:e.status,statusText:e.statusText,message:`incorrect http request with status code(${e.status}): ${e.statusText}`}:"arraybuffer"===t?e.arrayBuffer():"json"===t?e.json():e.text(),getArrayBuffer:(e,t={},s)=>(t||(t={}),t.responseType="arraybuffer",P.get(e,t,s)),getJSON:function(e,t={},s){return t&&t.jsonp?P.jsonp(e):((t=t||{}).responseType="json",P.get(e,t,s))},jsonp:function(e){const t="_maptalks_jsonp_"+g++;e.match(/\?/)?e+="&callback="+t:e+="?callback="+t;let s=document.createElement("script");return s.type="text/javascript",s.src=e,new Promise((e=>{window[t]=function(r){document.getElementsByTagName("head")[0].removeChild(s),s=null,delete window[t],e(r);},document.getElementsByTagName("head")[0].appendChild(s);}))}};class M{constructor(e,t,s,r,n){this._requestImage=e,this.decoders=t,this._supportedFormats=s,this.images={},this._imgRequests={},this._fetchOptions=r||{},this._urlModifier=n;}requestImageFromBufferURI(e,t,s){if(this.buffers[e.id]){const r=this.buffers[e.id],n=this._createDataView(t,r);return this.getImageByBuffer(n,s)}if(this._imgRequests[e.id])return this._imgRequests[e.id].then((()=>{const r=this.buffers[e.id],n=this._createDataView(t,r);return this.getImageByBuffer(n,s)}));if(w(e.uri)){const r=this.buffers[e.id]=T(e.uri),n=this._createDataView(t,r);return this.getImageByBuffer(n,s)}let r;const n=e.uri.indexOf("blob:")>=0;return r=e.uri.indexOf("://")>0||n?e.uri:this.rootPath+"/"+e.uri,this._imgRequests[e.id]=P.getArrayBuffer(r,this._fetchOptions,this._urlModifier).then((r=>{const n=this.buffers[e.id]=r.data,i=this._createDataView(t,n);return this.getImageByBuffer(i,s)}))}getImageByBuffer(e,t){if(this.images[t.id])return Promise.resolve(this.images[t.id]);const s=this.decoders;if(s[t.mimeType])return s[t.mimeType](e,{supportedFormats:this._supportedFormats});if("image/crn"===t.mimeType||"image/ktx2"===t.mimeType||"image/cttf"===t.mimeType)throw new Error("missing transcoder for "+t.mimeType,"");return this._getImageInfo(t.id,e)}requestExternalImage(e){if(this.images[e.id])return Promise.resolve(this.images[e.id]);const t=0===e.uri.indexOf("data:image/")?e.uri:this.rootPath+"/"+e.uri;return this._imgRequests[e.id]?this._imgRequests[e.id].then((()=>this.images[e.id])):this._imgRequests[e.id]=this._getImageInfo(e.id,t)}_getImageInfo(e,t){return new Promise(((s,r)=>{let n=t;this._urlModifier&&(n=this._urlModifier(t)),this._requestImage(n,this._fetchOptions,((n,i)=>{n?r(n):(URL.revokeObjectURL(t),this.images[e]=i,s(this.images[e]));}));}))}}const S=["SCALAR",1,"VEC2",2,"VEC3",3,"VEC4",4,"MAT2",4,"MAT3",9,"MAT4",16],V=[];class L{constructor(e,t,s,r,n){this.rootPath=e,this.gltf=t,this._enableInterleave=!1,this.glbBuffer=s,this.buffers={},this.requests={},this.accessors={},this._compareAccessor(),this._fetchOptions=r,this._urlModifier=n;}_requestData(e,t){const s=this.gltf,r=s.accessors[t];if(void 0===r.bufferView)return this.accessors[r.id]=this._toBufferData(e,t,null,0),Promise.resolve(this.accessors[r.id]);if(r&&this.accessors[r.id])return Promise.resolve(this.accessors[r.id]);const n=s.bufferViews[r.bufferView];return this._requestBufferOfBufferView(n).then((s=>{const{buffer:n,byteOffset:i}=s;return this.accessors[r.id]=this._toBufferData(e,t,n,i)}))}_requestBufferOfBufferView(e){const t=this.gltf.buffers[e.buffer];if(this.buffers[t.id]){const e=this.buffers[t.id];return Promise.resolve({buffer:e,byteOffset:0})}if(this.requests[t.id])return this.requests[t.id].then((()=>{const e=this.buffers[t.id];return Promise.resolve({buffer:e,byteOffset:0})}));if("binary_glTF"!==e.buffer&&"KHR_binary_glTF"!==e.buffer&&t.uri){if(w(t.uri)){const e=this.buffers[t.id]=T(t.uri);return Promise.resolve({buffer:e,byteOffset:0})}let e;const s=t.uri.indexOf("blob:")>=0;return e=t.uri.indexOf("://")>0||s?t.uri:this.rootPath+"/"+t.uri,this.requests[t.id]=P.getArrayBuffer(e,this._fetchOptions,!s&&this._urlModifier).then((r=>(s&&URL.revokeObjectURL(e),{buffer:this.buffers[t.id]=r.data,byteOffset:0})))}return Promise.resolve({buffer:this.glbBuffer.buffer,byteOffset:this.glbBuffer.byteOffset})}_toBufferData(e,t,s,r=0){const n=this.gltf,i=n.accessors[t],a=void 0!==i.bufferView?n.bufferViews[i.bufferView]:{},o=(a.byteOffset||0)+r,f=this._getTypeItemSize(i.type),u=x(i.componentType),h=a.byteStride||0,l={array:void 0,name:e,accessorName:t,byteLength:i.count*f*u.BYTES_PER_ELEMENT,componentType:i.componentType,count:i.count,type:i.type,itemSize:f,max:i.max,min:i.min,extensions:i.extensions};if(i.min&&(l.min=i.min),i.max&&(l.max=i.max),s)if(this._enableInterleave)l.byteStride=h,l.byteOffset=o+(i.byteOffset||0),!h||h===f*u.BYTES_PER_ELEMENT||"indices"===e||"input"===e||"output"===e||e.indexOf("morph")>=0?(l.array=this._typedArray(s,i.count,f,o+(i.byteOffset||0),u),l.array.buffer.byteLength===l.byteLength&&(l.byteOffset=0)):l.array=new Uint8Array(s,o,a.byteLength);else if(i.interleaved){l.byteStride=0,l.byteOffset=0;const e=new u(i.count*f);if(l.array=B(e,s,i.count,f,h,o+(i.byteOffset||0),i.componentType),l.extensions&&l.extensions.WEB3D_quantized_attributes&&f>2){const e=new Float32Array(l.array.length),{decodeMatrix:t}=l.extensions.WEB3D_quantized_attributes;for(let s=0;s<l.array.length;s+=f){V[0]=l.array[s],V[1]=l.array[s+1],V[2]=l.array[s+2],V[3]=1;const r=c(V,V,t);e[s]=r[0],e[s+1]=r[1],e[s+2]=r[2];}l.componentType=5126,l.array=e;}}else l.byteStride=0,l.array=this._typedArray(s,i.count,f,o+(i.byteOffset||0),u),l.byteOffset=l.array.byteOffset;else {l.array=new u(i.count);const e=l.min||l.max;e&&(l.array[0]=e[0],l.array[1]=e[1],l.array[2]=e[2]);}return l}_compareAccessor(){const e=this.gltf.accessors;if(Array.isArray(e))for(let t=0;t<e.length;t++)for(let s=0;s<e.length;s++)t!==s&&e[t].bufferView===e[s].bufferView&&(e[t].interleaved=e[s].interleaved=!0);else for(const t in e)for(const s in e)t!==s&&e[t].bufferView===e[s].bufferView&&(e[t].interleaved=e[s].interleaved=!0);}_typedArray(e,t,s,r,n){return r%n.BYTES_PER_ELEMENT!=0&&(e=e.slice(r,r+t*s*n.BYTES_PER_ELEMENT),r=0),new n(e,r,s*t)}_getTypeItemSize(e){const t=S.indexOf(e);return S[t+1]}requestKHRTechniquesWebgl(e){const{shaders:t}=e,s=t.map((e=>{if(void 0!==e.bufferView){const t=this.gltf.bufferViews[e.bufferView],{byteLength:s}=t;return this._requestBufferOfBufferView(t).then((r=>{const{buffer:n,byteOffset:i}=r,a=v(n,i+(t.byteOffset||0),s);return e.content=a,e}))}if(e.uri){if(w(e.uri)){const t=T(e.uri),s=v(t,0,t.byteLength);return e.content=s,Promise.resolve(e)}{const t=this.rootPath+"/"+e.uri;return P.get(t,this._fetchOptions,this._urlModifier).then((t=>(e.content=t,e)))}}return Promise.resolve(e)}));return Promise.all(s).then((()=>e))}}class D extends M{constructor(e,t,s,r,n,i,a,o){super(r,n,i,a,o),this.rootPath=e,this.gltf=t,this.requests={},this.buffers={},this.glbBuffer=s,this.accessor=new L(e,t,s,a,o);}iterate(e,t){const s=this.gltf[t];if(!s)return;let r=0;for(const t in s)e(t,s[t],r++);}createNode(e){const t={};if(b(e.name)&&(t.name=e.name),b(e.children)&&(t.children=e.children),b(e.jointName)&&(t.jointName=e.jointName),b(e.matrix)&&(t.matrix=e.matrix),b(e.rotation)&&(t.rotation=e.rotation),b(e.scale)&&(t.scale=e.scale),b(e.translation)&&(t.translation=e.translation),b(e.extras)&&(t.extras=e.extras),b(e.meshes)&&(t.mesh=e.meshes[0]),t.translation||t.rotation||t.scale){const e=function(e,t){if(t.matrix)return t.matrix;if(t.translation||t.scale||t.rotation){const s=function(e,t){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=t[0],e[13]=t[1],e[14]=t[2],e[15]=1,e}(E,t.translation||R),n=function(e,t){var s=t[0],r=t[1],n=t[2],i=t[3],a=s+s,o=r+r,f=n+n,u=s*a,h=r*a,c=r*o,l=n*a,d=n*o,m=n*f,g=i*a,p=i*o,b=i*f;return e[0]=1-c-m,e[1]=h+b,e[2]=l-p,e[3]=0,e[4]=h-b,e[5]=1-u-m,e[6]=d+g,e[7]=0,e[8]=l+p,e[9]=d-g,e[10]=1-u-c,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}(O,t.rotation||A),i=function(e,t){return e[0]=t[0],e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=t[1],e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=t[2],e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}(I,t.scale||q);return r(i,n,i),r(e,s,i)}return function(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}(e)}([],t);delete t.translation,delete t.rotation,delete t.scale,t.matrix=e;}return t}_loadMaterials(e){const t={};for(const s in e){const r=e[s];let n,i;r.instanceTechnique&&r.instanceTechnique.values?(n=r.instanceTechnique,i=n.values.diffuse):(n=r,i=n.values.tex||n.values.diffuseTex||n.values.diffuse);const a={baseColorTexture:{index:i}};r.name&&(a.name=r.name),r.extensions&&(a.extensions=r.extensions),r.extras&&(a.extras=r.extras),t[s]=a;}return t}_loadImage(e){if(e.bufferView||e.extensions&&(e.extensions.KHR_binary_glTF||e.extensions.binary_glTF)){const t=e.bufferView?e:e.extensions.KHR_binary_glTF||e.extensions.binary_glTF;e.extensions&&(e.mimeType=t.mimeType,e.width=t.width,e.height=t.height);const s=this.gltf.bufferViews[t.bufferView],r=(s.byteOffset||0)+this.glbBuffer.byteOffset,n=s.byteLength,i=this.buffers[t.bufferView]=new Uint8Array(this.glbBuffer.buffer,r,n);return this.getImageByBuffer(i,e)}return this.requestExternalImage(e)}_getTexture(e){const t=this.gltf.textures[e];if(!t)return null;const s=this.gltf.images[t.source];return this._loadImage(s).then((e=>{const r=this.gltf.samplers[t.sampler];return {image:{array:e.data,width:e.width,height:e.height,index:t.source,mimeType:s.mimeType,name:s.name,extras:s.extras},sampler:r}}))}getBaseColorTexture(e){const t=this.gltf.materials[e];let s,r;if(t.instanceTechnique&&t.instanceTechnique.values?(s=t.instanceTechnique,r=s.values.diffuse):(s=t,r=s.values.tex||s.values.diffuseTex||s.values.diffuse),void 0===r||void 0===this.gltf.textures)return null;const n=this.gltf.textures[r];if(!n)return null;const i=this.gltf.samplers[n.sampler];return {format:n.format||6408,internalFormat:n.internalFormat||6408,type:n.type||5121,sampler:i,source:this.gltf.images[n.source]}}getMaterial(){return null}getAnimations(){return null}}const U=9729;class C extends M{constructor(e,t,s,r,n,i,a,o){super(r,n,i,a,o),this.rootPath=e,this.gltf=t,this.glbBuffer=s,this.buffers={},this.requests={},this.accessor=new L(e,t,s,a,o);}iterate(e,t){const s=this.gltf[t];if(s)for(let t=0;t<s.length;t++)e(t,s[t],t);}createNode(e){const t={};return y(t,e),!b(e.weights)&&this.gltf.meshes&&b(t.mesh)?t.weights=this.gltf.meshes[t.mesh].weights:e.weights&&(t.weights=e.weights),t}_getTexture(e){const t=this.gltf.textures[e];if(!t)return null;let s=t.source;if(t.extensions&&t.extensions.EXT_texture_webp?s=t.extensions.EXT_texture_webp.source:t.extensions&&t.extensions.KHR_texture_basisu&&(s=t.extensions.KHR_texture_basisu.source),!b(s))return null;const r=this.gltf.images[s];return this._loadImage(r).then((e=>{if(!e)return null;const s={image:{array:e.data,mipmap:e.mipmap,width:e.width,height:e.height,index:t.source,mimeType:r.mimeType,name:r.name,extensions:r.extensions,extras:r.extras}};y(s,t);const n=b(t.sampler)?this.gltf.samplers[t.sampler]:void 0;if(n&&(s.sampler=n,s.sampler.magFilter=n.magFilter||U,s.sampler.minFilter=n.minFilter||9987,s.sampler.wrapS=n.wrapS||10497,s.sampler.wrapT=n.wrapT||10497),"image/ktx2"===s.image.mimeType&&!s.image.mipmap&&s.sampler&&s.sampler.minFilter!==U&&9728!==s.sampler.minFilter){const e=s.sampler.minFilter;s.sampler.minFilter=9984===e||9986===e?9728:U;}if(e.format&&(s.format=e.format),6407===s.format){const e=s.image.array&&s.image.array.length;e&&e===s.image.width*s.image.height*4&&(s.format=6408);}return s}))}_loadImage(e){if(!b(e.bufferView))return this.requestExternalImage(e);{const t=this.gltf.bufferViews[e.bufferView],s=this.gltf.buffers[t.buffer];if(s.uri)return this.requestImageFromBufferURI(s,t,e);if(this.glbBuffer)return this._requestFromGlbBuffer(t,e)}return null}_requestFromGlbBuffer(e,t){const s=this._createDataView(e,this.glbBuffer.buffer,this.glbBuffer.byteOffset);return this.getImageByBuffer(s,t)}_createDataView(e,t,s){s=s||0;const r=(e.byteOffset||0)+s,n=e.byteLength;return new Uint8Array(t,r,n)}_transformArrayBufferToBase64(e,t){const s=new Array(e.byteLength);for(let t=0;t<e.byteLength;t++)s[t]=String.fromCharCode(e[t]);s.join("");const r="data:"+(t=t||"image/png")+";base64,"+function(e){return "undefined"!=typeof self?self.btoa(e):window.btoa(e)}(unescape(encodeURIComponent(s)));return r}getAnimations(e){const t=[];return e.forEach((e=>{t.push(this.getSamplers(e.samplers));})),Promise.all(t).then((t=>{for(let s=0;s<t.length;s++)e[s].samplers=t[s];return e}))}getSamplers(e){const t=[];for(let s=0;s<e.length;s++)(b(e[s].input)||b(e[s].output))&&(t.push(this.accessor._requestData("input",e[s].input)),t.push(this.accessor._requestData("output",e[s].output)));return Promise.all(t).then((t=>{for(let s=0;s<t.length/2;s++)e[s].input=t[2*s],e[s].output=t[2*s+1],e[s].interpolation||(e[s].interpolation="LINEAR");return e}))}}const F="undefined"!=typeof TextDecoder?new TextDecoder("utf-8"):null;class k{static read(e,t=0,s=0){s||(s=e.byteLength);const r=new DataView(e,t,s),n=r.getUint32(4,!0);if(1===n)return k.readV1(r,t);if(2===n)return k.readV2(e,t);throw new Error("Unsupported glb version : "+n)}static readV1(e,t){const s=e.getUint32(8,!0),r=e.getUint32(12,!0);if(s!==e.byteLength)throw new Error("Length in GLB header is inconsistent with glb's byte length.");const n=X(e.buffer,20+t,r);return {json:JSON.parse(n),glbBuffer:{byteOffset:20+t+r,buffer:e.buffer,byteLength:s}}}static readV2(e,t){let s,r,n;const i=new DataView(e,t+12);let a=0;for(;a+8<i.byteLength;){const o=i.getUint32(a,!0);a+=4;const f=i.getUint32(a,!0);if(a+=4,1313821514===f)s=X(e,t+12+a,o);else if(5130562===f){n=t+12+a,r=o;break}a+=o;}return {json:JSON.parse(s),glbBuffer:{byteOffset:n,buffer:e,byteLength:r}}}}function X(e,t,s){if(F){const r=new Uint8Array(e,t,s);return F.decode(r)}return function(e){const t=e.length;let s="";for(let r=0;r<t;){let n=e[r++];if(128&n){let s=K[n>>3&7];if(!(64&n)||!s||r+s>t)return null;for(n&=63>>s;s>0;s-=1){const t=e[r++];if(128!=(192&t))return null;n=n<<6|63&t;}}s+=String.fromCharCode(n);}return s}(new Uint8Array(e,t,s))}const K=[1,1,1,1,2,2,3,0],H=[0,0,0],j=[0,0,0,1],z=[1,1,1],W={TRANSLATION:[0,0,0],ROTATION:[0,0,0,1],SCALE:[1,1,1]},G={PREVIOUS:null,NEXT:null,PREINDEX:null,NEXTINDEX:null,INTERPOLATION:null},Y={_getTRSW(e,t,s,r,n,i,o,f){const u=b(e)?t.animations:[t.animations[0]],h={};for(let t=0;t<u.length;t++){const c=u[t],l=c.name||t;if(b(e)&&l!==e)continue;const d=c.channelsMap[s];if(d)for(let e=0;e<d.length;e++){const t=d[e];"translation"===t.target.path?(this._getAnimateData(n,c.samplers[t.sampler],r,1),h.translation=a(H,n)):"rotation"===t.target.path?(this._getQuaternion(i,c.samplers[t.sampler],r,1),h.rotation=m(j,i)):"scale"===t.target.path?(this._getAnimateData(o,c.samplers[t.sampler],r,1),h.scale=a(z,o)):"weights"===t.target.path&&f&&(this._getAnimateData(f,c.samplers[t.sampler],r,f.length),h.weights=f);}}return h},_getAnimateData(e,t,s,r){switch(t.interpolation){case"LINEAR":{const n=this._getPreNext(G,t,s,1*r);n&&(e=function(e,t,s,r){for(let n=0;n<e.length;n++)e[n]=t[n]+r*(s[n]-t[n]);return e}(e,n.PREVIOUS,n.NEXT,n.INTERPOLATION));break}case"STEP":{const n=this._getPreNext(G,t,s,1*r);n&&(e=function(e,t){for(let s=0;s<e.length;s++)e[s]=t[s];return e}(e,...n.PREVIOUS));break}case"CUBICSPLINE":{const n=this._getPreNext(G,t,s,3*r);n&&(e=this._getCubicSpline(e,n,t.input.array,3*r));break}}return e},_getQuaternion(e,t,s){switch(t.interpolation){case"LINEAR":{const r=this._getPreNext(G,t,s,1);r&&function(e,t,s,r){var n,i,a,o,f,u=t[0],h=t[1],c=t[2],l=t[3],d=s[0],m=s[1],g=s[2],p=s[3];(i=u*d+h*m+c*g+l*p)<0&&(i=-i,d=-d,m=-m,g=-g,p=-p),1-i>1e-6?(n=Math.acos(i),a=Math.sin(n),o=Math.sin((1-r)*n)/a,f=Math.sin(r*n)/a):(o=1-r,f=r),e[0]=o*u+f*d,e[1]=o*h+f*m,e[2]=o*c+f*g,e[3]=o*l+f*p;}(e,r.PREVIOUS,r.NEXT,r.INTERPOLATION);break}case"STEP":{const r=this._getPreNext(G,t,s,1);r&&(e=h(e,...r.PREVIOUS));break}case"CUBICSPLINE":{const r=this._getPreNext(G,t,s,3);if(r){for(let e=0;e<r.PREVIOUS.length;e++)r.PREVIOUS[e]=Math.acos(r.PREVIOUS[e]),r.NEXT[e]=Math.acos(r.NEXT[e]);e=this._getCubicSpline(e,r,t.input.array,3);for(let t=0;t<e.length;t++)e[t]=Math.cos(e[t]);}break}}return e},_search(e,t){const s=e.length;let r,n,i,a=0,o=s-1,f=Math.floor((a+o)/2);for(;a<=s-1&&o>=0;){if(a===o)return null;if(e[f]<=t&&t<=e[f+1]){const s=e[f];return r=f,n=f+1,i=(t-s)/(e[f+1]-s),{preIndx:r,nextIndex:n,interpolation:i}}t<e[f]?(o=f,f=Math.floor((a+o)/2)):e[f+1]<t&&(a=f,f=Math.floor((a+o)/2));}return null},_getPreNext(e,t,s,r){const n=t.input.array,i=t.output.array,a=t.output.itemSize;(s<n[0]||s>n[n.length-1])&&(s=Math.max(n[0],Math.min(n[n.length-1],s))),s===n[n.length-1]&&(s=n[0]);const o=this._search(n,s);if(!o||!o.nextIndex)return null;const{preIndx:f,nextIndex:u,interpolation:h}=o;e.PREINDEX=f,e.NEXTINDEX=u,e.INTERPOLATION=h;const c=a*r;return e.PREVIOUS=i.subarray(e.PREINDEX*c,(e.PREINDEX+1)*c),e.NEXT=i.subarray(e.NEXTINDEX*c,(e.NEXTINDEX+1)*c),e},_getCubicSpline(e,t,s,r){const n=t.INTERPOLATION,i=s[t.PREINDEX],a=s[t.NEXTINDEX];for(let s=0;s<3;s++){const o=t.PREVIOUS[r+s],f=(a-i)*t.PREVIOUS[2*r+s],u=t.NEXT[3+s],h=(a-i)*t.NEXT[s],c=(2*Math.pow(n,3)-3*Math.pow(n,2)+1)*o+(Math.pow(n,3)-2*Math.pow(n,2)+n)*f+(2*-Math.pow(n,3)+3*Math.pow(n,2))*u+(Math.pow(n,3)-Math.pow(n,2))*h;e[s]=c;}return e},getAnimationClip(e,t,s,r){const n=e.nodes[t]&&e.nodes[t].weights;return o(H,...W.TRANSLATION),h(j,...W.ROTATION),o(z,...W.SCALE),this._getTRSW(r,e,t,s,H,j,z,n)},getTimeSpan(e){if(!e.animations)return null;if(e.timeSpan)return e.timeSpan;const t=e.animations;return e.timeSpan={},t.forEach(((t,s)=>{let r=-1/0,n=1/0;const i=t.channels;for(let e=0;e<i.length;e++){const s=i[e],a=t.samplers[s.sampler].input.array;a[a.length-1]>r&&(r=a[a.length-1]),a[0]<n&&(n=a[0]);}const a=t.name||s;e.timeSpan[a]={max:r,min:n};})),e.timeSpan},getTimeSpanByName(e,t){const s=this.getTimeSpan(e);return s?b(t)?s[t]:s[Object.keys(s)[0]]:null}};let $=!1;if("undefined"!=typeof OffscreenCanvas){let e;try{e=new OffscreenCanvas(2,2).getContext("2d");}catch(s){}e&&"undefined"!=typeof createImageBitmap&&($=!0);}const J="undefined"==typeof document?null:document.createElement("canvas");function Q(e,t,s){const r=new Image;r.crossOrigin="",r.onload=()=>{if(!J)return void s(new Error("There is no canvas to draw image!"));J.width=r.width,J.height=r.height;const e=J.getContext("2d",{willReadFrequently:!0});e.drawImage(r,0,0,r.width,r.height);const t=e.getImageData(0,0,r.width,r.height),n={width:r.width,height:r.height,data:new Uint8Array(t.data)};s(null,n);},r.onerror=function(e){s(e);},r.src=e;}const Z=[],ee=[],te=30;let se,re;function ne(e,t,s){se||(se=new OffscreenCanvas(2,2),re=se.getContext("2d",{willReadFrequently:!0}));let r=null;if(_(e))this.options.urlModifier&&(e=this.options.urlModifier(e)),Z.push([e,t,s,this]),ie();else {const t=new Blob([e]);r=createImageBitmap(t),r.then(ae.bind(this)).then((e=>{s(null,e);})).catch((e=>{console.warn(e),s(e);}));}}function ie(){if(!Z.length||ee.length>te)return;const e=Z.shift(),[t,s,r,n]=e;ee.push(e),fetch(t,s).then((e=>e.arrayBuffer())).then((e=>{const t=new Blob([new Uint8Array(e)]);return createImageBitmap(t)})).then(ae.bind(n)).then((t=>{r.call(n,null,t);const s=ee.indexOf(e);ee.splice(s,1),ie();})).catch((t=>{console.warn(t),r.call(n,t);const s=ee.indexOf(e);ee.splice(s,1),ie();}));}function ae(e){let{width:t,height:s}=e;oe(t)||(t=fe(t)),oe(s)||(s=fe(s));const r=this.options.maxTextureSize;r&&(t=Math.min(r,t),s=Math.min(r,s)),se.width=t,se.height=s,re.drawImage(e,0,0,t,s),e.close();const n=re.getImageData(0,0,t,s);return {width:t,height:s,data:new Uint8Array(n.data)}}function oe(e){return !(e&e-1)&&0!==e}function fe(e){return Math.pow(2,Math.floor(Math.log(e)/Math.LN2))}function ue(e,t){for(const s in e)if(e[s]===t)return s;return t}e.Ajax=P,e.GLTFLoader=class{constructor(e,t,s){if(this.options=s||{},this.options.decoders||(this.options.decoders={}),this._fetchOptions=this.options.fetchOptions||{},t.buffer instanceof ArrayBuffer){const{json:s,glbBuffer:r}=k.read(t.buffer,t.byteOffset,t.byteLength);this._init(e,s,r);}else this._init(e,t);this._accessor=new L(this.rootPath,this.gltf,this.glbBuffer,this._fetchOptions,this.options.urlModifier),this._checkExtensions();}_checkExtensions(){const e=this.gltf.extensionsRequired;if(e){if(e.indexOf("KHR_draco_mesh_compression")>=0&&!this.options.decoders.draco)throw new Error("KHR_draco_mesh_compression is required but @maptalks/transcoders.draco is not loaded");if(e.indexOf("KHR_texture_basisu")>=0&&!this.options.decoders["image/ktx2"])throw new Error("KHR_texture_basisu is required but @maptalks/transcoders.ktx2 is not loaded");if(e.indexOf("EXT_meshopt_compression")>=0)throw new Error("EXT_meshopt_compression extension is not supported yet.")}}_loadExtensions(){const e=this.gltf.extensions;return e&&e.KHR_techniques_webgl?this._accessor.requestKHRTechniquesWebgl(e.KHR_techniques_webgl).then((t=>(e.KHR_techniques_webgl=t,e))):Promise.resolve(e)}_convertKhrTechiqueToTechiques(){if(!Array.isArray(this.gltf.programs))return;const e=this.gltf.materials;for(let t=0;t<e.length;t++)e[t]&&e[t].extensions&&e[t].extensions.KHR_technique_webgl&&(e[t].extensions.KHR_techniques_webgl=e[t].extensions.KHR_technique_webgl,delete e[t].extensions.KHR_technique_webgl);const t=this.gltf.extensions||{},s=this.gltf.techniques;t.KHR_techniques_webgl={programs:this.gltf.programs,shaders:this.gltf.shaders,techniques:s};for(let t=0;t<e.length;t++){const n=(r=e[t])&&r.extensions&&r.extensions.KHR_techniques_webgl;if(n){const{values:e,technique:t}=n,r=s[t];if(!r||!e)continue;const{uniforms:i,parameters:a}=r,o={};for(const t in e){const s=ue(i,t);o[s]=e[t],a[t]&&35678===a[t].type&&(o[s]={index:e[t]});}n.values=o;}}var r;for(let e=0;e<s.length;e++){const t=s[e];if(!t)continue;const{attributes:r,uniforms:n,parameters:i}=t;if(r)for(const e in r){const t=r[e];r[e]=i[t];}if(n)for(const e in n){const t=n[e];n[e]=i[t];}delete t.parameters;}return delete this.gltf.programs,delete this.gltf.shaders,delete this.gltf.techniques,this.gltf.extensions=t,t}load(e){e=e||{},this._convertKhrTechiqueToTechiques();const t=this._loadScene(e),s=this._loadAnimations(),r=this._loadTextures(),n=this._loadExtensions();return Promise.all([t,s,r,n]).then((e=>(e[0].animations=e[1],e[0].textures=e[2],e[0].extensions=e[3],e[0].transferables=this.transferables||[],this.createChannelsMap(e[0]),e[0])))}createChannelsMap(e){const t=e.animations;if(t)for(let e=0;e<t.length;e++){const s=t[e];s.channelsMap={};for(let e=0;e<s.channels.length;e++){const t=s.channels[e];s.channelsMap[t.target.node]||(s.channelsMap[t.target.node]=[]),s.channelsMap[t.target.node].push(t);}}}getExternalResources(){const e=[];if(this.gltf){const{buffers:t,images:s}=this.gltf;for(let s=0;s<t.length;s++)t[s].uri&&t[s].uri.indexOf("data:application/octet-stream;base64")<0&&e.push({type:"buffer",uri:t[s].uri});for(let t=0;t<s.length;t++)s[t].uri&&s[t].uri.indexOf("data:image/")<0&&e.push({type:"image",uri:s[t].uri});}return e}static getAnimationClip(e,t,s,r){return Y.getAnimationClip(e,t,s,r)}static getAnimationTimeSpan(e,t){return Y.getTimeSpanByName(e,t)}static getTypedArrayCtor(e){return x(e)}static readInterleavedArray(e,t,s,r,n,i,a){return B(e,t,s,r,n,i,a)}_init(e,t,s){this.gltf=t,this.glbBuffer=s,this.version=t.asset?+t.asset.version:1,this.rootPath=e,this.buffers={},this.requests={},this.options.requestImage=$?ne.bind(this):this.options.requestImage||Q,this.options.transferable&&(this.transferables=[]),2===this.version?(this.adapter=new C(e,t,s,this.options.requestImage,this.options.decoders||{},this.options.supportedFormats||{},this._fetchOptions,this.options.urlModifier),this.adapter.iterate(((e,t,s)=>{t.id="buffer_"+s;}),"buffers"),this.adapter.iterate(((e,t,s)=>{t.id="image_"+s;}),"images"),this.adapter.iterate(((e,t,s)=>{t.id="accessor_"+s;}),"accessors")):(this.adapter=new D(e,t,s,this.options.requestImage,this.options.decoders||{},this.options.supportedFormats||{},this._fetchOptions,this.options.urlModifier),this.adapter.iterate(((e,t,s)=>{t.id="accessor_"+s;}),"accessors"),this.adapter.iterate(((e,t,s)=>{t.id="image_"+s;}),"images"));}_parseNodes(e,t){if(e.children&&e.children.length>0){if(!("number"==typeof(s=e.children[0])&&isFinite(s)||_(e.children[0])))return e;const r=e.children.map((e=>{const s=t[e];return s.nodeIndex=e,this._parseNodes(s,t)}));e.children=r;}var s;return e}_loadScene(e){return this._loadNodes(e).then((e=>{const t=this.scenes=[];let s;for(const t in e)e[t]=this._parseNodes(e[t],e),e[t].nodeIndex=Number(t)?Number(t):t;this.adapter.iterate(((r,n,i)=>{const a={};n.name&&(a.name=n.name),n.nodes&&(a.nodes=n.nodes.map((t=>e[t]))),this.gltf.scene===r&&(s=i),t.push(a);}),"scenes");const r={textures:this.gltf.textures,asset:this.gltf.asset,scene:s,scenes:t,nodes:e,meshes:this.meshes,materials:this.gltf.materials,skins:this.skins,extensionsRequired:this.gltf.extensionsRequired,extensionsUsed:this.gltf.extensionsUsed};if(this.gltf.extensions&&(r.extensions=this.gltf.extensions),1===this.version){const e=this.adapter._loadMaterials(this.gltf.materials);r.materials=e;}return delete this.gltf.buffers,r.json=this.gltf,r}))}_loadNodes(e){return this._loadMeshes(e).then((()=>{const e=this.nodes={};return this.adapter.iterate(((t,s)=>{const r=this.adapter.createNode(s,this.meshes,this.skins);e[t]=r;}),"nodes"),e}))}_loadSkins(){this.skins=[];const e=[];return this.adapter.iterate(((t,s,r)=>{e.push(this._loadSkin(s).then((e=>{e.index=r,this.skins.push(e);})));}),"skins"),e}_loadSkin(e){const t=e.inverseBindMatrices;return this.adapter.accessor._requestData("inverseBindMatrices",t).then((t=>(e.inverseBindMatrices=t,t&&t.buffer&&this.transferables&&this.transferables.indexOf(t.buffer)<0&&this.transferables.push(t.buffer),e)))}_loadAnimations(){const e=this.gltf.animations;return b(e)?this.adapter.getAnimations(e):null}_loadMeshes(e){this.meshes={};let t=[];return this.adapter.iterate(((s,r,n)=>{t.push(this._loadMesh(r,e).then((e=>{e.index=n,this.meshes[s]=e;})));}),"meshes"),t=t.concat(this._loadSkins()),Promise.all(t)}_loadMesh(e,t){const s=e.primitives.map((e=>this._loadPrimitive(e,t))).filter((e=>!!e));return Promise.all(s).then((t=>{const s={};return y(s,e),s.primitives=t,s}))}_loadTextures(){const e=this.gltf.textures;if(!e)return null;const t=[];for(const s in e)t.push(this.adapter._getTexture(s));return Promise.all(t).then((t=>{if(this.transferables)for(let e=0;e<t.length;e++){const s=t[e]&&t[e].image.array;if(s){let e;e=s instanceof ImageBitmap?s:s.buffer,e&&this.transferables.indexOf(e)<0&&this.transferables.push(e);}}if(!Array.isArray(e)){const s={},r=Object.keys(e);for(let e=0;e<t.length;e++)t[e]&&(s[r[e]]=t[e]);return s}return t}))}_loadPrimitive(e,t){let s;const r=[],n=e.extensions;if(b(e.targets))for(let t=0;t<e.targets.length;t++){const s=e.targets[t];for(const e in s){const n=this.adapter.accessor._requestData(`morphTargets_${e}_${t}`,s[e]);n&&r.push(n);}}if(n&&n.KHR_draco_mesh_compression){if(!this.options.decoders.draco&&(!this.gltf.extensionsRequired||!this.gltf.extensionsRequired.indexOf("KHR_draco_mesh_compression")<0))return null;const e=this.options.decoders.draco,{bufferView:i,attributes:a}=n.KHR_draco_mesh_compression,o=this.gltf.bufferViews[i],f=this._accessor._requestBufferOfBufferView(o).then((s=>{const{buffer:r,byteOffset:n}=s;let{byteOffset:i}=o;const f=o.byteLength;i||(i=0);const u=new DataView(r,n+i,f),h={attributes:a,useUniqueIDs:!1,skipAttributeTransform:t.skipAttributeTransform};return e(u,h).then((e=>{const t=Object.values(e.attributes);return e.indices&&t.push(e.indices),t}))}));r.push(f),s=Promise.all(r);}else {const t=e.attributes;for(const e in t){const s=this.adapter.accessor._requestData(e,t[e]);s&&r.push(s);}if(b(e.indices)){const t=this.adapter.accessor._requestData("indices",e.indices);t&&r.push(t);}s=Promise.all(r);}return s.then((t=>{if(n&&n.KHR_draco_mesh_compression){const s=e.targets?e.targets.length:0;t[s]=t[s].concat(t.slice(0,s)),t=t[s];}let s,r;const i={attributes:t.reduce(((e,t)=>{if("indices"===t.name)s=t;else if(t.name.indexOf("morphTargets_")>-1)r=r||{},r[t.name.slice(13)]=t;else {if(!("POSITION"!==t.name||t.min&&t.max)){const e=[1/0,1/0,1/0],s=[-1/0,-1/0,-1/0],{itemSize:r,array:n}=t,i=n.length/r;for(let t=0;t<i;t++)for(let i=0;i<r;i++){const a=t*r+i;n[a]<e[i]&&(e[i]=n[a]),n[a]>s[i]&&(s[i]=n[a]);}if(t.quantization){const r=t.quantization,n=r.range/(1<<r.quantizationBits),i=r.minValues;u(e,e,n),f(e,e,i),u(s,s,n),f(s,s,i);}t.min=e,t.max=s;}e[t.name]=t;}return this.transferables&&t.array.buffer&&this.transferables.indexOf(t.array.buffer)<0&&this.transferables.push(t.array.buffer),e}),{}),material:e.material};return s&&(i.indices=s),r&&(i.morphTargets=r),i.mode=b(e.mode)?e.mode:4,b(e.extras)&&(i.extras=e.extras),i}))}},t().maptalks_gltf_loader=e;}gltfLoaderExport({});
@@ -509,7 +509,7 @@ function hashCode(s) {
509
509
  * @param value - input value
510
510
  * @returns
511
511
  */
512
- function isPowerOfTwo(value) {
512
+ function isPowerOfTwo$1(value) {
513
513
  return (value & (value - 1)) === 0 && value !== 0;
514
514
  }
515
515
  /**
@@ -528,10 +528,10 @@ function floorPowerOfTwo(value) {
528
528
  function resizeFromArray(arr, width, height) {
529
529
  let newWidth = width;
530
530
  let newHeight = height;
531
- if (!isPowerOfTwo(width)) {
531
+ if (!isPowerOfTwo$1(width)) {
532
532
  newWidth = floorPowerOfTwo(width);
533
533
  }
534
- if (!isPowerOfTwo(height)) {
534
+ if (!isPowerOfTwo$1(height)) {
535
535
  newHeight = floorPowerOfTwo(height);
536
536
  }
537
537
  const imageData = new ImageData(new Uint8ClampedArray(arr), width, height);
@@ -558,7 +558,7 @@ function resizeFromArray(arr, width, height) {
558
558
  function resizeToPowerOfTwo(image, width, height) {
559
559
  if (isArray(image)) {
560
560
  image = image;
561
- if (!isPowerOfTwo(width) || !isPowerOfTwo(height)) {
561
+ if (!isPowerOfTwo$1(width) || !isPowerOfTwo$1(height)) {
562
562
  return resizeFromArray(image, width, height);
563
563
  }
564
564
  else {
@@ -566,15 +566,15 @@ function resizeToPowerOfTwo(image, width, height) {
566
566
  }
567
567
  }
568
568
  image = image;
569
- if (isPowerOfTwo(image.width) && isPowerOfTwo(image.height)) {
569
+ if (isPowerOfTwo$1(image.width) && isPowerOfTwo$1(image.height)) {
570
570
  return image;
571
571
  }
572
572
  width = image.width;
573
573
  height = image.height;
574
- if (!isPowerOfTwo(width)) {
574
+ if (!isPowerOfTwo$1(width)) {
575
575
  width = floorPowerOfTwo(width);
576
576
  }
577
- if (!isPowerOfTwo(height)) {
577
+ if (!isPowerOfTwo$1(height)) {
578
578
  height = floorPowerOfTwo(height);
579
579
  }
580
580
  const canvas = document.createElement('canvas');
@@ -625,7 +625,7 @@ var Util = /*#__PURE__*/Object.freeze({
625
625
  isInterleaved: isInterleaved,
626
626
  isNil: isNil$2,
627
627
  isNumber: isNumber$2,
628
- isPowerOfTwo: isPowerOfTwo,
628
+ isPowerOfTwo: isPowerOfTwo$1,
629
629
  isString: isString,
630
630
  isSupportVAO: isSupportVAO,
631
631
  isTextureDestroyed: isTextureDestroyed,
@@ -9554,7 +9554,7 @@ class Texture2D extends AbstractTexture {
9554
9554
  config.width = config.data.width;
9555
9555
  config.height = config.data.height;
9556
9556
  }
9557
- else if (!config.hdr && isArray(config.data) && (!isPowerOfTwo(config.width) || !isPowerOfTwo(config.height))) {
9557
+ else if (!config.hdr && isArray(config.data) && (!isPowerOfTwo$1(config.width) || !isPowerOfTwo$1(config.height))) {
9558
9558
  config.data = resizeToPowerOfTwo(config.data, config.width, config.height);
9559
9559
  config.width = config.data.width;
9560
9560
  config.height = config.data.height;
@@ -15724,663 +15724,671 @@ class GeometryResource {
15724
15724
  }
15725
15725
  }
15726
15726
 
15727
- let timespan = 0;
15728
-
15729
- const MAT4 = [];
15730
- const TEMP_VEC$1 = [];
15731
-
15732
- class GLTFPack {
15733
-
15734
- constructor(gltf, regl) {
15735
- this.gltf = gltf;
15736
- this.regl = regl;
15737
- this.geometries = [];
15738
- if (regl) {
15739
- this._emptyTexture = regl.texture({ width: 2, height: 2 });
15740
- }
15741
- }
15742
-
15743
- getMeshesInfo() {
15744
- if (!this.gltf) {
15745
- return null;
15746
- }
15747
- if (this.geometries.length) {
15748
- return this.geometries;
15749
- }
15750
- this._createTextures(this.gltf.textures);
15751
- this._createSkins(this.gltf.skins);
15752
- const nodes = this.gltf.scenes[0].nodes;
15753
- nodes.forEach((node) => {
15754
- this._parserNode(node, this.geometries);
15755
- });
15756
- this._checkBaseColorFactor();
15757
- return this.geometries;
15758
- }
15759
-
15760
- getGLTFBBox() {
15761
- if (!this.gltf) {
15762
- return null;
15763
- }
15764
- const geometries = this.geometries;
15765
- if (!geometries || !geometries.length) {
15766
- return null;
15767
- }
15768
- const min = [Infinity, Infinity, Infinity], max = [-Infinity, -Infinity, -Infinity];
15769
- for (let i = 0; i < geometries.length; i++) {
15770
- const bbox = geometries[i].bbox;
15771
- const bboxMin = bbox.min, bboxMax = bbox.max;
15772
- if (bboxMin[0] < min[0]) {
15773
- min[0] = bboxMin[0];
15774
- }
15775
- if (bboxMin[1] < min[1]) {
15776
- min[1] = bboxMin[1];
15777
- }
15778
- if (bboxMin[2] < min[2]) {
15779
- min[2] = bboxMin[2];
15780
- }
15781
-
15782
- if (bboxMax[0] > max[0]) {
15783
- max[0] = bboxMax[0];
15784
- }
15785
- if (bboxMax[1] > max[1]) {
15786
- max[1] = bboxMax[1];
15787
- }
15788
- if (bboxMax[2] > max[2]) {
15789
- max[2] = bboxMax[2];
15790
- }
15791
- }
15792
- return { min, max };
15793
- }
15794
-
15795
- _createSkins(skins) {
15796
- if (!skins) {
15797
- return;
15798
- }
15799
- this._skinMap = {};
15800
- for (let i = 0; i < skins.length; i++) {
15801
- const skin = skins[i];
15802
- skin.joints = skin.joints.map(j => this.gltf.nodes[j]);
15803
- this._skinMap[i] = new Skin(this.regl, skin.joints, skin.inverseBindMatrices.array);
15804
- delete skin.inverseBindMatrices;
15805
- }
15806
- }
15807
-
15808
- _createTextures(textures) {
15809
- if (!textures) {
15810
- return;
15811
- }
15812
- this._textureMap = {};
15813
- for (let i = 0; i < textures.length; i++) {
15814
- const texture = textures[i];
15815
- //避免重复创建纹理对象
15816
- if (!this._textureMap[i]) {
15817
- this._textureMap[i] = this._toTexture(texture);
15818
- //图像数据可能占有较大内存,在创建texture完成后可删除
15819
- delete texture.image;
15820
- }
15821
- }
15822
- }
15823
-
15824
- //所有baseColorFactor的alpha为0时,设置为1
15825
- _checkBaseColorFactor() {
15826
- if (!this._checkBaseColorFactorAlpha()) {
15827
- for (let i = 0; i < this.geometries.length; i++) {
15828
- const baseColorFactor = this.geometries[i].materialInfo['baseColorFactor'];
15829
- if (baseColorFactor && baseColorFactor[3] === 0) {
15830
- baseColorFactor[3] = 1;
15831
- }
15832
- }
15833
- }
15834
- }
15835
-
15836
- _checkBaseColorFactorAlpha() {
15837
- for (let i = 0; i < this.geometries.length; i++) {
15838
- const baseColorFactor = this.geometries[i].materialInfo['baseColorFactor'];
15839
- if (baseColorFactor && baseColorFactor[3] > 0) {
15840
- return true;
15841
- }
15842
- }
15843
- return false;
15844
- }
15845
-
15846
- dispose() {
15847
- if (this._emptyTexture) {
15848
- this._emptyTexture.destroy();
15849
- }
15850
- const geometries = this.getMeshesInfo();
15851
- if (!geometries) {
15852
- return;
15853
- }
15854
- geometries.forEach(g => {
15855
- g.geometry.dispose();
15856
- for (const m in g.materialInfo) {
15857
- const materialInfo = g.materialInfo[m];
15858
- //如果是texture对象,需要销毁,如果已经销毁过,不能再重复销毁
15859
- if (materialInfo && materialInfo.destroy && !materialInfo[KEY_DISPOSED]) {
15860
- materialInfo.destroy();
15861
- }
15862
- }
15863
- });
15864
- for (const index in this._textureMap) {
15865
- const tex = this._textureMap[index];
15866
- if (tex && tex.destroy && !tex[KEY_DISPOSED]) {
15867
- tex.destroy();
15868
- }
15869
- }
15870
- delete this.gltf;
15871
- }
15872
-
15873
- updateAnimation(time, loop, speed, animationName, startTime, nodeMatrixMap, skinMap, animationNodes) {
15874
- const json = this.gltf;
15875
- if (!json) {
15876
- return;
15877
- }
15878
- const gltf = getGLTFLoaderBundle();
15879
- timespan = json.animations ? gltf.GLTFLoader.getAnimationTimeSpan(json, animationName) : null;
15880
- //模型切换过快,会导致上一个模型有动画执行,当前模型没有动画数据,就出现timespan为null的情况
15881
- if (!timespan) {
15882
- return;
15883
- }
15884
- time = time - startTime;
15885
- let animTime = 0;
15886
- if (loop || (!loop && this._isFirstLoop(time, speed, animationName, startTime))) {
15887
- animTime = (time * speed * 0.001) % (timespan.max - timespan.min) + timespan.min;
15888
- } else {
15889
- animTime = time * speed * 0.001 + timespan.min;
15890
- }
15891
- json.scenes[0].nodes.forEach(node => {
15892
- this._updateNodeMatrix(animationName, animTime, node, null, nodeMatrixMap, animationNodes);
15893
- });
15894
- for (const index in this.gltf.nodes) {
15895
- const node = this.gltf.nodes[index];
15896
- const nodeMatrix = nodeMatrixMap[node.nodeIndex];
15897
- if (node.skin && nodeMatrix) {
15898
- const jointTexture = node.skin.update(nodeMatrix, nodeMatrixMap, skinMap[node.nodeIndex] && skinMap[node.nodeIndex].jointTexture);
15899
- if (!skinMap[node.nodeIndex]) {
15900
- skinMap[node.nodeIndex] = {
15901
- jointTextureSize: node.skin.jointTextureSize,
15902
- numJoints: node.skin.joints.length
15903
- };
15904
- }
15905
- skinMap[node.nodeIndex].jointTexture = jointTexture;
15906
- }
15907
- }
15908
- return;
15909
- }
15910
-
15911
- _isFirstLoop(time, speed, animationName, startTime) {
15912
- const json = this.gltf;
15913
- if (!startTime || !json) {
15914
- return true;
15915
- }
15916
- const gltf = getGLTFLoaderBundle();
15917
- timespan = json.animations ? gltf.GLTFLoader.getAnimationTimeSpan(json, animationName) : null;
15918
- return (time* speed * 0.001) / (timespan.max - timespan.min) < 1;
15919
- }
15920
-
15921
- hasSkinAnimation() {
15922
- return !!this._isAnimation;
15923
- }
15924
-
15925
- _updateNodeMatrix(animationName, time, node, parentNodeMatrix, nodeMatrixMap, animationNodes) {
15926
- const trs = node.trs;
15927
- if (trs) {
15928
- if (!animationNodes) {
15929
- this._updateNodeTRS(node, time, animationName);
15930
- } else if (animationNodes.indexOf(Number(node.nodeIndex)) > -1) {
15931
- this._updateNodeTRS(node, time, animationName);
15932
- }
15933
- }
15934
- if (parentNodeMatrix) {
15935
- nodeMatrixMap[node.nodeIndex] = mat4.multiply(nodeMatrixMap[node.nodeIndex] || [], parentNodeMatrix, node.matrix || node.trs.getMatrix());
15936
- } else {
15937
- nodeMatrixMap[node.nodeIndex] = mat4.copy(nodeMatrixMap[node.nodeIndex] || [], node.matrix || node.trs.getMatrix());
15938
- }
15939
- if (node.children) {
15940
- node.children.forEach(child => {
15941
- this._updateNodeMatrix(animationName, time, child, nodeMatrixMap[node.nodeIndex], nodeMatrixMap, animationNodes);
15942
- });
15943
- }
15944
- }
15945
-
15946
- _updateNodeTRS(node, time, animationName) {
15947
- const gltf = getGLTFLoaderBundle();
15948
- const animation = gltf.GLTFLoader.getAnimationClip(this.gltf, Number(node.nodeIndex), time, animationName);
15949
- if (animation.weights) {
15950
- this._updateMorph(node, animation.weights);
15951
- }
15952
- node.trs.update(animation);
15953
- }
15954
-
15955
- //更新morph的基本思路是,计算node下每一帧的weights,然后对weights排序,最后根据
15956
- //primitives[i].attributes.POSITION +
15957
- //weights[0] * primitives[i].targets[0].POSITION +
15958
- //weights[1] * primitives[i].targets[1].POSITION +
15959
- //weights[2] * primitives[i].targets[2].POSITION + ...
15960
- //方式去更新POSITION
15961
- //如果morphTargets数量超过8个,例如36个,由于shader中对attributes的数量有限制,每次丢到shader中的morphTargets按照gltf规范,数量为8
15962
- //需要实时计算这8个morphTarget的索引,来决定哪几个丢到shader中。
15963
- _updateMorph(node, weights) {
15964
- const length = weights.length;
15965
- if (!node.influencesList) {
15966
- node.influencesList = [];
15967
- for (let i = 0; i < length; i++) {
15968
- node.influencesList[i] = [i, 0];
15969
- }
15970
- }
15971
- const influences = node.influencesList;
15972
- for (let i = 0; i < influences.length; i++) {
15973
- const influence = influences[i];
15974
- influence[0] = i;
15975
- influence[1] = weights[i];
15976
- }
15977
- influences.sort(absNumericalSort);
15978
- const workInfluences = [];
15979
- for (let i = 0; i < 8; i++) {
15980
- workInfluences[i] = [i, 0];
15981
- }
15982
- for (let i = 0; i < 8; i++) {
15983
- if (i < length && influences[i][1]) {
15984
- workInfluences[i][0] = influences[i][0];
15985
- workInfluences[i][1] = influences[i][1];
15986
- } else {
15987
- workInfluences[i][0] = Number.MAX_SAFE_INTEGER;
15988
- workInfluences[i][1] = 0;
15989
- }
15990
- }
15991
- workInfluences.sort(numericalSort);
15992
- const geometries = node.geometries;
15993
- geometries.forEach(geometry => {
15994
- const morphTargets = geometry.properties.morphTargets;
15995
- for (let ii = 0; ii < 8; ii++) {
15996
- const influence = workInfluences[ii];
15997
- const index = influence[0];
15998
- const value = influence[1];
15999
- if (index !== Number.MAX_SAFE_INTEGER && value) {
16000
- geometry.updateData('POSITION' + ii, morphTargets['POSITION_' + index].array);
16001
- geometry.properties.morphWeights[ii] = value;
16002
- } else {
16003
- geometry.properties.morphWeights[ii] = 0;
16004
- }
16005
- }
16006
- });
16007
- }
16008
-
16009
-
16010
- _parserNode(node, geometries, parentNodeMatrix) {
16011
- if (node.isParsed) {
16012
- return;
16013
- }
16014
- node.nodeMatrix = node.nodeMatrix || mat4.identity([]);
16015
- node.localMatrix = node.localMatrix || mat4.identity([]);
16016
- if (node.matrix) {
16017
- node.trs = new TRS();
16018
- node.trs.decompose(node.matrix);
16019
- } else {
16020
- node.trs = new TRS(node.translation, node.rotation, node.scale);
16021
- }
16022
- node.localMatrix = node.trs.getMatrix();
16023
- if (parentNodeMatrix) {
16024
- mat4.multiply(node.nodeMatrix, parentNodeMatrix, node.matrix || node.localMatrix);
16025
- } else {
16026
- mat4.copy(node.nodeMatrix, node.matrix || node.localMatrix);
16027
- }
16028
- const nodeMatrix = node.nodeMatrix;
16029
- if (node.children) {
16030
- for (let i = 0; i < node.children.length; i++) {
16031
- const child = node.children[i];
16032
- this._parserNode(child, geometries, nodeMatrix);
16033
- }
16034
- }
16035
- if (defined(node.skin)) {
16036
- this._isAnimation = true;
16037
- const skin = node.skin;
16038
- node.trs = new TRS();
16039
- node.skin = this._skinMap[skin];
16040
- }
16041
-
16042
- if (defined(node.mesh)) {
16043
- const meshIndex = node.mesh;
16044
- node.mesh = this.gltf.meshes[meshIndex];
16045
- node.mesh.node = node;
16046
- node.geometries = node.geometries || [];
16047
- node.mesh.primitives.forEach(primitive => {
16048
- const materialInfo = this._createMaterialInfo(primitive.material);
16049
- const geometry = createGeometry(primitive, this.regl, materialInfo.occlusionTexture);
16050
- geometry.properties.morphTargets = primitive.morphTargets;
16051
- //一个node下可能有多个geometry, node附带的weights会影响其下辖的所有geometry的morph变形结果,这里保存
16052
- //geometries,方便后面morph的运算
16053
- node.geometries.push(geometry);
16054
- let bbox = geometry.boundingBox.copy();
16055
- bbox = bbox.transform(mat4.identity(MAT4), nodeMatrix);
16056
- const info = {
16057
- geometry,
16058
- bbox,
16059
- nodeMatrix,
16060
- materialInfo,
16061
- extraInfo: this._createExtralInfo(primitive.material),
16062
- animationMatrix : node.trs.getMatrix(),
16063
- morphWeights: node.weights,
16064
- nodeIndex: node.nodeIndex
16065
- };
16066
- if (node.skin) {
16067
- info.skin = {
16068
- jointTextureSize: [4, 6],
16069
- numJoints: node.skin.joints.length,
16070
- jointTexture: node.skin.jointTexture
16071
- };
16072
- }
16073
- const resource = new GeometryResource(info);
16074
- geometries.push(resource);
16075
- });
16076
- }
16077
- node.isParsed = true;
16078
- }
16079
-
16080
- _createMaterialInfo(materialIndex) {
16081
- const materialUniforms = {
16082
- };
16083
- if (this.gltf.materials && this.gltf.materials[materialIndex]) {
16084
- const material = this.gltf.materials[materialIndex];
16085
- const pbrMetallicRoughness = material.pbrMetallicRoughness;
16086
- if (pbrMetallicRoughness) {
16087
- const metallicRoughnessTexture = pbrMetallicRoughness.metallicRoughnessTexture;
16088
- const baseColorTexture = pbrMetallicRoughness.baseColorTexture;
16089
- if (baseColorTexture) {
16090
- materialUniforms['baseColorTexture'] = this._getTexture(baseColorTexture);
16091
- if (baseColorTexture['KHR_texture_transform']) {
16092
- materialUniforms['khr_offset'] = baseColorTexture['KHR_texture_transform'].offset || [0, 0];
16093
- materialUniforms['khr_rotation'] = baseColorTexture['KHR_texture_transform'].rotation ||0;
16094
- materialUniforms['khr_scale'] = baseColorTexture['KHR_texture_transform'].scale || [1, 1];
16095
- }
16096
- }
16097
- if (pbrMetallicRoughness.baseColorFactor) {
16098
- materialUniforms['baseColorFactor'] = pbrMetallicRoughness.baseColorFactor;
16099
- }
16100
- if (metallicRoughnessTexture) {
16101
- materialUniforms['metallicRoughnessTexture'] = this._getTexture(metallicRoughnessTexture);
16102
- } else {
16103
- materialUniforms['metallicFactor'] = defined(pbrMetallicRoughness.metallicFactor) ? pbrMetallicRoughness.metallicFactor : 1.0;
16104
- materialUniforms['roughnessFactor'] = defined(pbrMetallicRoughness.roughnessFactor) ? pbrMetallicRoughness.roughnessFactor : 1.0;
16105
- }
16106
- }
16107
- const extensions = material.extensions;
16108
- if (extensions && extensions['KHR_materials_pbrSpecularGlossiness']) {
16109
- const pbrSpecularGlossiness = extensions['KHR_materials_pbrSpecularGlossiness'];
16110
- materialUniforms.name = 'pbrSpecularGlossiness';
16111
- for (const p in pbrSpecularGlossiness) {
16112
- if (defined(pbrSpecularGlossiness[p].index)) {
16113
- materialUniforms[p] = this._getTexture(pbrSpecularGlossiness[p]);
16114
- } else {
16115
- materialUniforms[p] = pbrSpecularGlossiness[p];
16116
- }
16117
- }
16118
- }
16119
- if (material.normalTexture) {
16120
- materialUniforms['normalTexture'] = this._getTexture(material.normalTexture);
16121
- }
16122
- if (material.occlusionTexture) {
16123
- materialUniforms['occlusionTexture'] = this._getTexture(material.occlusionTexture);
16124
- }
16125
- if (material.emissiveTexture) {
16126
- materialUniforms['emissiveTexture'] = this._getTexture(material.emissiveTexture);
16127
- }
16128
- if (material.emissiveFactor) {
16129
- materialUniforms['emissiveFactor'] = material.emissiveFactor;
16130
- }
16131
- materialUniforms['alphaCutoff'] = material.alphaCutoff || 0.5;
16132
- materialUniforms['doubleSided'] = material.doubleSided;
16133
- materialUniforms['alphaMode'] = material.alphaMode || 'OPAQUE';
16134
- }
16135
- return materialUniforms;
16136
- }
16137
-
16138
- _createExtralInfo(material) {
16139
- const info = {};
16140
- if (this.gltf.materials && this.gltf.materials[material]) {
16141
- const mat = this.gltf.materials[material];
16142
- info['doubleSided'] = mat.doubleSided;
16143
- info['alphaMode'] = mat.alphaMode || 'OPAQUE';
16144
- }
16145
- return info;
16146
- }
16147
-
16148
- _getTexture(texInfo) {
16149
- const extensions = texInfo.extensions;
16150
- const index = texInfo.index;
16151
- if (!defined(index)) {
16152
- return null;
16153
- }
16154
- if (extensions && extensions['KHR_texture_transform']) {
16155
- texInfo['KHR_texture_transform'] = extensions['KHR_texture_transform'];
16156
- }
16157
- const texture = this._textureMap[index];
16158
- texture.texInfo = texInfo;
16159
- return texture;
16160
- }
16161
-
16162
- _toTexture(texture) {
16163
- if (!texture) {
16164
- // empty texture
16165
- return this._emptyTexture;
16166
- }
16167
- const data = texture.image.array;
16168
- const sampler = texture.sampler || {};
16169
- const width = texture.image.width;
16170
- const height = texture.image.height;
16171
- return new Texture2D({
16172
- width,
16173
- height,
16174
- data,
16175
- mag: getTextureMagFilter(sampler.magFilter) || 'linear',
16176
- min: getTextureMinFilter(sampler.minFilter) || 'linear mipmap linear',
16177
- wrapS: getTextureWrap(sampler.wrapS) || 'repeat',
16178
- wrapT: getTextureWrap(sampler.wrapT) || 'repeat'
16179
- });
16180
- }
16181
-
16182
- /**
16183
- *
16184
- * @param map
16185
- * @param from
16186
- * @param to
16187
- * @param dist
16188
- * @param rotationZ 模型绕Z轴旋转角度,弧度
16189
- * @param rotationXY 模型绕Z轴与线段的交叉轴的旋转角度,弧度
16190
- * @param gltfScale
16191
- * @param projectionScale
16192
- * @param options
16193
- * @returns
16194
- */
16195
- arrangeAlongLine(from, to, xyDist, gltfScale, projectionScale, options) {
16196
- const items = [];
16197
- const rotationZ = this._getRotationZ(from, to);
16198
- // cm to mi
16199
- const zDist = (from.z || 0) - (to.z || 0);
16200
- const rotationXY = this._getRotationXY(xyDist, zDist);
16201
- let boxWidth = this._calBoxWidth(gltfScale, options);
16202
- boxWidth /= projectionScale;
16203
- const distance = Math.sqrt(xyDist * xyDist + zDist * zDist);
16204
- const times = Math.floor(distance / boxWidth);
16205
- let scaleIndex = (options.direction || 0);
16206
- // scale的scaleIndex已经是Y_UP后的模型,所以和direction不同
16207
- if (scaleIndex === 1) {
16208
- scaleIndex = 2;
16209
- } else if (scaleIndex === 2) {
16210
- scaleIndex = 1;
16211
- }
16212
- //取余缩放
16213
- if (times >= 1) {
16214
- for (let i = 1; i <= times; i++) {
16215
- const t = boxWidth * (i - 0.5) / distance;
16216
- const item = {
16217
- coordinates: interpolate(from, to, t),
16218
- t,
16219
- scale: [1, 1, 1],
16220
- rotation: [0, 0, rotationZ],
16221
- rotationZ,
16222
- rotationXY
16223
- };
16224
- items.push(item);
16225
- }
16226
- //尾巴
16227
- if (options['scaleVertex']) {
16228
- const t = (boxWidth * times + (distance - boxWidth * times) / 2) / distance;
16229
- const scale = (distance - boxWidth * times) / boxWidth;
16230
- const itemScale = [1, 1, 1];
16231
- itemScale[scaleIndex] = scale;
16232
- const item = {
16233
- coordinates: interpolate(from, to, t),
16234
- t,
16235
- scale: itemScale,
16236
- rotation: [0, 0, rotationZ],
16237
- rotationZ,
16238
- rotationXY
16239
- };
16240
- items.push(item);
16241
- }
16242
- } else if (options['scaleVertex']) {
16243
- const scale = distance / boxWidth;
16244
- const itemScale = [1, 1, 1];
16245
- itemScale[scaleIndex] = scale;
16246
- const item = {
16247
- coordinates: interpolate(from, to, 0.5),
16248
- t: 0.5,
16249
- scale: itemScale,
16250
- rotation: [0, 0, rotationZ],
16251
- rotationZ,
16252
- rotationXY
16253
- };
16254
- items.push(item);
16255
- }
16256
- return items;
16257
- }
16258
-
16259
- calModelHeightScale(out, modelHeight) {
16260
- const bbox = this.getGLTFBBox();
16261
- const fitScale = modelHeight / (Math.abs(bbox.max[1] - bbox.min[1]));//YZ轴做了翻转,所以需要用y方向来算高度比例
16262
- return vec3.set(out, fitScale, fitScale, fitScale);
16263
- }
16264
-
16265
- _calBoxWidth(scale, options) {
16266
- const gltfmodelBBox = this.getGLTFBBox();
16267
- const direction = options.direction || 0;
16268
- const boxExtent = vec3.sub(TEMP_VEC$1, gltfmodelBBox.max, gltfmodelBBox.min);
16269
- vec3.multiply(boxExtent, boxExtent, scale);
16270
- const gapLength = options['gapLength'];
16271
- return boxExtent[direction] + gapLength;
16272
- }
16273
-
16274
- _getRotationZ(from, to) {
16275
- const degree = computeDegree(
16276
- to.x, to.y,
16277
- from.x, from.y
16278
- );
16279
- return degree / Math.PI * 180;
16280
- }
16281
-
16282
- _getRotationXY(xyDist, zDist) {
16283
- const rotation = Math.atan(zDist / xyDist) * 180 / Math.PI;
16284
- return rotation;
16285
- }
16286
- }
16287
-
16288
- function createGeometry(primitive, regl, hasAOMap) {
16289
- const attributes = primitive.attributes;
16290
- const aColor0 = attributes['COLOR_0'];
16291
- //将float类型的颜色值转为0-255的uint8类型
16292
- if (aColor0 && aColor0.array instanceof Float32Array) {
16293
- const color = new Uint8Array(aColor0.array.length);
16294
- for (let i = 0; i < color.length; i++) {
16295
- color[i] = Math.round(aColor0.array[i] * 255);
16296
- }
16297
- aColor0.array = color;
16298
- } else if (aColor0 && (aColor0.array instanceof Uint16Array ||
16299
- aColor0.array instanceof Int16Array ||
16300
- aColor0.array instanceof Uint32Array ||
16301
- aColor0.array instanceof Int32Array)) {
16302
- const color = new Uint8Array(aColor0.array);
16303
- aColor0.array = color;
16304
- }
16305
- if (hasAOMap && attributes['TEXCOORD_0'] && !attributes['TEXCOORD_0']) {
16306
- attributes['TEXCOORD_1'] = attributes['TEXCOORD_0'];
16307
- }
16308
- const attrs = {};
16309
- for (const name in attributes) {
16310
- // 把原有的array赋给attr,用于计算 bbox、buildUniqueVertex
16311
- attrs[name] = extend$1({}, attributes[name]);
16312
- if (regl) {
16313
- attrs[name].buffer = getUniqueREGLBuffer(regl, attributes[name], { dimension: attributes[name].itemSize });
16314
- }
16315
- }
16316
-
16317
- //如果有morph,需要预先填充morph空数据,动画开启后,会不断向这些空数据中填充morphTargets数据
16318
- if (primitive.morphTargets) {
16319
- const length = isInterleaved(attrs['POSITION']) ? attrs['POSITION'].itemSize * attrs['POSITION'].count : attrs['POSITION'].array.length;
16320
- for (let i = 0; i < 8; i++) {
16321
- if (!attrs[`POSITION${i}`]) {
16322
- attrs[`POSITION${i}`] = new Float32Array(length).fill(0);
16323
- }
16324
- }
16325
- for (let i = 0; i < 4; i++) {
16326
- const length = attrs['NORMAL'].array ? attrs['NORMAL'].array.length : attrs['NORMAL'].length;
16327
- if (!attrs[`NORMAL${i}`]) {
16328
- attrs[`NORMAL${i}`] = new Float32Array(length).fill(0);
16329
- }
16330
- }
16331
- }
16332
- let indices = primitive.indices;
16333
- if (indices && indices.bufferView === undefined && indices.array) {
16334
- indices = indices.array;
16335
- }
16336
- const modelGeometry = new Geometry(
16337
- attrs,
16338
- indices,
16339
- 0,
16340
- {
16341
- //绘制类型,例如 triangle strip, line等,根据gltf中primitive的mode来判断,默认是triangles
16342
- primitive : isNumber$2(primitive.mode) ? getPrimitive(primitive.mode) : primitive.mode,
16343
- positionAttribute: 'POSITION',
16344
- normalAttribute: 'NORMAL',
16345
- uv0Attribute: 'TEXCOORD_0',
16346
- uv1Attribute: 'TEXCOORD_1',
16347
- color0Attribute: 'COLOR_0'
16348
- }
16349
- );
16350
- if (primitive.morphTargets) {
16351
- modelGeometry.properties.morphWeights = [];
16352
- }
16353
- if (primitive.mode > 3 && !modelGeometry.data['NORMAL']) {
16354
- modelGeometry.createNormal('NORMAL');
16355
- }
16356
- return modelGeometry;
16357
- }
16358
-
16359
- function numericalSort(a, b) {
16360
- return a[ 0 ] - b[ 0 ];
16361
- }
16362
-
16363
- function absNumericalSort(a, b) {
16364
- return Math.abs(b[1]) - Math.abs(a[1]);
16365
- }
16366
-
16367
- function computeDegree(x0, y0, x1, y1) {
16368
- const dx = x1 - x0;
16369
- const dy = y1 - y0;
16370
- return Math.atan2(dy, dx);
16371
- }
16372
-
16373
- function interpolate(from, to, t) {
16374
- const x = lerp(from.x, to.x, t);
16375
- const y = lerp(from.y, to.y, t);
16376
- const z1 = from.z || 0;
16377
- const z2 = to.z || 0;
16378
- const z = lerp(z1, z2, t);
16379
- return new from.constructor(x, y, z);
16380
- }
16381
-
16382
- function lerp(a, b, t) {
16383
- return a + t * (b - a);
15727
+ const Y_TO_Z = [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1];
15728
+
15729
+ let timespan = 0;
15730
+
15731
+ const MAT4 = [];
15732
+ const TEMP_VEC$1 = [];
15733
+
15734
+ class GLTFPack {
15735
+
15736
+ constructor(gltf, regl) {
15737
+ this.gltf = gltf;
15738
+ this.regl = regl;
15739
+ this.geometries = [];
15740
+ if (regl) {
15741
+ this._emptyTexture = regl.texture({ width: 2, height: 2 });
15742
+ }
15743
+ }
15744
+
15745
+ getMeshesInfo() {
15746
+ if (!this.gltf) {
15747
+ return null;
15748
+ }
15749
+ if (this.geometries.length) {
15750
+ return this.geometries;
15751
+ }
15752
+ this._createTextures(this.gltf.textures);
15753
+ this._createSkins(this.gltf.skins);
15754
+ const nodes = this.gltf.scenes[0].nodes;
15755
+ nodes.forEach((node) => {
15756
+ this._parserNode(node, this.geometries);
15757
+ });
15758
+ this._checkBaseColorFactor();
15759
+ return this.geometries;
15760
+ }
15761
+
15762
+ getGLTFBBox(transform) {
15763
+ if (!this.gltf) {
15764
+ return null;
15765
+ }
15766
+ const geometries = this.geometries;
15767
+ if (!geometries || !geometries.length) {
15768
+ return null;
15769
+ }
15770
+ const min = [Infinity, Infinity, Infinity], max = [-Infinity, -Infinity, -Infinity];
15771
+ for (let i = 0; i < geometries.length; i++) {
15772
+ const bbox = geometries[i].bbox;
15773
+ const bboxMin = bbox.min, bboxMax = bbox.max;
15774
+ if (bboxMin[0] < min[0]) {
15775
+ min[0] = bboxMin[0];
15776
+ }
15777
+ if (bboxMin[1] < min[1]) {
15778
+ min[1] = bboxMin[1];
15779
+ }
15780
+ if (bboxMin[2] < min[2]) {
15781
+ min[2] = bboxMin[2];
15782
+ }
15783
+
15784
+ if (bboxMax[0] > max[0]) {
15785
+ max[0] = bboxMax[0];
15786
+ }
15787
+ if (bboxMax[1] > max[1]) {
15788
+ max[1] = bboxMax[1];
15789
+ }
15790
+ if (bboxMax[2] > max[2]) {
15791
+ max[2] = bboxMax[2];
15792
+ }
15793
+ }
15794
+ const bbox = new BoundingBox(min, max);
15795
+ if (transform) {
15796
+ bbox.transform(transform);
15797
+ }
15798
+
15799
+ return bbox;
15800
+ }
15801
+
15802
+ _createSkins(skins) {
15803
+ if (!skins) {
15804
+ return;
15805
+ }
15806
+ this._skinMap = {};
15807
+ for (let i = 0; i < skins.length; i++) {
15808
+ const skin = skins[i];
15809
+ skin.joints = skin.joints.map(j => this.gltf.nodes[j]);
15810
+ this._skinMap[i] = new Skin(this.regl, skin.joints, skin.inverseBindMatrices.array);
15811
+ delete skin.inverseBindMatrices;
15812
+ }
15813
+ }
15814
+
15815
+ _createTextures(textures) {
15816
+ if (!textures) {
15817
+ return;
15818
+ }
15819
+ this._textureMap = {};
15820
+ for (let i = 0; i < textures.length; i++) {
15821
+ const texture = textures[i];
15822
+ //避免重复创建纹理对象
15823
+ if (!this._textureMap[i]) {
15824
+ this._textureMap[i] = this._toTexture(texture);
15825
+ //图像数据可能占有较大内存,在创建texture完成后可删除
15826
+ delete texture.image;
15827
+ }
15828
+ }
15829
+ }
15830
+
15831
+ //所有baseColorFactor的alpha为0时,设置为1
15832
+ _checkBaseColorFactor() {
15833
+ if (!this._checkBaseColorFactorAlpha()) {
15834
+ for (let i = 0; i < this.geometries.length; i++) {
15835
+ const baseColorFactor = this.geometries[i].materialInfo['baseColorFactor'];
15836
+ if (baseColorFactor && baseColorFactor[3] === 0) {
15837
+ baseColorFactor[3] = 1;
15838
+ }
15839
+ }
15840
+ }
15841
+ }
15842
+
15843
+ _checkBaseColorFactorAlpha() {
15844
+ for (let i = 0; i < this.geometries.length; i++) {
15845
+ const baseColorFactor = this.geometries[i].materialInfo['baseColorFactor'];
15846
+ if (baseColorFactor && baseColorFactor[3] > 0) {
15847
+ return true;
15848
+ }
15849
+ }
15850
+ return false;
15851
+ }
15852
+
15853
+ dispose() {
15854
+ if (this._emptyTexture) {
15855
+ this._emptyTexture.destroy();
15856
+ }
15857
+ const geometries = this.getMeshesInfo();
15858
+ if (!geometries) {
15859
+ return;
15860
+ }
15861
+ geometries.forEach(g => {
15862
+ g.geometry.dispose();
15863
+ for (const m in g.materialInfo) {
15864
+ const materialInfo = g.materialInfo[m];
15865
+ //如果是texture对象,需要销毁,如果已经销毁过,不能再重复销毁
15866
+ if (materialInfo && materialInfo.destroy && !materialInfo[KEY_DISPOSED]) {
15867
+ materialInfo.destroy();
15868
+ }
15869
+ }
15870
+ });
15871
+ for (const index in this._textureMap) {
15872
+ const tex = this._textureMap[index];
15873
+ if (tex && tex.destroy && !tex[KEY_DISPOSED]) {
15874
+ tex.destroy();
15875
+ }
15876
+ }
15877
+ delete this.gltf;
15878
+ }
15879
+
15880
+ updateAnimation(time, loop, speed, animationName, startTime, nodeMatrixMap, skinMap, animationNodes) {
15881
+ const json = this.gltf;
15882
+ if (!json) {
15883
+ return;
15884
+ }
15885
+ const gltf = getGLTFLoaderBundle();
15886
+ timespan = json.animations ? gltf.GLTFLoader.getAnimationTimeSpan(json, animationName) : null;
15887
+ //模型切换过快,会导致上一个模型有动画执行,当前模型没有动画数据,就出现timespan为null的情况
15888
+ if (!timespan) {
15889
+ return;
15890
+ }
15891
+ time = time - startTime;
15892
+ let animTime = 0;
15893
+ if (loop || (!loop && this._isFirstLoop(time, speed, animationName, startTime))) {
15894
+ animTime = (time * speed * 0.001) % (timespan.max - timespan.min) + timespan.min;
15895
+ } else {
15896
+ animTime = time * speed * 0.001 + timespan.min;
15897
+ }
15898
+ json.scenes[0].nodes.forEach(node => {
15899
+ this._updateNodeMatrix(animationName, animTime, node, null, nodeMatrixMap, animationNodes);
15900
+ });
15901
+ for (const index in this.gltf.nodes) {
15902
+ const node = this.gltf.nodes[index];
15903
+ const nodeMatrix = nodeMatrixMap[node.nodeIndex];
15904
+ if (node.skin && nodeMatrix) {
15905
+ const jointTexture = node.skin.update(nodeMatrix, nodeMatrixMap, skinMap[node.nodeIndex] && skinMap[node.nodeIndex].jointTexture);
15906
+ if (!skinMap[node.nodeIndex]) {
15907
+ skinMap[node.nodeIndex] = {
15908
+ jointTextureSize: node.skin.jointTextureSize,
15909
+ numJoints: node.skin.joints.length
15910
+ };
15911
+ }
15912
+ skinMap[node.nodeIndex].jointTexture = jointTexture;
15913
+ }
15914
+ }
15915
+ return;
15916
+ }
15917
+
15918
+ _isFirstLoop(time, speed, animationName, startTime) {
15919
+ const json = this.gltf;
15920
+ if (!startTime || !json) {
15921
+ return true;
15922
+ }
15923
+ const gltf = getGLTFLoaderBundle();
15924
+ timespan = json.animations ? gltf.GLTFLoader.getAnimationTimeSpan(json, animationName) : null;
15925
+ return (time* speed * 0.001) / (timespan.max - timespan.min) < 1;
15926
+ }
15927
+
15928
+ hasSkinAnimation() {
15929
+ return !!this._isAnimation;
15930
+ }
15931
+
15932
+ _updateNodeMatrix(animationName, time, node, parentNodeMatrix, nodeMatrixMap, animationNodes) {
15933
+ const trs = node.trs;
15934
+ if (trs) {
15935
+ if (!animationNodes) {
15936
+ this._updateNodeTRS(node, time, animationName);
15937
+ } else if (animationNodes.indexOf(Number(node.nodeIndex)) > -1) {
15938
+ this._updateNodeTRS(node, time, animationName);
15939
+ }
15940
+ }
15941
+ if (parentNodeMatrix) {
15942
+ nodeMatrixMap[node.nodeIndex] = mat4.multiply(nodeMatrixMap[node.nodeIndex] || [], parentNodeMatrix, node.matrix || node.trs.getMatrix());
15943
+ } else {
15944
+ nodeMatrixMap[node.nodeIndex] = mat4.copy(nodeMatrixMap[node.nodeIndex] || [], node.matrix || node.trs.getMatrix());
15945
+ }
15946
+ if (node.children) {
15947
+ node.children.forEach(child => {
15948
+ this._updateNodeMatrix(animationName, time, child, nodeMatrixMap[node.nodeIndex], nodeMatrixMap, animationNodes);
15949
+ });
15950
+ }
15951
+ }
15952
+
15953
+ _updateNodeTRS(node, time, animationName) {
15954
+ const gltf = getGLTFLoaderBundle();
15955
+ const animation = gltf.GLTFLoader.getAnimationClip(this.gltf, Number(node.nodeIndex), time, animationName);
15956
+ if (animation.weights) {
15957
+ this._updateMorph(node, animation.weights);
15958
+ }
15959
+ node.trs.update(animation);
15960
+ }
15961
+
15962
+ //更新morph的基本思路是,计算node下每一帧的weights,然后对weights排序,最后根据
15963
+ //primitives[i].attributes.POSITION +
15964
+ //weights[0] * primitives[i].targets[0].POSITION +
15965
+ //weights[1] * primitives[i].targets[1].POSITION +
15966
+ //weights[2] * primitives[i].targets[2].POSITION + ...
15967
+ //方式去更新POSITION
15968
+ //如果morphTargets数量超过8个,例如36个,由于shader中对attributes的数量有限制,每次丢到shader中的morphTargets按照gltf规范,数量为8
15969
+ //需要实时计算这8个morphTarget的索引,来决定哪几个丢到shader中。
15970
+ _updateMorph(node, weights) {
15971
+ const length = weights.length;
15972
+ if (!node.influencesList) {
15973
+ node.influencesList = [];
15974
+ for (let i = 0; i < length; i++) {
15975
+ node.influencesList[i] = [i, 0];
15976
+ }
15977
+ }
15978
+ const influences = node.influencesList;
15979
+ for (let i = 0; i < influences.length; i++) {
15980
+ const influence = influences[i];
15981
+ influence[0] = i;
15982
+ influence[1] = weights[i];
15983
+ }
15984
+ influences.sort(absNumericalSort);
15985
+ const workInfluences = [];
15986
+ for (let i = 0; i < 8; i++) {
15987
+ workInfluences[i] = [i, 0];
15988
+ }
15989
+ for (let i = 0; i < 8; i++) {
15990
+ if (i < length && influences[i][1]) {
15991
+ workInfluences[i][0] = influences[i][0];
15992
+ workInfluences[i][1] = influences[i][1];
15993
+ } else {
15994
+ workInfluences[i][0] = Number.MAX_SAFE_INTEGER;
15995
+ workInfluences[i][1] = 0;
15996
+ }
15997
+ }
15998
+ workInfluences.sort(numericalSort);
15999
+ const geometries = node.geometries;
16000
+ geometries.forEach(geometry => {
16001
+ const morphTargets = geometry.properties.morphTargets;
16002
+ for (let ii = 0; ii < 8; ii++) {
16003
+ const influence = workInfluences[ii];
16004
+ const index = influence[0];
16005
+ const value = influence[1];
16006
+ if (index !== Number.MAX_SAFE_INTEGER && value) {
16007
+ geometry.updateData('POSITION' + ii, morphTargets['POSITION_' + index].array);
16008
+ geometry.properties.morphWeights[ii] = value;
16009
+ } else {
16010
+ geometry.properties.morphWeights[ii] = 0;
16011
+ }
16012
+ }
16013
+ });
16014
+ }
16015
+
16016
+
16017
+ _parserNode(node, geometries, parentNodeMatrix) {
16018
+ if (node.isParsed) {
16019
+ return;
16020
+ }
16021
+ node.nodeMatrix = node.nodeMatrix || mat4.identity([]);
16022
+ node.localMatrix = node.localMatrix || mat4.identity([]);
16023
+ if (node.matrix) {
16024
+ node.trs = new TRS();
16025
+ node.trs.decompose(node.matrix);
16026
+ } else {
16027
+ node.trs = new TRS(node.translation, node.rotation, node.scale);
16028
+ }
16029
+ node.localMatrix = node.trs.getMatrix();
16030
+ if (parentNodeMatrix) {
16031
+ mat4.multiply(node.nodeMatrix, parentNodeMatrix, node.matrix || node.localMatrix);
16032
+ } else {
16033
+ mat4.copy(node.nodeMatrix, node.matrix || node.localMatrix);
16034
+ }
16035
+ const nodeMatrix = node.nodeMatrix;
16036
+ if (node.children) {
16037
+ for (let i = 0; i < node.children.length; i++) {
16038
+ const child = node.children[i];
16039
+ this._parserNode(child, geometries, nodeMatrix);
16040
+ }
16041
+ }
16042
+ if (defined(node.skin)) {
16043
+ this._isAnimation = true;
16044
+ const skin = node.skin;
16045
+ node.trs = new TRS();
16046
+ node.skin = this._skinMap[skin];
16047
+ }
16048
+
16049
+ if (defined(node.mesh)) {
16050
+ const meshIndex = node.mesh;
16051
+ node.mesh = this.gltf.meshes[meshIndex];
16052
+ node.mesh.node = node;
16053
+ node.geometries = node.geometries || [];
16054
+ node.mesh.primitives.forEach(primitive => {
16055
+ const materialInfo = this._createMaterialInfo(primitive.material);
16056
+ const geometry = createGeometry(primitive, this.regl, materialInfo.occlusionTexture);
16057
+ geometry.properties.morphTargets = primitive.morphTargets;
16058
+ //一个node下可能有多个geometry, node附带的weights会影响其下辖的所有geometry的morph变形结果,这里保存
16059
+ //geometries,方便后面morph的运算
16060
+ node.geometries.push(geometry);
16061
+ let bbox = geometry.boundingBox.copy();
16062
+ bbox = bbox.transform(mat4.identity(MAT4), nodeMatrix);
16063
+ const info = {
16064
+ geometry,
16065
+ bbox,
16066
+ nodeMatrix,
16067
+ materialInfo,
16068
+ extraInfo: this._createExtralInfo(primitive.material),
16069
+ animationMatrix : node.trs.getMatrix(),
16070
+ morphWeights: node.weights,
16071
+ nodeIndex: node.nodeIndex
16072
+ };
16073
+ if (node.skin) {
16074
+ info.skin = {
16075
+ jointTextureSize: [4, 6],
16076
+ numJoints: node.skin.joints.length,
16077
+ jointTexture: node.skin.jointTexture
16078
+ };
16079
+ }
16080
+ const resource = new GeometryResource(info);
16081
+ geometries.push(resource);
16082
+ });
16083
+ }
16084
+ node.isParsed = true;
16085
+ }
16086
+
16087
+ _createMaterialInfo(materialIndex) {
16088
+ const materialUniforms = {
16089
+ };
16090
+ if (this.gltf.materials && this.gltf.materials[materialIndex]) {
16091
+ const material = this.gltf.materials[materialIndex];
16092
+ const pbrMetallicRoughness = material.pbrMetallicRoughness;
16093
+ if (pbrMetallicRoughness) {
16094
+ const metallicRoughnessTexture = pbrMetallicRoughness.metallicRoughnessTexture;
16095
+ const baseColorTexture = pbrMetallicRoughness.baseColorTexture;
16096
+ if (baseColorTexture) {
16097
+ materialUniforms['baseColorTexture'] = this._getTexture(baseColorTexture);
16098
+ if (baseColorTexture['KHR_texture_transform']) {
16099
+ materialUniforms['khr_offset'] = baseColorTexture['KHR_texture_transform'].offset || [0, 0];
16100
+ materialUniforms['khr_rotation'] = baseColorTexture['KHR_texture_transform'].rotation ||0;
16101
+ materialUniforms['khr_scale'] = baseColorTexture['KHR_texture_transform'].scale || [1, 1];
16102
+ }
16103
+ }
16104
+ if (pbrMetallicRoughness.baseColorFactor) {
16105
+ materialUniforms['baseColorFactor'] = pbrMetallicRoughness.baseColorFactor;
16106
+ }
16107
+ if (metallicRoughnessTexture) {
16108
+ materialUniforms['metallicRoughnessTexture'] = this._getTexture(metallicRoughnessTexture);
16109
+ } else {
16110
+ materialUniforms['metallicFactor'] = defined(pbrMetallicRoughness.metallicFactor) ? pbrMetallicRoughness.metallicFactor : 1.0;
16111
+ materialUniforms['roughnessFactor'] = defined(pbrMetallicRoughness.roughnessFactor) ? pbrMetallicRoughness.roughnessFactor : 1.0;
16112
+ }
16113
+ }
16114
+ const extensions = material.extensions;
16115
+ if (extensions && extensions['KHR_materials_pbrSpecularGlossiness']) {
16116
+ const pbrSpecularGlossiness = extensions['KHR_materials_pbrSpecularGlossiness'];
16117
+ materialUniforms.name = 'pbrSpecularGlossiness';
16118
+ for (const p in pbrSpecularGlossiness) {
16119
+ if (defined(pbrSpecularGlossiness[p].index)) {
16120
+ materialUniforms[p] = this._getTexture(pbrSpecularGlossiness[p]);
16121
+ } else {
16122
+ materialUniforms[p] = pbrSpecularGlossiness[p];
16123
+ }
16124
+ }
16125
+ }
16126
+ if (material.normalTexture) {
16127
+ materialUniforms['normalTexture'] = this._getTexture(material.normalTexture);
16128
+ }
16129
+ if (material.occlusionTexture) {
16130
+ materialUniforms['occlusionTexture'] = this._getTexture(material.occlusionTexture);
16131
+ }
16132
+ if (material.emissiveTexture) {
16133
+ materialUniforms['emissiveTexture'] = this._getTexture(material.emissiveTexture);
16134
+ }
16135
+ if (material.emissiveFactor) {
16136
+ materialUniforms['emissiveFactor'] = material.emissiveFactor;
16137
+ }
16138
+ materialUniforms['alphaCutoff'] = material.alphaCutoff || 0.5;
16139
+ materialUniforms['doubleSided'] = material.doubleSided;
16140
+ materialUniforms['alphaMode'] = material.alphaMode || 'OPAQUE';
16141
+ }
16142
+ return materialUniforms;
16143
+ }
16144
+
16145
+ _createExtralInfo(material) {
16146
+ const info = {};
16147
+ if (this.gltf.materials && this.gltf.materials[material]) {
16148
+ const mat = this.gltf.materials[material];
16149
+ info['doubleSided'] = mat.doubleSided;
16150
+ info['alphaMode'] = mat.alphaMode || 'OPAQUE';
16151
+ }
16152
+ return info;
16153
+ }
16154
+
16155
+ _getTexture(texInfo) {
16156
+ const extensions = texInfo.extensions;
16157
+ const index = texInfo.index;
16158
+ if (!defined(index)) {
16159
+ return null;
16160
+ }
16161
+ if (extensions && extensions['KHR_texture_transform']) {
16162
+ texInfo['KHR_texture_transform'] = extensions['KHR_texture_transform'];
16163
+ }
16164
+ const texture = this._textureMap[index];
16165
+ texture.texInfo = texInfo;
16166
+ return texture;
16167
+ }
16168
+
16169
+ _toTexture(texture) {
16170
+ if (!texture) {
16171
+ // empty texture
16172
+ return this._emptyTexture;
16173
+ }
16174
+ const data = texture.image.array;
16175
+ const sampler = texture.sampler || {};
16176
+ const width = texture.image.width;
16177
+ const height = texture.image.height;
16178
+ return new Texture2D({
16179
+ width,
16180
+ height,
16181
+ data,
16182
+ mag: getTextureMagFilter(sampler.magFilter) || 'linear',
16183
+ min: getTextureMinFilter(sampler.minFilter) || 'linear mipmap linear',
16184
+ wrapS: getTextureWrap(sampler.wrapS) || 'repeat',
16185
+ wrapT: getTextureWrap(sampler.wrapT) || 'repeat'
16186
+ });
16187
+ }
16188
+
16189
+ /**
16190
+ *
16191
+ * @param map
16192
+ * @param from
16193
+ * @param to
16194
+ * @param dist
16195
+ * @param rotationZ 模型绕Z轴旋转角度,弧度
16196
+ * @param rotationXY 模型绕Z轴与线段的交叉轴的旋转角度,弧度
16197
+ * @param gltfScale
16198
+ * @param projectionScale
16199
+ * @param options
16200
+ * @returns
16201
+ */
16202
+ arrangeAlongLine(from, to, xyDist, gltfScale, projectionScale, rotationScaleMat, options) {
16203
+ const items = [];
16204
+ const rotationZ = this._getRotationZ(from, to);
16205
+ // cm to mi
16206
+ const zDist = (from.z || 0) - (to.z || 0);
16207
+ const rotationXY = this._getRotationXY(xyDist, zDist);
16208
+ let boxWidth = this._calBoxWidth(gltfScale, rotationScaleMat, options);
16209
+ boxWidth /= projectionScale;
16210
+ const distance = Math.sqrt(xyDist * xyDist + zDist * zDist);
16211
+ const times = Math.floor(distance / boxWidth);
16212
+ let scaleIndex = (options.direction || 0);
16213
+ // scale的scaleIndex已经是Y_UP后的模型,所以和direction不同
16214
+ if (scaleIndex === 1) {
16215
+ scaleIndex = 2;
16216
+ } else if (scaleIndex === 2) {
16217
+ scaleIndex = 1;
16218
+ }
16219
+ //取余缩放
16220
+ if (times >= 1) {
16221
+ for (let i = 1; i <= times; i++) {
16222
+ const t = boxWidth * (i - 0.5) / distance;
16223
+ const item = {
16224
+ coordinates: interpolate(from, to, t),
16225
+ t,
16226
+ scale: [1, 1, 1],
16227
+ rotation: [0, 0, rotationZ],
16228
+ rotationZ,
16229
+ rotationXY
16230
+ };
16231
+ items.push(item);
16232
+ }
16233
+ //尾巴
16234
+ if (options['scaleVertex']) {
16235
+ const t = (boxWidth * times + (distance - boxWidth * times) / 2) / distance;
16236
+ const scale = (distance - boxWidth * times) / boxWidth;
16237
+ const itemScale = [1, 1, 1];
16238
+ itemScale[scaleIndex] = scale;
16239
+ const item = {
16240
+ coordinates: interpolate(from, to, t),
16241
+ t,
16242
+ scale: itemScale,
16243
+ rotation: [0, 0, rotationZ],
16244
+ rotationZ,
16245
+ rotationXY
16246
+ };
16247
+ items.push(item);
16248
+ }
16249
+ } else if (options['scaleVertex']) {
16250
+ const scale = distance / boxWidth;
16251
+ const itemScale = [1, 1, 1];
16252
+ itemScale[scaleIndex] = scale;
16253
+ const item = {
16254
+ coordinates: interpolate(from, to, 0.5),
16255
+ t: 0.5,
16256
+ scale: itemScale,
16257
+ rotation: [0, 0, rotationZ],
16258
+ rotationZ,
16259
+ rotationXY
16260
+ };
16261
+ items.push(item);
16262
+ }
16263
+ return items;
16264
+ }
16265
+
16266
+ calModelHeightScale(out, modelHeight) {
16267
+ const bbox = this.getGLTFBBox();
16268
+ const fitScale = modelHeight / (Math.abs(bbox.max[1] - bbox.min[1]));//YZ轴做了翻转,所以需要用y方向来算高度比例
16269
+ return vec3.set(out, fitScale, fitScale, fitScale);
16270
+ }
16271
+
16272
+ _calBoxWidth(scale, rotationScaleMat, options) {
16273
+ const mat = mat4.multiply(MAT4, rotationScaleMat, Y_TO_Z);
16274
+ const gltfmodelBBox = this.getGLTFBBox(mat);
16275
+ const direction = options.direction || 0;
16276
+ const boxExtent = vec3.sub(TEMP_VEC$1, gltfmodelBBox.max, gltfmodelBBox.min);
16277
+ vec3.multiply(boxExtent, boxExtent, scale);
16278
+ const gapLength = options['gapLength'];
16279
+ return boxExtent[direction] + gapLength;
16280
+ }
16281
+
16282
+ _getRotationZ(from, to) {
16283
+ const degree = computeDegree(
16284
+ to.x, to.y,
16285
+ from.x, from.y
16286
+ );
16287
+ return degree / Math.PI * 180;
16288
+ }
16289
+
16290
+ _getRotationXY(xyDist, zDist) {
16291
+ const rotation = Math.atan(zDist / xyDist) * 180 / Math.PI;
16292
+ return rotation;
16293
+ }
16294
+ }
16295
+
16296
+ function createGeometry(primitive, regl, hasAOMap) {
16297
+ const attributes = primitive.attributes;
16298
+ const aColor0 = attributes['COLOR_0'];
16299
+ //将float类型的颜色值转为0-255的uint8类型
16300
+ if (aColor0 && aColor0.array instanceof Float32Array) {
16301
+ const color = new Uint8Array(aColor0.array.length);
16302
+ for (let i = 0; i < color.length; i++) {
16303
+ color[i] = Math.round(aColor0.array[i] * 255);
16304
+ }
16305
+ aColor0.array = color;
16306
+ } else if (aColor0 && (aColor0.array instanceof Uint16Array ||
16307
+ aColor0.array instanceof Int16Array ||
16308
+ aColor0.array instanceof Uint32Array ||
16309
+ aColor0.array instanceof Int32Array)) {
16310
+ const color = new Uint8Array(aColor0.array);
16311
+ aColor0.array = color;
16312
+ }
16313
+ if (hasAOMap && attributes['TEXCOORD_0'] && !attributes['TEXCOORD_0']) {
16314
+ attributes['TEXCOORD_1'] = attributes['TEXCOORD_0'];
16315
+ }
16316
+ const attrs = {};
16317
+ for (const name in attributes) {
16318
+ // 把原有的array赋给attr,用于计算 bbox、buildUniqueVertex
16319
+ attrs[name] = extend$1({}, attributes[name]);
16320
+ if (regl) {
16321
+ attrs[name].buffer = getUniqueREGLBuffer(regl, attributes[name], { dimension: attributes[name].itemSize });
16322
+ }
16323
+ }
16324
+
16325
+ //如果有morph,需要预先填充morph空数据,动画开启后,会不断向这些空数据中填充morphTargets数据
16326
+ if (primitive.morphTargets) {
16327
+ const length = isInterleaved(attrs['POSITION']) ? attrs['POSITION'].itemSize * attrs['POSITION'].count : attrs['POSITION'].array.length;
16328
+ for (let i = 0; i < 8; i++) {
16329
+ if (!attrs[`POSITION${i}`]) {
16330
+ attrs[`POSITION${i}`] = new Float32Array(length).fill(0);
16331
+ }
16332
+ }
16333
+ for (let i = 0; i < 4; i++) {
16334
+ const length = attrs['NORMAL'].array ? attrs['NORMAL'].array.length : attrs['NORMAL'].length;
16335
+ if (!attrs[`NORMAL${i}`]) {
16336
+ attrs[`NORMAL${i}`] = new Float32Array(length).fill(0);
16337
+ }
16338
+ }
16339
+ }
16340
+ let indices = primitive.indices;
16341
+ if (indices && indices.bufferView === undefined && indices.array) {
16342
+ indices = indices.array;
16343
+ }
16344
+ const modelGeometry = new Geometry(
16345
+ attrs,
16346
+ indices,
16347
+ 0,
16348
+ {
16349
+ //绘制类型,例如 triangle strip, line等,根据gltf中primitive的mode来判断,默认是triangles
16350
+ primitive : isNumber$2(primitive.mode) ? getPrimitive(primitive.mode) : primitive.mode,
16351
+ positionAttribute: 'POSITION',
16352
+ normalAttribute: 'NORMAL',
16353
+ uv0Attribute: 'TEXCOORD_0',
16354
+ uv1Attribute: 'TEXCOORD_1',
16355
+ color0Attribute: 'COLOR_0'
16356
+ }
16357
+ );
16358
+ if (primitive.morphTargets) {
16359
+ modelGeometry.properties.morphWeights = [];
16360
+ }
16361
+ if (primitive.mode > 3 && !modelGeometry.data['NORMAL']) {
16362
+ modelGeometry.createNormal('NORMAL');
16363
+ }
16364
+ return modelGeometry;
16365
+ }
16366
+
16367
+ function numericalSort(a, b) {
16368
+ return a[ 0 ] - b[ 0 ];
16369
+ }
16370
+
16371
+ function absNumericalSort(a, b) {
16372
+ return Math.abs(b[1]) - Math.abs(a[1]);
16373
+ }
16374
+
16375
+ function computeDegree(x0, y0, x1, y1) {
16376
+ const dx = x1 - x0;
16377
+ const dy = y1 - y0;
16378
+ return Math.atan2(dy, dx);
16379
+ }
16380
+
16381
+ function interpolate(from, to, t) {
16382
+ const x = lerp(from.x, to.x, t);
16383
+ const y = lerp(from.y, to.y, t);
16384
+ const z1 = from.z || 0;
16385
+ const z2 = to.z || 0;
16386
+ const z = lerp(z1, z2, t);
16387
+ return new from.constructor(x, y, z);
16388
+ }
16389
+
16390
+ function lerp(a, b, t) {
16391
+ return a + t * (b - a);
16384
16392
  }
16385
16393
 
16386
16394
  // options.fetchOptions
@@ -27770,7 +27778,7 @@ class TerrainLayerRenderer extends MaskRendererMixin(TileLayerRendererable$1(Lay
27770
27778
  const terrainWidth = heights.width;
27771
27779
  const mesh = createMartiniData(error / 2, heights.data, terrainWidth);
27772
27780
 
27773
- return { data: heights, mesh, sourceZoom };
27781
+ return { data: heights, mesh, sourceZoom, colorsTexture: heights.colorsTexture };
27774
27782
  }
27775
27783
 
27776
27784
  _findTileMinAltitude(tile, parentTile) {
@@ -27806,6 +27814,7 @@ class TerrainLayerRenderer extends MaskRendererMixin(TileLayerRendererable$1(Lay
27806
27814
  tileImage.sourceZoom = -1;
27807
27815
  } else {
27808
27816
  tileImage = this._createTerrainFromParent(tileInfo, parentTile);
27817
+ wrapTileColorsTexture(tileInfo, tileImage);
27809
27818
  }
27810
27819
  }
27811
27820
  this._createMesh(tileImage, tileInfo);
@@ -28474,6 +28483,27 @@ class TerrainLayerRenderer extends MaskRendererMixin(TileLayerRendererable$1(Lay
28474
28483
  xmin = Math.floor(xmin);
28475
28484
  ymin = Math.floor(ymin);
28476
28485
 
28486
+ let colorsTexture;
28487
+ //parent tile has colorstexture
28488
+ if (info.colorsTexture) {
28489
+ const { width, height } = info.colorsTexture;
28490
+ if (width * height > 0) {
28491
+ const x1 = info.extent2d.xmin;
28492
+ const x2 = info.extent2d.xmax;
28493
+ const y1 = info.extent2d.ymin;
28494
+ const y2 = info.extent2d.ymax;
28495
+ const ax = (width) / (x2 - x1), ay = height / (y2 - y1);
28496
+ const minx = (extent2d.xmin * res / parentRes - parentExtent.xmin) * ax;
28497
+ const maxx = (extent2d.xmax * res / parentRes - parentExtent.xmin) * ax;
28498
+ const miny = (extent2d.ymin * res / parentRes - parentExtent.ymin) * ay;
28499
+ const maxy = (extent2d.ymax * res / parentRes - parentExtent.ymin) * ay;
28500
+ //clip texture from parent tile texture
28501
+ colorsTexture = clipTileTexture(info.colorsTexture, minx, miny, maxx, maxy);
28502
+ }
28503
+
28504
+
28505
+ }
28506
+
28477
28507
  // const tileSize = tileWidth - 1;
28478
28508
  // if (tileSize & (tileSize - 1)) {
28479
28509
  // debugger
@@ -28515,7 +28545,8 @@ class TerrainLayerRenderer extends MaskRendererMixin(TileLayerRendererable$1(Lay
28515
28545
  height: tileWidth,
28516
28546
  data: heights,
28517
28547
  min,
28518
- max
28548
+ max,
28549
+ colorsTexture
28519
28550
  };
28520
28551
  }
28521
28552
 
@@ -28628,6 +28659,7 @@ class TerrainLayerRenderer extends MaskRendererMixin(TileLayerRendererable$1(Lay
28628
28659
  const args = [x, y, maxAvailableZoom, idx, idy, res, tile.error * Math.pow(2, diff)];
28629
28660
  tile = layer.createTileNode ? layer.createTileNode(...args) : layer._createTileNode(...args);
28630
28661
  } else {
28662
+ wrapTileColorsTexture(tile, terrainData);
28631
28663
  this.onTileLoad(terrainData, tile);
28632
28664
  return terrainData;
28633
28665
  }
@@ -28670,8 +28702,7 @@ class TerrainLayerRenderer extends MaskRendererMixin(TileLayerRendererable$1(Lay
28670
28702
  maptalks.Util.extend(terrainData, resource);
28671
28703
 
28672
28704
  // this.consumeTile(terrainData, tile);
28673
- tile.colorsTexture = terrainData.colorsTexture;
28674
- delete terrainData.colorsTexture;
28705
+ wrapTileColorsTexture(tile, terrainData);
28675
28706
  this.onTileLoad(terrainData, tile);
28676
28707
  });
28677
28708
  };
@@ -29312,6 +29343,42 @@ function isValidSkinImage(image) {
29312
29343
 
29313
29344
  function getParentRequestKey(x, y) {
29314
29345
  return x + '-' + y;
29346
+ }
29347
+
29348
+ function isPowerOfTwo(value) {
29349
+ return (value & (value - 1)) === 0 && value !== 0;
29350
+ }
29351
+
29352
+ let tempCanvas;
29353
+
29354
+ function clipTileTexture(image, x1, y1, x2, y2) {
29355
+ if (maptalks.Browser.decodeImageInWorker) {
29356
+ if (!tempCanvas) {
29357
+ tempCanvas = new OffscreenCanvas(1, 1);
29358
+ }
29359
+ const width = Math.floor(x2 - x1), height = Math.floor((y2 - y1));
29360
+ if (!isPowerOfTwo(width) || !isPowerOfTwo(height)) {
29361
+ return;
29362
+ }
29363
+ tempCanvas.width = width;
29364
+ tempCanvas.height = height;
29365
+ const ctx = tempCanvas.getContext('2d');
29366
+ ctx.clearRect(0, 0, width, height);
29367
+ ctx.drawImage(image, x1, y1, width, height, 0, 0, width, height);
29368
+ return tempCanvas.transferToImageBitmap();
29369
+ }
29370
+ }
29371
+
29372
+ function wrapTileColorsTexture(tile, terrainData) {
29373
+ const colorsTexture = terrainData.colorsTexture;
29374
+ delete terrainData.colorsTexture;
29375
+ if (colorsTexture) {
29376
+ if (tile.info) {
29377
+ tile.info.colorsTexture = colorsTexture;
29378
+ } else {
29379
+ tile.colorsTexture = colorsTexture;
29380
+ }
29381
+ }
29315
29382
  }
29316
29383
 
29317
29384
  const MASK_MODES = {
@@ -33977,7 +34044,7 @@ class Height3DTool extends Measure3DTool {
33977
34044
 
33978
34045
  const e = "${"; const code$1 = `function(t){
33979
34046
  /*!
33980
- * @maptalks/gltf-loader v0.117.0
34047
+ * @maptalks/gltf-loader v0.117.1
33981
34048
  * LICENSE : UNLICENSED
33982
34049
  * (c) 2016-2025 maptalks.org
33983
34050
  */
@@ -33990,7 +34057,7 @@ var e,r,n="undefined"!=typeof Float32Array?Float32Array:Array;function i(){var t
33990
34057
  *
33991
34058
  * Generate tangents per vertex.
33992
34059
  */
33993
- function M(t,e,r,n,i){const s=t.length/3,a=new Array(4*s),o=[],h=[];for(let t=0;t<s;t++)o[t]=[0,0,0],h[t]=[0,0,0];const c=[0,0,0],f=[0,0,0],l=[0,0,0],u=[0,0],g=[0,0],d=[0,0],p=[0,0,0],y=[0,0,0];function m(e,n,i){I(c,t,3*e),I(f,t,3*n),I(l,t,3*i),S(u,r,2*e),S(g,r,2*n),S(d,r,2*i);const s=f[0]-c[0],a=l[0]-c[0],m=f[1]-c[1],b=l[1]-c[1],w=f[2]-c[2],A=l[2]-c[2],v=g[0]-u[0],k=d[0]-u[0],T=g[1]-u[1],U=d[1]-u[1],M=1/(v*U-k*T);E(p,(U*s-T*a)*M,(U*m-T*b)*M,(U*w-T*A)*M),E(y,(v*a-k*s)*M,(v*b-k*m)*M,(v*A-k*w)*M),x(o[e],o[e],p),x(o[n],o[n],p),x(o[i],o[i],p),x(h[e],h[e],y),x(h[n],h[n],y),x(h[i],h[i],y)}for(let t=0,e=n.length;t<e;t+=3)m(n[t+0],n[t+1],n[t+2]);const b=[],w=[],A=[],v=[];let M,D,F;function B(t){I(A,e,3*t),k(v,A),D=o[t],k(b,D),U(b,b,function(t,e,r){return t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t}(A,A,T(A,D))),function(t,e){var r=e[0],n=e[1],i=e[2],s=r*r+n*n+i*i;s>0&&(s=1/Math.sqrt(s),t[0]=e[0]*s,t[1]=e[1]*s,t[2]=e[2]*s)}(b,b),function(t,e,r){var n=e[0],i=e[1],s=e[2],a=r[0],o=r[1],h=r[2];t[0]=i*h-s*o,t[1]=s*a-n*h,t[2]=n*o-i*a}(w,v,D),F=T(w,h[t]),M=F<0?-1:1,a[4*t]=b[0],a[4*t+1]=b[1],a[4*t+2]=b[2],a[4*t+3]=M}for(let t=0,e=n.length;t<e;t+=3)B(n[t+0]),B(n[t+1]),B(n[t+2]);return a}function I(t,e,r){return t[0]=e[r],t[1]=e[r+1],t[2]=e[r+2],t}function S(t,e,r){return t[0]=e[r],t[1]=e[r+1],t}function D(t){return"number"==typeof t&&!isNaN(t)}let F;!function(){var t=function(){var t=new v(3);return v!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}()}();let B=null,z=null;const N=[0,0,0],_=[256,256];function C(){try{B||(B=new OffscreenCanvas(1,1))}catch(t){console.error(t)}}const O={},R={},P={width:64,height:64,elementsPerHeight:3,heightOffset:-1e3,exaggeration:1,heightScale:.001,elementMultiplier:256,stride:4,skirtHeight:.002,skirtOffset:.01},j={cesium_request_token:{Accept:"application/json,*/*;q=0.01","Accept-Encoding":"gzip, deflate, br"},tianditu:{"Accept-Encoding":"gzip, deflate, br"},cesium:{"Accept-Encoding":"gzip, deflate, br",Accept:"application/vnd.quantized-mesh,application/octet-stream;q=0.9,*/*;q=0.01"},mapbox:{Accept:"image/webp,*/*"}};j["cesium-ion"]=j.cesium;const q=32767;let L=null,H=null;function Y(t,e){const r=function(t){if(t.length<1e3)return null;const e=new Zlib.Inflate(t);return e?e.decompress():null}(new Uint8Array(t));if(!r)throw new Error((n=new Uint8Array(t),W.decode(n)));var n;const i=function(t){const e=t,r=P.width,n=P.height,i=new Uint8Array(r*n*P.stride);let s,a,o,h,c;for(let t=0;t<n;t++)for(let f=0;f<r;f++){h=parseInt(149*t/(n-1)),c=parseInt(149*f/(r-1)),a=2*(150*h+c),s=e[a]+256*e[a+1],(s>1e4||s<-2e3)&&(s=0),o=4*(t*r+f);const l=(s+1e3)/P.heightScale,u=P.elementMultiplier;i[o]=l/(u*u),i[o+1]=(l-i[o]*u*u)/u,i[o+2]=l-i[o]*u*u-i[o+1]*u,i[o+3]=255}return i}(r),s=function(t,e){const r=e,n=e,i=r+1,s=n+1,a=P.elementsPerHeight,o=P.heightOffset,h=P.heightScale,c=P.elementMultiplier,f=P.skirtHeight,l=new Float32Array(i*s);let u=0,g=1/0,d=-1/0;for(let e=0;e<i;e++){const i=e>=n?n-1:e;for(let e=0;e<s;e++){let n=0;const s=i*(4*r)+4*(e>=r?r-1:e);for(let e=0;e<a;e++)n=n*c+t[s+e];n=1*(n*h+o),n-=f,l[u]=n,n<g&&(g=n),n>d&&(d=n),u++}}return{data:l,min:g,max:d}}(i,e-1);return s.width=s.height=e,s}const W=new TextDecoder("utf-8");function V(t){return t>>1^-(1&t)}const Z=[];function G(t){let e=0;const r=3*Float64Array.BYTES_PER_ELEMENT,n=3*Uint16Array.BYTES_PER_ELEMENT;let i=Uint16Array.BYTES_PER_ELEMENT;const s=new DataView(t);e+=r;const a=s.getFloat32(e,!0);e+=Float32Array.BYTES_PER_ELEMENT;const o=s.getFloat32(e,!0);e+=Float32Array.BYTES_PER_ELEMENT,e+=r;const h=s.getFloat64(e,!0);e+=Float64Array.BYTES_PER_ELEMENT,e+=r;const c=s.getUint32(e,!0);e+=Uint32Array.BYTES_PER_ELEMENT;const f=new Uint16Array(t,e,3*c);e+=c*n,c>65536&&(i=Uint32Array.BYTES_PER_ELEMENT);!function(t,e,r){const n=t.length;let i=0,s=0,a=0;for(let o=0;o<n;++o)i+=V(t[o]),s+=V(e[o]),t[o]=i,e[o]=s,r&&(a+=V(r[o]),r[o]=a)}(f.subarray(0,c),f.subarray(c,2*c),f.subarray(2*c,3*c)),e%i!=0&&(e+=i-e%i);const l=s.getUint32(e,!0);e+=Uint32Array.BYTES_PER_ELEMENT;const u=c>65536?new Uint32Array(t,e,3*l):new Uint16Array(t,e,3*l);let g=0;const d=u.length;for(let t=0;t<d;++t){const e=u[t];u[t]=g-e,0===e&&++g}const p={minimumHeight:a,maximumHeight:o,quantizedVertices:f,indices:u}.quantizedVertices,y=p.length/3,m=p.subarray(0,y),b=p.subarray(y,2*y),w=p.subarray(2*y,3*y),A=Z;for(let t=0;t<y;++t){const e=m[t],r=b[t],n=e/q,i=r/q,s=(v=a,k=o,(1-(E=w[t]/q))*v+E*k);A[3*t]=n,A[3*t+1]=1-i,A[3*t+2]=s}var v,k,E;return{positions:A,radius:h,min:a,max:o,indices:u}}const $=[],J=[],K=[],X=[],Q=[];class tt{constructor(t,e,r,n,i){this.p0=[],this.p1=[],this.p2=[],this.normal=[],this.min=[],this.max=[],this.set(t,e,r,n,i)}set(t,e,r,n,i){this.radius=i;let s=3*e,a=3*e+1,o=3*e+2;this.p0[0]=t[s]*i,this.p0[1]=t[a]*i,this.p0[2]=t[o],s=3*r,a=3*r+1,o=3*r+2,this.p1[0]=t[s]*i,this.p1[1]=t[a]*i,this.p1[2]=t[o],s=3*n,a=3*n+1,o=3*n+2,this.p2[0]=t[s]*i,this.p2[1]=t[a]*i,this.p2[2]=t[o],this.min[0]=Math.min(this.p0[0],this.p1[0],this.p2[0]),this.min[1]=Math.min(this.p0[1],this.p1[1],this.p2[1]),this.max[0]=Math.max(this.p0[0],this.p1[0],this.p2[0]),this.max[1]=Math.max(this.p0[1],this.p1[1],this.p2[1]);const h=l($,this.p1,this.p0),c=l(J,this.p2,this.p1);this.normal=function(t,e){var r=e[0],n=e[1],i=e[2],s=r*r+n*n+i*i;return s>0&&(s=1/Math.sqrt(s)),t[0]=e[0]*s,t[1]=e[1]*s,t[2]=e[2]*s,t}(this.normal,function(t,e,r){var n=e[0],i=e[1],s=e[2],a=r[0],o=r[1],h=r[2];return t[0]=i*h-s*o,t[1]=s*a-n*h,t[2]=n*o-i*a,t}(this.normal,h,c))}contains(t,e){if(t<this.min[0]||t>this.max[0]||e<this.min[1]||e>this.max[1])return!1;u(K,this.p0[0],this.p0[1]),u(X,this.p1[0],this.p1[1]),u(Q,this.p2[0],this.p2[1]);const r=it(K[0],K[1],X[0],X[1],Q[0],Q[1]);return it(t,e,K[0],K[1],Q[0],Q[1])+it(t,e,K[0],K[1],X[0],X[1])+it(t,e,X[0],X[1],Q[0],Q[1])-r<=1e-4}getHeight(t,e){const r=this.normal;return this.p0[2]-((t-this.p0[0])*r[0]+(e-this.p0[1])*r[1])/r[2]}}let et=null;function rt(t,e,r){if(et&&et.contains(e,r))return et.getHeight(e,r);for(let n=0;n<t.length;n++)if(t[n].contains(e,r))return et=t[n],t[n].getHeight(e,r);return 0}const nt=[];function it(t,e,r,n,i,s){return.5*Math.abs(t*n+r*s+i*e-t*s-r*e-i*n)}function st(t,e,r,n,i,s){"cesium-ion"===r&&(e.Authorization="Bearer "+L),function(t,e,r){const n={method:"GET",referrer:r,headers:e},i=h.getArrayBuffer(t,n),s=i.xhr;return R[t]=s,i.then((e=>(delete R[t],e)))}(t,e,origin).then((t=>{if(!t||t.message)s(t?{empty:!0,originalError:t}:{error:{canceled:!0}});else{const e=t.data;let a=null;if("tianditu"===r){const t=Y(e,n);ot(i,t,n,null,!0,s)}else if("cesium-ion"===r||"cesium"===r){a=G(e);const t=function(t,e){const{positions:r,min:n,max:i,indices:s,radius:a}=t,o=[];let h=0;for(let t=0;t<s.length;t+=3){let e=nt[h];e?e.set(r,s[t],s[t+1],s[t+2],2*a):e=nt[h]=new tt(r,s[t],s[t+1],s[t+2],2*a),h++,o.push(e)}const c=new Float32Array(e*e);h=0;for(let t=0;t<e;t++)for(let r=0;r<e;r++)c[h++]=rt(o,r/e*a*2,t/e*a*2);return{data:c,min:n,max:i,width:e,height:e}}(a,n);ot(i,t,n,null,!0,s)}else"mapbox"===r&&(a=function(t){const e=new self.Blob([new Uint8Array(t)]);return self.createImageBitmap(e)}(e),a.then((t=>{const e=ct(ht(t),n);ot(i,e,n,t,!0,s)})))}})).catch((e=>{delete R[t],s({empty:!0,originalError:e})}))}function at(t,e){const r=Math.floor(10*(t+1e4)),n=r>>16,i=r>>8&255,s=255&r;return e?(e[0]=n,e[1]=i,e[2]=s,e):[n,i,s]}function ot(t,e,r,n,i,s){const a=function(t,e,r){let n=p[r];n||(n=p[r]=new g(r));const i=n.createTile(e).getMeshWithSkirts(t,!0),{triangles:s,vertices:a,leftSkirtIndex:o,rightSkirtIndex:h,bottomSkirtIndex:c,topSkirtIndex:f}=i;let{numVerticesWithoutSkirts:l,numTrianglesWithoutSkirts:u}=i;l||(l=a.length/2,u=s.length/3);const d=a.length/2,y=new Float32Array(3*d),m=new Float32Array(2*d);let b=1/0,w=-1/0;const A=r-1;for(let t=0;t<d;t++){const n=a[2*t],i=a[2*t+1];if(t>=l){const e=n/2*3;let r,i=.001;(t-(t<o/2?l:t<h/2?o/2:t<c/2?h/2:c/2))%3==0?(r=Math.min(0,b),i=0):r=y[e+2],y[3*t]=y[e],y[3*t+1]=y[e+1],y[3*t+2]=r,m[2*t]=y[e]/A+i,m[2*t+1]=-y[e+1]/A+i}else{const s=e[i*r+n];y[3*t]=1*n,y[3*t+1]=1*-i,y[3*t+2]=s,m[2*t]=n/A,m[2*t+1]=i/A,s<b&&(b=s),s>w&&(w=s)}}return{positions:y,texcoords:m,triangles:s,leftSkirtIndex:o,rightSkirtIndex:h,bottomSkirtIndex:c,topSkirtIndex:f,numTrianglesWithoutSkirts:u,numVerticesWithoutSkirts:l,minHeight:Math.min(0,b),maxHeight:w,terrainWidth:r}}(t/6,e.data,r),o=[a.positions.buffer,a.texcoords.buffer,a.triangles.buffer];n||(n=function(t){if(C(),!B)return;const{width:e,height:r,data:n}=t;if(e&&r&&n)try{let t=B.getContext("2d",{willReadFrequently:!0});const i=t.createImageData(e,r);for(let t=0,e=n.length;t<e;t++){const e=n[t],[r,s,a]=at(e,N),o=4*t;i.data[o]=r,i.data[o+1]=s,i.data[o+2]=a,i.data[o+3]=255}return B.width=e,B.height=r,t=B.getContext("2d",{willReadFrequently:!0}),ft(t),t.putImageData(i,0,0),B.transferToImageBitmap()}catch(t){console.log(t)}}(e)),n&&o.push(n);const h={mesh:a};h.image=n,h.data=e,o.push(e.data.buffer),s(h,o)}function ht(t){const{width:e,height:r}=t;return B||(B=new OffscreenCanvas(1,1),z=B.getContext("2d",{willReadFrequently:!0})),B.width=e,B.height=r,z.drawImage(t,0,0,e,r),z.getImageData(0,0,e,r)}function ct(t,e){const{data:r,width:n}=t;let i=1/0,s=-1/0;const a=new Float32Array(e*e),o=Math.round(n/e);for(let t=0;t<e;t++)for(let h=0;h<e;h++){const c=t+h*e;let f=0,l=0;const u=t,g=h;for(let t=0;t<o;t++)for(let e=0;e<o;e++){let i=u*o+t,s=g*o+e;s>n-1&&(s=n-1),i>n-1&&(i=n-1);const a=i+s*n,h=r[4*a],c=r[4*a+1],d=r[4*a+2];0===r[4*a+3]?l+=1:f+=.1*(256*h*256+256*c+d)-1e4}f/=o*o-l||1,f>s&&(s=f),f<i&&(i=f),a[c]=f}return{data:a,width:e,height:e,min:i,max:s}}function ft(t){const e=t.canvas,{width:r,height:n}=e;t.clearRect(0,0,r,n)}function lt(t,e,r){if(!e||!Array.isArray(e)||e.length<2)return;if(!t||!t.image)return null;let{width:n,height:i}=t.image;(r=r||_)[0]===n&&r[1]===i||(n=r[0],i=r[1]),[n,i]=_;try{if(C(),!B)return;const r=B;r.width=n,r.height=i;const s=r.getContext("2d",{willReadFrequently:!0});ft(s),s.drawImage(t.image,0,0,n,i);const a=s.getImageData(0,0,n,i);!function(t,e){const r=JSON.stringify(e);O[r]||(O[r]=new A(e));const n=O[r],i=t.data;for(let t=0,e=i.length;t<e;t+=4){const e=i[t],r=i[t+1],s=i[t+2];let a=0;0!==i[t+3]&&(a=.1*(256*e*256+256*r+s)-1e4,a=Math.max(a,0));const[o,h,c]=n.getColor(a);i[t]=o,i[t+1]=h,i[t+2]=c,i[t+3]=255}}(a,e),s.putImageData(a,0,0);const o=r.transferToImageBitmap();s.save(),s.scale(1,-1),s.drawImage(o,0,-i,n,i),s.restore();const h=r.transferToImageBitmap();return o.close(),h}catch(t){console.error(t)}}t.initialize=function(){},t.onmessage=function(t,e){const r=t.data;if("addLayer"===r.command||"removeLayer"===r.command)F=t.workerId,self.postMessage({type:"<response>",actorId:r.actorId,workerId:F,params:"ok",callback:t.callback});else if("fetchTerrain"===r.command){const t=(r.params||{}).colors,n=(r.params||{}).tileSize;!function(t,e){const{url:r,origin:n,type:i,accessToken:s,terrainWidth:a,error:o,tileImage:h}=t;if(h&&h.close){const t=ct(ht(h),a);return void ot(o,t,a,h,0,e)}const c=t.headers||j[i];if("tianditu"===i)st(r,c,i,a,o,e);else if("cesium-ion"===i){const h=t.cesiumIonTokenURL+s;L?st(r,c,i,a,o,e):(H||(H=fetch(h,{responseType:"json",method:"GET",referrer:n,headers:{Accept:"application/json,*/*;q=0.01","Accept-Encoding":"gzip, deflate, br"}}).then((t=>t.json())).then((t=>{L=t.accessToken,H=null}))),H.then((()=>{st(r,c,i,a,o,e)})))}else("cesium"===i||"mapbox"===i)&&st(r,c,i,a,o,e)}(r.params,((r,i)=>{i=i||[];const s=lt(r,t,n);s&&(r.colorsTexture=s,i.push(s));const a=function(t){if(!t)return;const{positions:e,texcoords:r,triangles:n,leftSkirtIndex:i,rightSkirtIndex:s,bottomSkirtIndex:a,numVerticesWithoutSkirts:o}=t;if(!e||!r||!n)return;if(!(D(i)&&D(s)&&D(a)&&D(o)))return;const h=new Int8Array(e.length);for(let t=2;t<h.length;t+=3)t<3*o?h[t]=1:t<i/2*3?h[t-2]=-1:t<s/2*3?h[t-2]=1:h[t-1]=t<a/2*3?-1:1;const c=M(e,h,r,n);return new Float32Array(c)}(r.mesh);a&&r.mesh&&(r.mesh.tangents=a,i.push(a.buffer)),e(r.error,r,i)}))}else"abortTerrain"===r.command&&(n=r.params.url,R[n]&&(R[n].abort(),delete R[n]));var n}}`;
34060
+ function M(t,e,r,n,i){const s=t.length/3,a=new Array(4*s),o=[],h=[];for(let t=0;t<s;t++)o[t]=[0,0,0],h[t]=[0,0,0];const c=[0,0,0],f=[0,0,0],l=[0,0,0],u=[0,0],g=[0,0],d=[0,0],p=[0,0,0],y=[0,0,0];function m(e,n,i){I(c,t,3*e),I(f,t,3*n),I(l,t,3*i),S(u,r,2*e),S(g,r,2*n),S(d,r,2*i);const s=f[0]-c[0],a=l[0]-c[0],m=f[1]-c[1],b=l[1]-c[1],w=f[2]-c[2],A=l[2]-c[2],v=g[0]-u[0],k=d[0]-u[0],T=g[1]-u[1],U=d[1]-u[1],M=1/(v*U-k*T);E(p,(U*s-T*a)*M,(U*m-T*b)*M,(U*w-T*A)*M),E(y,(v*a-k*s)*M,(v*b-k*m)*M,(v*A-k*w)*M),x(o[e],o[e],p),x(o[n],o[n],p),x(o[i],o[i],p),x(h[e],h[e],y),x(h[n],h[n],y),x(h[i],h[i],y)}for(let t=0,e=n.length;t<e;t+=3)m(n[t+0],n[t+1],n[t+2]);const b=[],w=[],A=[],v=[];let M,D,F;function B(t){I(A,e,3*t),k(v,A),D=o[t],k(b,D),U(b,b,function(t,e,r){return t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t}(A,A,T(A,D))),function(t,e){var r=e[0],n=e[1],i=e[2],s=r*r+n*n+i*i;s>0&&(s=1/Math.sqrt(s),t[0]=e[0]*s,t[1]=e[1]*s,t[2]=e[2]*s)}(b,b),function(t,e,r){var n=e[0],i=e[1],s=e[2],a=r[0],o=r[1],h=r[2];t[0]=i*h-s*o,t[1]=s*a-n*h,t[2]=n*o-i*a}(w,v,D),F=T(w,h[t]),M=F<0?-1:1,a[4*t]=b[0],a[4*t+1]=b[1],a[4*t+2]=b[2],a[4*t+3]=M}for(let t=0,e=n.length;t<e;t+=3)B(n[t+0]),B(n[t+1]),B(n[t+2]);return a}function I(t,e,r){return t[0]=e[r],t[1]=e[r+1],t[2]=e[r+2],t}function S(t,e,r){return t[0]=e[r],t[1]=e[r+1],t}function D(t){return"number"==typeof t&&!isNaN(t)}let F;!function(){var t=function(){var t=new v(3);return v!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}()}();let B=null,z=null;const N=[0,0,0],_=[256,256];function C(){try{B||(B=new OffscreenCanvas(1,1))}catch(t){console.error(t)}}const O={},R={},P={width:64,height:64,elementsPerHeight:3,heightOffset:-1e3,exaggeration:1,heightScale:.001,elementMultiplier:256,stride:4,skirtHeight:.002,skirtOffset:.01},j={cesium_request_token:{Accept:"application/json,*/*;q=0.01","Accept-Encoding":"gzip, deflate, br"},tianditu:{"Accept-Encoding":"gzip, deflate, br"},cesium:{"Accept-Encoding":"gzip, deflate, br",Accept:"application/vnd.quantized-mesh,application/octet-stream;q=0.9,*/*;q=0.01"},mapbox:{Accept:"image/webp,*/*"}};j["cesium-ion"]=j.cesium;const q=32767;let L=null,H=null;function Y(t,e){const r=function(t){if(t.length<1e3)return null;const e=new Zlib.Inflate(t);return e?e.decompress():null}(new Uint8Array(t));if(!r)throw new Error((n=new Uint8Array(t),W.decode(n)));var n;const i=function(t){const e=t,r=P.width,n=P.height,i=new Uint8Array(r*n*P.stride);let s,a,o,h,c;for(let t=0;t<n;t++)for(let f=0;f<r;f++){h=parseInt(149*t/(n-1)),c=parseInt(149*f/(r-1)),a=2*(150*h+c),s=e[a]+256*e[a+1],(s>1e4||s<-2e3)&&(s=0),o=4*(t*r+f);const l=(s+1e3)/P.heightScale,u=P.elementMultiplier;i[o]=l/(u*u),i[o+1]=(l-i[o]*u*u)/u,i[o+2]=l-i[o]*u*u-i[o+1]*u,i[o+3]=255}return i}(r),s=function(t,e){const r=e,n=e,i=r+1,s=n+1,a=P.elementsPerHeight,o=P.heightOffset,h=P.heightScale,c=P.elementMultiplier,f=P.skirtHeight,l=new Float32Array(i*s);let u=0,g=1/0,d=-1/0;for(let e=0;e<i;e++){const i=e>=n?n-1:e;for(let e=0;e<s;e++){let n=0;const s=i*(4*r)+4*(e>=r?r-1:e);for(let e=0;e<a;e++)n=n*c+t[s+e];n=1*(n*h+o),n-=f,l[u]=n,n<g&&(g=n),n>d&&(d=n),u++}}return{data:l,min:g,max:d}}(i,e-1);return s.width=s.height=e,s}const W=new TextDecoder("utf-8");function V(t){return t>>1^-(1&t)}const Z=[];function G(t){let e=0;const r=3*Float64Array.BYTES_PER_ELEMENT,n=3*Uint16Array.BYTES_PER_ELEMENT;let i=Uint16Array.BYTES_PER_ELEMENT;const s=new DataView(t);e+=r;const a=s.getFloat32(e,!0);e+=Float32Array.BYTES_PER_ELEMENT;const o=s.getFloat32(e,!0);e+=Float32Array.BYTES_PER_ELEMENT,e+=r;const h=s.getFloat64(e,!0);e+=Float64Array.BYTES_PER_ELEMENT,e+=r;const c=s.getUint32(e,!0);e+=Uint32Array.BYTES_PER_ELEMENT;const f=new Uint16Array(t,e,3*c);e+=c*n,c>65536&&(i=Uint32Array.BYTES_PER_ELEMENT);!function(t,e,r){const n=t.length;let i=0,s=0,a=0;for(let o=0;o<n;++o)i+=V(t[o]),s+=V(e[o]),t[o]=i,e[o]=s,r&&(a+=V(r[o]),r[o]=a)}(f.subarray(0,c),f.subarray(c,2*c),f.subarray(2*c,3*c)),e%i!=0&&(e+=i-e%i);const l=s.getUint32(e,!0);e+=Uint32Array.BYTES_PER_ELEMENT;const u=c>65536?new Uint32Array(t,e,3*l):new Uint16Array(t,e,3*l);let g=0;const d=u.length;for(let t=0;t<d;++t){const e=u[t];u[t]=g-e,0===e&&++g}const p={minimumHeight:a,maximumHeight:o,quantizedVertices:f,indices:u}.quantizedVertices,y=p.length/3,m=p.subarray(0,y),b=p.subarray(y,2*y),w=p.subarray(2*y,3*y),A=Z;for(let t=0;t<y;++t){const e=m[t],r=b[t],n=e/q,i=r/q,s=(v=a,k=o,(1-(E=w[t]/q))*v+E*k);A[3*t]=n,A[3*t+1]=1-i,A[3*t+2]=s}var v,k,E;return{positions:A,radius:h,min:a,max:o,indices:u}}const $=[],J=[],K=[],X=[],Q=[];class tt{constructor(t,e,r,n,i){this.p0=[],this.p1=[],this.p2=[],this.normal=[],this.min=[],this.max=[],this.set(t,e,r,n,i)}set(t,e,r,n,i){this.radius=i;let s=3*e,a=3*e+1,o=3*e+2;this.p0[0]=t[s]*i,this.p0[1]=t[a]*i,this.p0[2]=t[o],s=3*r,a=3*r+1,o=3*r+2,this.p1[0]=t[s]*i,this.p1[1]=t[a]*i,this.p1[2]=t[o],s=3*n,a=3*n+1,o=3*n+2,this.p2[0]=t[s]*i,this.p2[1]=t[a]*i,this.p2[2]=t[o],this.min[0]=Math.min(this.p0[0],this.p1[0],this.p2[0]),this.min[1]=Math.min(this.p0[1],this.p1[1],this.p2[1]),this.max[0]=Math.max(this.p0[0],this.p1[0],this.p2[0]),this.max[1]=Math.max(this.p0[1],this.p1[1],this.p2[1]);const h=l($,this.p1,this.p0),c=l(J,this.p2,this.p1);this.normal=function(t,e){var r=e[0],n=e[1],i=e[2],s=r*r+n*n+i*i;return s>0&&(s=1/Math.sqrt(s)),t[0]=e[0]*s,t[1]=e[1]*s,t[2]=e[2]*s,t}(this.normal,function(t,e,r){var n=e[0],i=e[1],s=e[2],a=r[0],o=r[1],h=r[2];return t[0]=i*h-s*o,t[1]=s*a-n*h,t[2]=n*o-i*a,t}(this.normal,h,c))}contains(t,e){if(t<this.min[0]||t>this.max[0]||e<this.min[1]||e>this.max[1])return!1;u(K,this.p0[0],this.p0[1]),u(X,this.p1[0],this.p1[1]),u(Q,this.p2[0],this.p2[1]);const r=it(K[0],K[1],X[0],X[1],Q[0],Q[1]);return it(t,e,K[0],K[1],Q[0],Q[1])+it(t,e,K[0],K[1],X[0],X[1])+it(t,e,X[0],X[1],Q[0],Q[1])-r<=1e-4}getHeight(t,e){const r=this.normal;return this.p0[2]-((t-this.p0[0])*r[0]+(e-this.p0[1])*r[1])/r[2]}}let et=null;function rt(t,e,r){if(et&&et.contains(e,r))return et.getHeight(e,r);for(let n=0;n<t.length;n++)if(t[n].contains(e,r))return et=t[n],t[n].getHeight(e,r);return 0}const nt=[];function it(t,e,r,n,i,s){return.5*Math.abs(t*n+r*s+i*e-t*s-r*e-i*n)}function st(t,e,r,n,i,s){"cesium-ion"===r&&(e.Authorization="Bearer "+L),function(t,e,r){const n={method:"GET",referrer:r,headers:e},i=h.getArrayBuffer(t,n),s=i.xhr;return R[t]=s,i.then((e=>(delete R[t],e)))}(t,e,origin).then((t=>{if(!t||t.message)s(t?{empty:!0,originalError:t}:{error:{canceled:!0}});else{const e=t.data;let a=null;if("tianditu"===r){const t=Y(e,n);ot(i,t,n,null,!0,s)}else if("cesium-ion"===r||"cesium"===r){a=G(e);const t=function(t,e){const{positions:r,min:n,max:i,indices:s,radius:a}=t,o=[];let h=0;for(let t=0;t<s.length;t+=3){let e=nt[h];e?e.set(r,s[t],s[t+1],s[t+2],2*a):e=nt[h]=new tt(r,s[t],s[t+1],s[t+2],2*a),h++,o.push(e)}const c=new Float32Array(e*e);h=0;for(let t=0;t<e;t++)for(let r=0;r<e;r++)c[h++]=rt(o,r/e*a*2,t/e*a*2);return{data:c,min:n,max:i,width:e,height:e}}(a,n);ot(i,t,n,null,!0,s)}else"mapbox"===r&&(a=function(t){const e=new self.Blob([new Uint8Array(t)]);return self.createImageBitmap(e)}(e),a.then((t=>{const e=ct(ht(t),n);ot(i,e,n,t,!0,s)})))}})).catch((e=>{delete R[t],s({empty:!0,originalError:e})}))}function at(t,e){const r=Math.floor(10*(t+1e4)),n=r>>16,i=r>>8&255,s=255&r;return e?(e[0]=n,e[1]=i,e[2]=s,e):[n,i,s]}function ot(t,e,r,n,i,s){const a=function(t,e,r){let n=p[r];n||(n=p[r]=new g(r));const i=n.createTile(e).getMeshWithSkirts(t,!0),{triangles:s,vertices:a,leftSkirtIndex:o,rightSkirtIndex:h,bottomSkirtIndex:c,topSkirtIndex:f}=i;let{numVerticesWithoutSkirts:l,numTrianglesWithoutSkirts:u}=i;l||(l=a.length/2,u=s.length/3);const d=a.length/2,y=new Float32Array(3*d),m=new Float32Array(2*d);let b=1/0,w=-1/0;const A=r-1;for(let t=0;t<d;t++){const n=a[2*t],i=a[2*t+1];if(t>=l){const e=n/2*3;let r,i=.001;(t-(t<o/2?l:t<h/2?o/2:t<c/2?h/2:c/2))%3==0?(r=Math.min(0,b),i=0):r=y[e+2],y[3*t]=y[e],y[3*t+1]=y[e+1],y[3*t+2]=r,m[2*t]=y[e]/A+i,m[2*t+1]=-y[e+1]/A+i}else{const s=e[i*r+n];y[3*t]=1*n,y[3*t+1]=1*-i,y[3*t+2]=s,m[2*t]=n/A,m[2*t+1]=i/A,s<b&&(b=s),s>w&&(w=s)}}return{positions:y,texcoords:m,triangles:s,leftSkirtIndex:o,rightSkirtIndex:h,bottomSkirtIndex:c,topSkirtIndex:f,numTrianglesWithoutSkirts:u,numVerticesWithoutSkirts:l,minHeight:Math.min(0,b),maxHeight:w,terrainWidth:r}}(t/6,e.data,r),o=[a.positions.buffer,a.texcoords.buffer,a.triangles.buffer];n||(n=function(t){if(C(),!B)return;const{width:e,height:r,data:n}=t;if(e&&r&&n)try{let t=B.getContext("2d",{willReadFrequently:!0});const i=t.createImageData(e,r);for(let t=0,e=n.length;t<e;t++){const e=n[t],[r,s,a]=at(e,N),o=4*t;i.data[o]=r,i.data[o+1]=s,i.data[o+2]=a,i.data[o+3]=255}return B.width=e,B.height=r,t=B.getContext("2d",{willReadFrequently:!0}),ft(t),t.putImageData(i,0,0),B.transferToImageBitmap()}catch(t){console.log(t)}}(e)),n&&o.push(n);const h={mesh:a};h.image=n,h.data=e,o.push(e.data.buffer),s(h,o)}function ht(t){const{width:e,height:r}=t;return B||(B=new OffscreenCanvas(1,1),z=B.getContext("2d",{willReadFrequently:!0})),B.width=e,B.height=r,z.drawImage(t,0,0,e,r),z.getImageData(0,0,e,r)}function ct(t,e){const{data:r,width:n}=t;let i=1/0,s=-1/0;const a=new Float32Array(e*e),o=Math.round(n/e);for(let t=0;t<e;t++)for(let h=0;h<e;h++){const c=t+h*e;let f=0,l=0;const u=t,g=h;for(let t=0;t<o;t++)for(let e=0;e<o;e++){let i=u*o+t,s=g*o+e;s>n-1&&(s=n-1),i>n-1&&(i=n-1);const a=i+s*n,h=r[4*a],c=r[4*a+1],d=r[4*a+2];0===r[4*a+3]?l+=1:f+=.1*(256*h*256+256*c+d)-1e4}f/=o*o-l||1,f>s&&(s=f),f<i&&(i=f),a[c]=f}return{data:a,width:e,height:e,min:i,max:s}}function ft(t){const e=t.canvas,{width:r,height:n}=e;t.clearRect(0,0,r,n)}function lt(t,e,r){if(!e||!Array.isArray(e)||e.length<2)return;if(!t||!t.image)return null;let{width:n,height:i}=t.image;(r=r||_)[0]===n&&r[1]===i||(n=r[0],i=r[1]),n*=2,i*=2;try{if(C(),!B)return;const r=B;r.width=n,r.height=i;const s=r.getContext("2d",{willReadFrequently:!0});ft(s),s.drawImage(t.image,0,0,n,i);const a=s.getImageData(0,0,n,i);!function(t,e){const r=JSON.stringify(e);O[r]||(O[r]=new A(e));const n=O[r],i=t.data;for(let t=0,e=i.length;t<e;t+=4){const e=i[t],r=i[t+1],s=i[t+2];let a=0;0!==i[t+3]&&(a=.1*(256*e*256+256*r+s)-1e4,a=Math.max(a,0));const[o,h,c]=n.getColor(a);i[t]=o,i[t+1]=h,i[t+2]=c,i[t+3]=255}}(a,e),s.putImageData(a,0,0);const o=r.transferToImageBitmap();s.save(),s.scale(1,-1),s.drawImage(o,0,-i,n,i),s.restore();const h=r.transferToImageBitmap();return o.close(),h}catch(t){console.error(t)}}t.initialize=function(){},t.onmessage=function(t,e){const r=t.data;if("addLayer"===r.command||"removeLayer"===r.command)F=t.workerId,self.postMessage({type:"<response>",actorId:r.actorId,workerId:F,params:"ok",callback:t.callback});else if("fetchTerrain"===r.command){const t=(r.params||{}).colors,n=(r.params||{}).tileSize;!function(t,e){const{url:r,origin:n,type:i,accessToken:s,terrainWidth:a,error:o,tileImage:h}=t;if(h&&h.close){const t=ct(ht(h),a);return void ot(o,t,a,h,0,e)}const c=t.headers||j[i];if("tianditu"===i)st(r,c,i,a,o,e);else if("cesium-ion"===i){const h=t.cesiumIonTokenURL+s;L?st(r,c,i,a,o,e):(H||(H=fetch(h,{responseType:"json",method:"GET",referrer:n,headers:{Accept:"application/json,*/*;q=0.01","Accept-Encoding":"gzip, deflate, br"}}).then((t=>t.json())).then((t=>{L=t.accessToken,H=null}))),H.then((()=>{st(r,c,i,a,o,e)})))}else("cesium"===i||"mapbox"===i)&&st(r,c,i,a,o,e)}(r.params,((r,i)=>{i=i||[];const s=lt(r,t,n);s&&(r.colorsTexture=s,i.push(s));const a=function(t){if(!t)return;const{positions:e,texcoords:r,triangles:n,leftSkirtIndex:i,rightSkirtIndex:s,bottomSkirtIndex:a,numVerticesWithoutSkirts:o}=t;if(!e||!r||!n)return;if(!(D(i)&&D(s)&&D(a)&&D(o)))return;const h=new Int8Array(e.length);for(let t=2;t<h.length;t+=3)t<3*o?h[t]=1:t<i/2*3?h[t-2]=-1:t<s/2*3?h[t-2]=1:h[t-1]=t<a/2*3?-1:1;const c=M(e,h,r,n);return new Float32Array(c)}(r.mesh);a&&r.mesh&&(r.mesh.tangents=a,i.push(a.buffer)),e(r.error,r,i)}))}else"abortTerrain"===r.command&&(n=r.params.url,R[n]&&(R[n].abort(),delete R[n]));var n}}`;
33994
34061
 
33995
34062
  const code = `function(t){var n,r="undefined"!=typeof Float32Array?Float32Array:Array;function o(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t}function e(t,n,r,o){return t[0]=n[0]+r[0]*o,t[1]=n[1]+r[1]*o,t[2]=n[2]+r[2]*o,t}function a(t,n){var r=n[0],o=n[1],e=n[2],a=r*r+o*o+e*e;return a>0&&(a=1/Math.sqrt(a)),t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t}
33996
34063
  /*!
@@ -34006,5 +34073,5 @@ maptalks.registerWorkerAdapter('maplight', code);
34006
34073
 
34007
34074
  export { Area3DTool, BoxInsideClipper as BoxInsideClipMask, BoxOutsideClipper as BoxOutsideClipMask, canvasCompatible as CanvasCompatible, ClipInsideMask, ClipOutsideMask, ColorMask, context as ContextUtil, Distance3DTool, ElevateMask, FlatInsideMask$1 as FlatInsideMask, FlatInsideMask as FlatOutsideMask, GroundPainter, GroupGLLayer, HeatmapProcess, Height3DTool, highlight as HighlightUtil, ImageMask, MapGLRenderer, MapGPURenderer, MaskLayerMixin, MaskRendererMixin, Measure3DTool, RayCaster, VideoMask, Color$1 as color, earcut$1 as earcut, index as reshader, transcoders };
34008
34075
 
34009
- typeof console !== 'undefined' && console.log('@maptalks/gpu v0.117.0');
34076
+ typeof console !== 'undefined' && console.log('@maptalks/gpu v0.117.1');
34010
34077
  //# sourceMappingURL=maptalksgpu.es.js.map