s3m-three 0.3.10 → 0.3.12

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.
@@ -3,7 +3,7 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
3
3
  vec4 sampledDiffuseColor = s3mAtlasUnit( vMapUv, vAtlasRect, uAtlasDim, map );
4
4
  diffuseColor *= sampledDiffuseColor;
5
5
  #endif
6
- ${f?`\n${di}`:``}`):f&&(e.fragmentShader=e.fragmentShader.replace(`#include <map_fragment>`,`#include <map_fragment>\n${di}`))},r.customProgramCacheKey=()=>`s3m-styled${d?`-atlas`:``}${f?`-bake`:``}`,r.userData.uSelBatch=i,r.userData.uSelWhole=a,r.userData.uBatchTex=o,r.userData.uBatchTex2=s,r.userData.uBatchTexWidth=c,r.userData.uBatchTexActive=l,r.userData.uTileFade=u,r.userData.isStyled=!0,r}function Qr(e,n=.9){let r=new t.ShaderMaterial({uniforms:{uSelBatch:{value:-1},uSelWhole:{value:0},uWidth:{value:n},uElevation:{value:0},uBatchTex:{value:ri},uBatchTex2:{value:ri},uBatchMix:e.uBatchMix??{value:0},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uPathTex:e.uPathTex??{value:Jr.DUMMY_PATH_TEX},uPathCount:e.uPathCount??{value:1},uPathTexActive:e.uPathTexActive??{value:0},uPathTime:e.uPathTime??{value:0},uColor:{value:e.uSelColor.value.clone()}},vertexShader:fi,fragmentShader:pi,side:t.BackSide,depthWrite:!1,transparent:!1,polygonOffset:!0,polygonOffsetFactor:1,polygonOffsetUnits:1});return r.userData.isOutline=!0,r}var Z,$r,Q,ei,ti,ni,ri,ii,ai,oi,si,ci,li,ui,di,fi,pi,mi=c((()=>{Yr(),Z={WHITE:0,TEXTURE:1,SOLID:2,HEIGHT:3,FLOORS:4,BATCH:5,DYNAMIC:6,TOP_SIDE:7,CUSTOM:8},$r={[Z.WHITE]:`白膜`,[Z.TEXTURE]:`原色`,[Z.SOLID]:`单色`,[Z.HEIGHT]:`按高度`,[Z.FLOORS]:`按楼层`,[Z.BATCH]:`按单体`,[Z.DYNAMIC]:`动态扫描`,[Z.TOP_SIDE]:`顶/侧分色`,[Z.CUSTOM]:`自定义`},Q={REPLACE:`replace`,OVERLAY:`overlay`,MULTIPLY:`multiply`,GLOW_ONLY:`glowOnly`},ei={[Q.OVERLAY]:`叠加原图 (Overlay)`,[Q.REPLACE]:`纯色覆盖 (Replace)`,[Q.MULTIPLY]:`叠乘模式 (Multiply)`,[Q.GLOW_ONLY]:`仅描边发光 (Glow)`},ti={mode:Z.TEXTURE,colorA:`#dfe6ee`,colorB:`#1d4ed8`,colorC:`#fbbf24`,selectColor:`#22d3ee`,selectMode:Q.OVERLAY,selectOpacity:.65,selectEmissive:.35,selectElevation:0,floorHeight:wt,speed:1,opacity:1,shading:`flat`,dimOthers:!0,dimFactor:.42,outline:!0,outlineStyle:`edges`,outlineColor:`#22d3ee`,outlineWidth:.9,outlineWidthPx:3,edges:!1,edgeWidth:1.5,edgeColor:`#334155`,edgeOpacity:.6,edgeThreshold:55,roofThreshold:.65,texMix:0,ambientGain:0,depthWrite:!0,fadeIn:0},ni=new Float32Array([-1,-1,-1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,-1,0,0,0]),ri=new t.DataTexture(ni,1,6,t.RGBAFormat,t.FloatType),ri.minFilter=t.NearestFilter,ri.magFilter=t.NearestFilter,ri.needsUpdate=!0,ii=`
6
+ ${f?`\n${di}`:``}`):f&&(e.fragmentShader=e.fragmentShader.replace(`#include <map_fragment>`,`#include <map_fragment>\n${di}`))},r.customProgramCacheKey=()=>`s3m-styled${d?`-atlas`:``}${f?`-bake`:``}`,r.userData.uSelBatch=i,r.userData.uSelWhole=a,r.userData.uSelElevation=n?.uSelElevation,r.userData.uBatchMix=n?.uBatchMix,r.userData.uPathTex=n?.uPathTex,r.userData.uPathCount=n?.uPathCount,r.userData.uPathTime=n?.uPathTime,r.userData.uPathTexActive=n?.uPathTexActive,r.userData.uBatchTex=o,r.userData.uBatchTex2=s,r.userData.uBatchTexWidth=c,r.userData.uBatchTexActive=l,r.userData.uTileFade=u,r.userData.isStyled=!0,r}function Qr(e,n=.9){let r=new t.ShaderMaterial({uniforms:{uSelBatch:{value:-1},uSelWhole:{value:0},uWidth:{value:n},uElevation:{value:0},uBatchTex:{value:ri},uBatchTex2:{value:ri},uBatchMix:e.uBatchMix??{value:0},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uPathTex:e.uPathTex??{value:Jr.DUMMY_PATH_TEX},uPathCount:e.uPathCount??{value:1},uPathTexActive:e.uPathTexActive??{value:0},uPathTime:e.uPathTime??{value:0},uColor:{value:e.uSelColor.value.clone()}},vertexShader:fi,fragmentShader:pi,side:t.BackSide,depthWrite:!1,transparent:!1,polygonOffset:!0,polygonOffsetFactor:1,polygonOffsetUnits:1});return r.userData.isOutline=!0,r}var Z,$r,Q,ei,ti,ni,ri,ii,ai,oi,si,ci,li,ui,di,fi,pi,mi=c((()=>{Yr(),Z={WHITE:0,TEXTURE:1,SOLID:2,HEIGHT:3,FLOORS:4,BATCH:5,DYNAMIC:6,TOP_SIDE:7,CUSTOM:8},$r={[Z.WHITE]:`白膜`,[Z.TEXTURE]:`原色`,[Z.SOLID]:`单色`,[Z.HEIGHT]:`按高度`,[Z.FLOORS]:`按楼层`,[Z.BATCH]:`按单体`,[Z.DYNAMIC]:`动态扫描`,[Z.TOP_SIDE]:`顶/侧分色`,[Z.CUSTOM]:`自定义`},Q={REPLACE:`replace`,OVERLAY:`overlay`,MULTIPLY:`multiply`,GLOW_ONLY:`glowOnly`},ei={[Q.OVERLAY]:`叠加原图 (Overlay)`,[Q.REPLACE]:`纯色覆盖 (Replace)`,[Q.MULTIPLY]:`叠乘模式 (Multiply)`,[Q.GLOW_ONLY]:`仅描边发光 (Glow)`},ti={mode:Z.TEXTURE,colorA:`#dfe6ee`,colorB:`#1d4ed8`,colorC:`#fbbf24`,selectColor:`#22d3ee`,selectMode:Q.OVERLAY,selectOpacity:.65,selectEmissive:.35,selectElevation:0,floorHeight:wt,speed:1,opacity:1,shading:`flat`,dimOthers:!0,dimFactor:.42,outline:!0,outlineStyle:`edges`,outlineColor:`#22d3ee`,outlineWidth:.9,outlineWidthPx:3,edges:!1,edgeWidth:1.5,edgeColor:`#334155`,edgeOpacity:.6,edgeThreshold:55,roofThreshold:.65,texMix:0,ambientGain:0,depthWrite:!0,fadeIn:0},ni=new Float32Array([-1,-1,-1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,-1,0,0,0]),ri=new t.DataTexture(ni,1,6,t.RGBAFormat,t.FloatType),ri.minFilter=t.NearestFilter,ri.magFilter=t.NearestFilter,ri.needsUpdate=!0,ii=`
7
7
  attribute float aBatchId;
8
8
  attribute vec3 aColor;
9
9
  #ifdef S3M_ATLAS
@@ -141,9 +141,12 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
141
141
  if ( autoHeading ) {
142
142
  float c = cos( pathYaw );
143
143
  float s = sin( pathYaw );
144
+
145
+ // GLSL 的 mat3 是列优先:下面两行是「第 0 列 = (c, s)」,等价于绕 Z 转 +yaw,
146
+ // 把模型 +X 朝向对到切线方向(yaw = atan2(dy, dx))。写成 (c,-s; s,c) 会左右镜像。
144
147
  mat3 rotHeading = mat3(
145
- c, -s, 0.0,
146
- s, c, 0.0,
148
+ c, s, 0.0,
149
+ -s, c, 0.0,
147
150
  0.0, 0.0, 1.0
148
151
  );
149
152
  s3mRot = rotHeading * s3mRot;
@@ -563,9 +566,12 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
563
566
  if ( autoHeading ) {
564
567
  float c = cos( pathYaw );
565
568
  float s = sin( pathYaw );
569
+
570
+ // GLSL 的 mat3 是列优先:下面两行是「第 0 列 = (c, s)」,等价于绕 Z 转 +yaw,
571
+ // 把模型 +X 朝向对到切线方向(yaw = atan2(dy, dx))。写成 (c,-s; s,c) 会左右镜像。
566
572
  mat3 rotHeading = mat3(
567
- c, -s, 0.0,
568
- s, c, 0.0,
573
+ c, s, 0.0,
574
+ -s, c, 0.0,
569
575
  0.0, 0.0, 1.0
570
576
  );
571
577
  s3mRot = rotHeading * s3mRot;
@@ -622,13 +628,26 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
622
628
  #endif
623
629
  uniform float uObjectId;
624
630
  uniform sampler2D uBatchTex;
631
+ uniform sampler2D uBatchTex2;
632
+ uniform float uBatchMix;
625
633
  uniform float uBatchTexWidth;
626
634
  uniform int uBatchTexActive;
635
+ uniform sampler2D uPathTex;
636
+ uniform float uPathCount;
637
+ uniform float uPathTime;
638
+ uniform int uPathTexActive;
627
639
  uniform float uSelBatch;
628
640
  uniform float uSelWhole;
629
641
  uniform float uSelElevation;
630
642
  varying float vBatch;
631
643
 
644
+ /** 交叉淡化期间也要读「屏幕上正在显示的那份」,否则过渡中点到的是旧位置 */
645
+ vec4 s3mPickSample( vec2 uv ) {
646
+ vec4 a = texture2D( uBatchTex, uv );
647
+ if ( uBatchMix <= 0.0001 ) return a;
648
+ return mix( a, texture2D( uBatchTex2, uv ), uBatchMix );
649
+ }
650
+
632
651
  void main() {
633
652
  float s3mBatch;
634
653
  #ifdef USE_INSTANCING
@@ -640,22 +659,82 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
640
659
  vBatch = aBatchId;
641
660
  #endif
642
661
 
643
- // 单体状态(平移 / 隐藏)必须和主着色器用同一份数据、同一套算法:
644
- // 平移只发生在顶点着色器里,拾取这一趟如果还按原始坐标画,移位的楼就点不中。
662
+ // 单体状态必须和主着色器用同一份数据、同一套算法:位移 / 旋转 / 隐藏 / GPU 路径
663
+ // 全都只发生在顶点着色器里,拾取这一趟如果还按原始坐标画,动过的楼就点不中。
664
+ // 状态纹理共 6 行,行序与 StyleMaterial 的 VERT_SETUP 严格一一对应。
645
665
  vec3 p = position;
666
+ mat3 rot = mat3( 1.0 );
667
+ vec3 pivot = vec3( 0.0 );
668
+ vec3 offset = vec3( 0.0 );
669
+ bool hidden = false;
670
+
646
671
  if ( uBatchTexActive > 0 && s3mBatch >= 0.0 ) {
647
- vec4 state = texture2D( uBatchTex, vec2( ( s3mBatch + 0.5 ) / uBatchTexWidth, 0.25 ) );
672
+ float u = ( s3mBatch + 0.5 ) / uBatchTexWidth;
673
+ // Row 0:rgb = 配色,a = 抬高 / < -0.5 表示隐藏
674
+ vec4 state = s3mPickSample( vec2( u, 0.08333333 ) );
648
675
  if ( state.a < -0.5 ) {
649
- p = vec3( 0.0 );
676
+ hidden = true;
650
677
  } else {
651
- vec4 offset = texture2D( uBatchTex, vec2( ( s3mBatch + 0.5 ) / uBatchTexWidth, 0.75 ) );
652
- p += offset.xyz;
653
- if ( offset.z == 0.0 && state.a > 0.0 ) {
654
- p.z += state.a;
678
+ // Row 1:平移(z 已包含抬高)
679
+ vec4 r1 = s3mPickSample( vec2( u, 0.25 ) );
680
+ offset = r1.xyz;
681
+ if ( offset.z == 0.0 && state.a > 0.0 ) offset.z = state.a;
682
+
683
+ // Row 2/3/4:3x3 姿态矩阵(列优先)+ 轴心
684
+ vec4 r2 = s3mPickSample( vec2( u, 0.41666667 ) );
685
+ vec4 r3 = s3mPickSample( vec2( u, 0.58333333 ) );
686
+ vec4 r4 = s3mPickSample( vec2( u, 0.75 ) );
687
+ rot = mat3(
688
+ vec3( r2.x, r3.x, r4.x ),
689
+ vec3( r2.y, r3.y, r4.y ),
690
+ vec3( r2.z, r3.z, r4.z )
691
+ );
692
+ pivot = vec3( r2.w, r3.w, r4.w );
693
+
694
+ // Row 5:GPU 路径动画,与主着色器逐行对齐(含 loop / pingpong / clamp 与自动朝向)
695
+ if ( uPathTexActive > 0 && uPathCount > 0.0 ) {
696
+ vec4 r5 = s3mPickSample( vec2( u, 0.91666667 ) );
697
+ float pathId = r5.x;
698
+ float speed = r5.y;
699
+ float phase = r5.z;
700
+ float mode = r5.w;
701
+ if ( pathId >= 0.0 && mode > 0.5 ) {
702
+ float t = phase + uPathTime * speed;
703
+ bool autoHeading = true;
704
+ if ( mode >= 4.0 ) {
705
+ autoHeading = false;
706
+ mode -= 3.0;
707
+ }
708
+ if ( mode < 1.5 ) {
709
+ t = fract( t );
710
+ } else if ( mode < 2.5 ) {
711
+ t = clamp( t, 0.0, 1.0 );
712
+ } else {
713
+ t = mod( t, 2.0 );
714
+ t = ( t > 1.0 ) ? ( 2.0 - t ) : t;
715
+ }
716
+ vec4 pathSample = texture2D(
717
+ uPathTex,
718
+ vec2( ( t * 255.0 + 0.5 ) / 256.0, ( pathId + 0.5 ) / uPathCount )
719
+ );
720
+ if ( autoHeading ) {
721
+ float c = cos( pathSample.w );
722
+ float s = sin( pathSample.w );
723
+ // 列优先:(c, s) 是第 0 列 → 绕 Z 转 +yaw,与 StyleMaterial / EdgeLines 逐位一致
724
+ rot = mat3( c, s, 0.0, -s, c, 0.0, 0.0, 0.0, 1.0 ) * rot;
725
+ }
726
+ offset += pathSample.xyz;
727
+ }
655
728
  }
656
729
  }
657
730
  }
658
731
 
732
+ if ( hidden ) {
733
+ p = vec3( 0.0 );
734
+ } else {
735
+ p = rot * ( p - pivot ) + pivot + offset;
736
+ }
737
+
659
738
  // 选中单体自身的拔高(selectElevation)
660
739
  float sel = max( step( 0.0, uSelBatch ) * step( abs( s3mBatch - uSelBatch ), 0.5 ), uSelWhole );
661
740
  p.z += sel * uSelElevation;
@@ -682,7 +761,7 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
682
761
  floor( b / 256.0 ) / 255.0
683
762
  );
684
763
  }
685
- `,ha=(()=>{let e=new t.DataTexture(new Float32Array([-1,-1,-1,0,0,0,0,0]),1,2,t.RGBAFormat,t.FloatType);return e.minFilter=t.NearestFilter,e.magFilter=t.NearestFilter,e.needsUpdate=!0,e})();function ga(e){return new t.ShaderMaterial({uniforms:{uObjectId:{value:e},uBatchTex:{value:ha},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uSelBatch:{value:-1},uSelWhole:{value:0},uSelElevation:{value:0}},vertexShader:pa,fragmentShader:ma,side:t.DoubleSide,depthTest:!0,depthWrite:!0,toneMapped:!1})}function _a(e){return e.isPoints===!0}var va=class{constructor(e,t={}){v(this,`renderer`,void 0),v(this,`size`,void 0),v(this,`target`,null),v(this,`buf`,new Uint8Array(4)),this.renderer=e,this.size=Math.max(1,Math.floor(t.size??1))}_ensureTarget(e){return this.target&&this.target.width===e&&this.target.height===e||(this.target?.dispose(),this.target=new t.WebGLRenderTarget(e,e,{minFilter:t.NearestFilter,magFilter:t.NearestFilter,format:t.RGBAFormat,type:t.UnsignedByteType,depthBuffer:!0,stencilBuffer:!1}),this.target.texture.colorSpace=t.LinearSRGBColorSpace),this.target}pick(e,n,r,i){let a=this.renderer,o=a.domElement,s=o.width,c=o.height;if(!s||!c)return null;let l=Math.floor(r/o.clientWidth*s),u=Math.floor(i/o.clientHeight*c);if(l<0||u<0||l>=s||u>=c)return null;let d=this._ensureTarget(this.size),f=c-1-u,p=Math.floor(this.size/2),m=Math.floor(this.size/2);d.viewport.set(p-l,m-f,s,c);let h=a.getRenderTarget(),g=a.getViewport(new t.Vector4),_=a.toneMapping,v=a.outputColorSpace,y=a.autoClear,b=a.getClearColor(new t.Color),x=a.getClearAlpha(),S=[],C=new Set;e.traverseVisible(e=>{let t=e;if(!t.isMesh&&!_a(t))return;let n=t.userData;if(n.pickId===void 0)return;n.pickMaterial||(n.pickMaterial=ga(n.pickId)),t.isInstancedMesh&&C.add(n.pickId);let r=t.material,i=n.pickMaterial,a=Array.isArray(r)?r[0]:r,o=a?.userData?.uBatchTex;o?(i.uniforms.uBatchTex.value=o.value,i.uniforms.uBatchTexWidth.value=a?.userData?.uBatchTexWidth?.value??1,i.uniforms.uBatchTexActive.value=a?.userData?.uBatchTexActive?.value??0):(i.uniforms.uBatchTex.value=ha,i.uniforms.uBatchTexWidth.value=1,i.uniforms.uBatchTexActive.value=0),i.uniforms.uSelBatch.value=a?.userData?.uSelBatch?.value??-1,i.uniforms.uSelWhole.value=a?.userData?.uSelWhole?.value??0,i.uniforms.uSelElevation.value=a?.uniforms?.uSelElevation?.value??0,S.push([t,r]),t.material=i});let w=[];e.traverseVisible(e=>{let t=e;(t.isMesh||_a(t))&&t.userData.pickId===void 0&&(w.push(t),t.visible=!1)});let T=null;try{a.resetState(),a.setRenderTarget(d),a.toneMapping=t.NoToneMapping,a.outputColorSpace=t.LinearSRGBColorSpace,a.autoClear=!0,a.setClearColor(0,0),a.clear(),a.render(e,n),a.readRenderTargetPixels(d,p,m,1,1,this.buf);let r=this.buf[0],i=this.buf[1],o=this.buf[2],s=this.buf[3],c=r+i*256-1,l=o+s*256-1;c>=0&&(T=C.has(c)?{objectId:c,batchId:-1,instanceIndex:Math.max(0,l)}:{objectId:c,batchId:l})}finally{for(let[e,t]of S)e.material=t;for(let e of w)e.visible=!0;a.setRenderTarget(h),a.setViewport(g),a.toneMapping=_,a.outputColorSpace=v,a.autoClear=y,a.setClearColor(b,x),a.resetState()}return T}dispose(){this.target?.dispose(),this.target=null}},ya=1.70158,ba=ya*1.525,xa=2.70158,Sa=2*Math.PI/3,Ca=2*Math.PI/4.5,wa=7.5625,Ta=2.75;function Ea(e){if(e<1/Ta)return wa*e*e;if(e<2/Ta){let t=e-1.5/Ta;return wa*t*t+.75}if(e<2.5/Ta){let t=e-2.25/Ta;return wa*t*t+.9375}let t=e-2.625/Ta;return wa*t*t+.984375}function Da(e){return 1-Ea(1-e)}var Oa={linear:e=>e,easeInQuad:e=>e*e,easeOutQuad:e=>1-(1-e)*(1-e),easeInOutQuad:e=>e<.5?2*e*e:1-(-2*e+2)**2/2,easeInCubic:e=>e*e*e,easeOutCubic:e=>1-(1-e)**3,easeInOutCubic:e=>e<.5?4*e*e*e:1-(-2*e+2)**3/2,easeInQuart:e=>e*e*e*e,easeOutQuart:e=>1-(1-e)**4,easeInOutQuart:e=>e<.5?8*e*e*e*e:1-(-2*e+2)**4/2,easeInQuint:e=>e*e*e*e*e,easeOutQuint:e=>1-(1-e)**5,easeInOutQuint:e=>e<.5?16*e*e*e*e*e:1-(-2*e+2)**5/2,easeInSine:e=>1-Math.cos(e*Math.PI/2),easeOutSine:e=>Math.sin(e*Math.PI/2),easeInOutSine:e=>-(Math.cos(Math.PI*e)-1)/2,easeInExpo:e=>e===0?0:2**(10*e-10),easeOutExpo:e=>e===1?1:1-2**(-10*e),easeInOutExpo:e=>e===0?0:e===1?1:e<.5?2**(20*e-10)/2:(2-2**(-20*e+10))/2,easeInCirc:e=>1-Math.sqrt(1-e*e),easeOutCirc:e=>Math.sqrt(1-(e-1)**2),easeInOutCirc:e=>e<.5?(1-Math.sqrt(1-(2*e)**2))/2:(Math.sqrt(1-(-2*e+2)**2)+1)/2,easeInBack:e=>xa*e*e*e-ya*e*e,easeOutBack:e=>1+xa*(e-1)**3+ya*(e-1)**2,easeInOutBack:e=>e<.5?(2*e)**2*(7.189819*e-ba)/2:((2*e-2)**2*(3.5949095*(e*2-2)+ba)+2)/2,easeInElastic:e=>e===0?0:e===1?1:-(2**(10*e-10))*Math.sin((e*10-10.75)*Sa),easeOutElastic:e=>e===0?0:e===1?1:2**(-10*e)*Math.sin((e*10-.75)*Sa)+1,easeInOutElastic:e=>e===0?0:e===1?1:e<.5?-(2**(20*e-10)*Math.sin((20*e-11.125)*Ca))/2:2**(-20*e+10)*Math.sin((20*e-11.125)*Ca)/2+1,easeInBounce:Da,easeOutBounce:Ea,easeInOutBounce:e=>e<.5?(1-Da(1-2*e))/2:(1+Da(2*e-1))/2},ka=Object.keys(Oa);function Aa(e){if(typeof e==`function`)return e;let t=Oa[e];if(!t)throw Error(`[s3m] 未知的缓动曲线: ${String(e)}`);return t}var ja=8,Ma=.001,Na=1e-7,Pa=12,Fa=(e,t)=>1-3*t+3*e,Ia=(e,t)=>3*t-6*e,La=e=>3*e;function Ra(e,t,n){return((Fa(t,n)*e+Ia(t,n))*e+La(t))*e}function za(e,t,n){return 3*Fa(t,n)*e*e+2*Ia(t,n)*e+La(t)}function Ba(e,t,n,r){if(e===t&&n===r)return e=>e;let i=t=>{let r=t;for(let i=0;i<ja;i++){let i=za(r,e,n);if(Math.abs(i)<Ma)break;let a=Ra(r,e,n)-t;if(Math.abs(a)<Na)return r;r-=a/i}let i=0,a=1;r=t;for(let o=0;o<Pa;o++){let o=Ra(r,e,n);if(Math.abs(o-t)<Na)return r;o<t?i=r:a=r,r=(i+a)/2}return r};return e=>e<=0?0:e>=1?1:Ra(i(e),t,r)}function Va(e,t=`end`){let n=Math.max(1,Math.floor(e));return e=>{let r=Math.min(1,Math.max(0,e));return t===`start`?Math.min(1,(Math.floor(r*n)+1)/n):Math.min(1,Math.floor(r*n)/n)}}y();var Ha=1e-4,Ua=.15;function Wa(e){return e<0?0:e>1?1:e}function Ga(e,t,n){let r=0;for(let i=0;i<n;i++){let n=Math.abs(e[i]-t[i]);n>r&&(r=n)}return r}var Ka=class{constructor(e,t){v(this,`key`,void 0),v(this,`channel`,void 0),v(this,`dim`,void 0),v(this,`to`,new Float32Array(3)),v(this,`_cur`,new Float32Array(3)),v(this,`done`,!1),v(this,`onComplete`,void 0),this.key=e,this.channel=t,this.dim=t.dim}},qa=class extends Ka{constructor(...e){super(...e),v(this,`_from`,new Float32Array(3)),v(this,`_start`,0),v(this,`_duration`,0),v(this,`_delay`,0),v(this,`_ease`,Aa(`linear`)),v(this,`_retarget`,`proportional`),v(this,`_span`,0),v(this,`_progress`,0)}get progress(){return this._progress}start(e,t,n){n?this._from.set(n.subarray(0,this.dim)):this.channel.read(this._from),this._start=e,this._delay=Math.max(0,t.delay??0),this._duration=Math.max(0,t.duration??0),this._ease=t.easing?Aa(t.easing):Aa(`linear`),this._retarget=t.retarget??`proportional`,this._span=Ga(this._from,this.to,this.dim),this._progress=0,this.done=!1}advance(e){let t=e-this._start-this._delay,n=this._duration<=0?1:Wa(t/this._duration);this._progress=n;let r=this._ease(n);for(let e=0;e<this.dim;e++)this._cur[e]=this._from[e]+(this.to[e]-this._from[e])*r;this.channel.write(this._cur),n>=1&&(this.done=!0)}retarget(e,t,n){this.channel.read(this._from),this.to.set(e.subarray(0,this.dim));let r=Math.max(0,n.duration??this._duration),i=r;if((n.retarget??this._retarget)!==`fixed`&&this._span>Ha){let e=Ga(this._from,this.to,this.dim)/this._span;i=Math.min(r,Math.max(r*Ua,r*e))}this._start=t,this._delay=Math.max(0,n.delay??0),this._duration=i,this._ease=n.easing?Aa(n.easing):this._ease,this._span=Ga(this._from,this.to,this.dim),this._progress=0,this.done=!1}},Ja=class extends Ka{constructor(...e){super(...e),v(this,`_x0`,new Float32Array(3)),v(this,`_v0`,new Float32Array(3)),v(this,`_vel`,new Float32Array(3)),v(this,`_start`,0),v(this,`_k`,120),v(this,`_c`,14),v(this,`_eps`,.001),v(this,`_progress`,0)}get progress(){return this._progress}start(e,t,n){let r=t.spring??{stiffness:120,damping:14};this._k=Math.max(.001,r.stiffness),this._c=Math.max(0,r.damping),this._eps=r.epsilon??.001,n?this._x0.set(n.subarray(0,this.dim)):this.channel.read(this._x0),this._v0.fill(0),this._vel.fill(0),this._start=e,this.done=!1,this._progress=0}advance(e){let t=Math.max(0,(e-this._start)/1e3),n=!0;for(let e=0;e<this.dim;e++){let{x:r,v:i}=Ya(this._x0[e]-this.to[e],this._v0[e],this._k,this._c,t);this._cur[e]=this.to[e]+r,this._vel[e]=i,(Math.abs(r)>this._eps||Math.abs(i)>this._eps)&&(n=!1)}if(this.channel.write(this._cur),n){for(let e=0;e<this.dim;e++)this._cur[e]=this.to[e];this.channel.write(this._cur),this.done=!0,this._progress=1}}retarget(e,t,n){this.channel.read(this._cur);let r=n.spring;r&&(this._k=Math.max(.001,r.stiffness),this._c=Math.max(0,r.damping),this._eps=r.epsilon??this._eps);let i=Math.max(0,(t-this._start)/1e3);for(let t=0;t<this.dim;t++){let n=Ya(this._x0[t]-this.to[t],this._v0[t],this._k,this._c,i);this._x0[t]=this._cur[t]-e[t],this._v0[t]=n.v}this.to.set(e.subarray(0,this.dim)),this._start=t,this.done=!1}};function Ya(e,t,n,r,i){let a=Math.sqrt(n),o=r/(2*a);if(o<1){let n=a*Math.sqrt(1-o*o),r=Math.exp(-o*a*i),s=Math.cos(n*i),c=Math.sin(n*i),l=e,u=(t+o*a*e)/n;return{x:r*(l*s+u*c),v:r*((u*n-o*a*l)*s+(-l*n-o*a*u)*c)}}let s=Math.exp(-a*i),c=t+a*e;return{x:(e+c*i)*s,v:(t-a*c*i)*s}}var Xa=class{constructor(e=()=>performance.now()){v(this,`_channels`,new Map),v(this,`_tracks`,new Map),v(this,`_buf`,new Float32Array(3)),v(this,`_finished`,[]),v(this,`_now`,void 0),v(this,`_budgetMs`,2.5),v(this,`_lastTick`,-1/0),v(this,`_skipped`,0),v(this,`onActive`,void 0),this._now=e}set budgetMs(e){this._budgetMs=Math.max(0,e)}get budgetMs(){return this._budgetMs}get skippedLastTick(){return this._skipped}get activeCount(){return this._tracks.size}get active(){return this._tracks.size>0}register(e,t){this._channels.set(e,t)}unregister(e){this._channels.delete(e),this._tracks.delete(e)}unregisterPrefix(e){for(let t of[...this._channels.keys()])t.startsWith(e)&&(this._channels.delete(t),this._tracks.delete(t))}has(e){return this._channels.has(e)}isActive(e){return this._tracks.has(e)}to(e,t,n={}){let r=this._channels.get(e);if(!r)throw Error(`[s3m] 未注册的动画通道: ${e}`);let i=this._buf;if(r.dim===1)i[0]=typeof t==`number`?t:Number(t[0]),i[1]=0,i[2]=0;else{if(typeof t==`number`)throw Error(`[s3m] 通道 ${e} 需要三元数组目标值`);for(let e=0;e<3;e++)i[e]=Number(t[e]??0)}let a=!!n.spring,o=Math.max(0,n.duration??0);if(!a&&o<=0&&!n.delay){this._tracks.delete(e),r.write(i),this.onActive?.(),n.onComplete?.();return}let s=Math.max(this._now(),this._lastTick),c=this._tracks.get(e),l=a,u=c instanceof Ja;if(c&&c!=null&&u!==l&&(this._tracks.delete(e),c=void 0),c||this.onActive?.(),!c){let t=l?new Ja(e,r):new qa(e,r);t.to.set(i.subarray(0,r.dim)),t.onComplete=n.onComplete,t.start(s,n),this._tracks.set(e,t)}else c.to.set(i.subarray(0,r.dim)),c.onComplete=n.onComplete,c.retarget(i,s,n)}cancel(e){this._tracks.delete(e)}finish(e){let t=this._tracks.get(e);t&&(this._tracks.delete(e),t.channel.write(t.to),this.onActive?.(),t.onComplete?.())}clear(){this._tracks.clear()}tick(e=this._now()){if(this._tracks.size===0)return this._lastTick=Math.max(this._lastTick,e),!1;this._lastTick=Math.max(this._lastTick,e);let t=performance.now(),n=0;for(let r of this._tracks.values())if(r.advance(e),n++,r.done&&this._finished.push(r),performance.now()-t>=this._budgetMs)break;if(this._finished.length>0){for(let e of this._finished)this._tracks.get(e.key)===e&&this._tracks.delete(e.key);let e=this._finished.splice(0,this._finished.length);for(let t of e)t.onComplete?.()}return this._skipped=Math.max(0,this._tracks.size-n),this._tracks.size>0}};mi(),Yr();function Za(){return{uResolution:{value:new t.Vector2(1,1)},uDpr:{value:1}}}var Qa=`
764
+ `,ha=(()=>{let e=new t.DataTexture(new Float32Array([-1,-1,-1,0,0,0,0,0]),1,2,t.RGBAFormat,t.FloatType);return e.minFilter=t.NearestFilter,e.magFilter=t.NearestFilter,e.needsUpdate=!0,e})(),ga=(()=>{let e=new t.DataTexture(new Float32Array([0,0,0,0]),1,1,t.RGBAFormat,t.FloatType);return e.minFilter=t.NearestFilter,e.magFilter=t.NearestFilter,e.needsUpdate=!0,e})();function _a(e){return new t.ShaderMaterial({uniforms:{uObjectId:{value:e},uBatchTex:{value:ha},uBatchTex2:{value:ha},uBatchMix:{value:0},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uPathTex:{value:ga},uPathCount:{value:1},uPathTime:{value:0},uPathTexActive:{value:0},uSelBatch:{value:-1},uSelWhole:{value:0},uSelElevation:{value:0}},vertexShader:pa,fragmentShader:ma,side:t.DoubleSide,depthTest:!0,depthWrite:!0,toneMapped:!1})}function va(e){return e.isPoints===!0}var ya=class{constructor(e,t={}){v(this,`renderer`,void 0),v(this,`size`,void 0),v(this,`target`,null),v(this,`buf`,new Uint8Array(4)),this.renderer=e,this.size=Math.max(1,Math.floor(t.size??1))}_ensureTarget(e){return this.target&&this.target.width===e&&this.target.height===e||(this.target?.dispose(),this.target=new t.WebGLRenderTarget(e,e,{minFilter:t.NearestFilter,magFilter:t.NearestFilter,format:t.RGBAFormat,type:t.UnsignedByteType,depthBuffer:!0,stencilBuffer:!1}),this.target.texture.colorSpace=t.LinearSRGBColorSpace),this.target}pick(e,n,r,i){let a=this.renderer,o=a.domElement,s=o.width,c=o.height;if(!s||!c)return null;let l=Math.floor(r/o.clientWidth*s),u=Math.floor(i/o.clientHeight*c);if(l<0||u<0||l>=s||u>=c)return null;let d=this._ensureTarget(this.size),f=c-1-u,p=Math.floor(this.size/2),m=Math.floor(this.size/2);d.viewport.set(p-l,m-f,s,c);let h=a.getRenderTarget(),g=a.getViewport(new t.Vector4),_=a.toneMapping,v=a.outputColorSpace,y=a.autoClear,b=a.getClearColor(new t.Color),x=a.getClearAlpha(),S=[],C=new Set;e.traverseVisible(e=>{let t=e;if(!t.isMesh&&!va(t))return;let n=t.userData;if(n.pickId===void 0)return;n.pickMaterial||(n.pickMaterial=_a(n.pickId)),t.isInstancedMesh&&C.add(n.pickId);let r=t.material,i=n.pickMaterial,a=Array.isArray(r)?r[0]:r,o=a?.userData?.uBatchTex;o?(i.uniforms.uBatchTex.value=o.value,i.uniforms.uBatchTex2.value=a?.userData?.uBatchTex2?.value??o.value,i.uniforms.uBatchTexWidth.value=a?.userData?.uBatchTexWidth?.value??1,i.uniforms.uBatchTexActive.value=a?.userData?.uBatchTexActive?.value??0):(i.uniforms.uBatchTex.value=ha,i.uniforms.uBatchTex2.value=ha,i.uniforms.uBatchTexWidth.value=1,i.uniforms.uBatchTexActive.value=0),i.uniforms.uBatchMix.value=a?.userData?.uBatchMix?.value??0,i.uniforms.uPathTex.value=a?.userData?.uPathTex?.value??ga,i.uniforms.uPathCount.value=a?.userData?.uPathCount?.value??1,i.uniforms.uPathTime.value=a?.userData?.uPathTime?.value??0,i.uniforms.uPathTexActive.value=a?.userData?.uPathTexActive?.value??0,i.uniforms.uSelBatch.value=a?.userData?.uSelBatch?.value??-1,i.uniforms.uSelWhole.value=a?.userData?.uSelWhole?.value??0,i.uniforms.uSelElevation.value=a?.userData?.uSelElevation?.value??a?.uniforms?.uSelElevation?.value??0,S.push([t,r]),t.material=i});let w=[];e.traverseVisible(e=>{let t=e;(t.isMesh||va(t))&&t.userData.pickId===void 0&&(w.push(t),t.visible=!1)});let T=null;try{a.resetState(),a.setRenderTarget(d),a.toneMapping=t.NoToneMapping,a.outputColorSpace=t.LinearSRGBColorSpace,a.autoClear=!0,a.setClearColor(0,0),a.clear(),a.render(e,n),a.readRenderTargetPixels(d,p,m,1,1,this.buf);let r=this.buf[0],i=this.buf[1],o=this.buf[2],s=this.buf[3],c=r+i*256-1,l=o+s*256-1;c>=0&&(T=C.has(c)?{objectId:c,batchId:-1,instanceIndex:Math.max(0,l)}:{objectId:c,batchId:l})}finally{for(let[e,t]of S)e.material=t;for(let e of w)e.visible=!0;a.setRenderTarget(h),a.setViewport(g),a.toneMapping=_,a.outputColorSpace=v,a.autoClear=y,a.setClearColor(b,x),a.resetState()}return T}dispose(){this.target?.dispose(),this.target=null}},ba=1.70158,xa=ba*1.525,Sa=2.70158,Ca=2*Math.PI/3,wa=2*Math.PI/4.5,Ta=7.5625,Ea=2.75;function Da(e){if(e<1/Ea)return Ta*e*e;if(e<2/Ea){let t=e-1.5/Ea;return Ta*t*t+.75}if(e<2.5/Ea){let t=e-2.25/Ea;return Ta*t*t+.9375}let t=e-2.625/Ea;return Ta*t*t+.984375}function Oa(e){return 1-Da(1-e)}var ka={linear:e=>e,easeInQuad:e=>e*e,easeOutQuad:e=>1-(1-e)*(1-e),easeInOutQuad:e=>e<.5?2*e*e:1-(-2*e+2)**2/2,easeInCubic:e=>e*e*e,easeOutCubic:e=>1-(1-e)**3,easeInOutCubic:e=>e<.5?4*e*e*e:1-(-2*e+2)**3/2,easeInQuart:e=>e*e*e*e,easeOutQuart:e=>1-(1-e)**4,easeInOutQuart:e=>e<.5?8*e*e*e*e:1-(-2*e+2)**4/2,easeInQuint:e=>e*e*e*e*e,easeOutQuint:e=>1-(1-e)**5,easeInOutQuint:e=>e<.5?16*e*e*e*e*e:1-(-2*e+2)**5/2,easeInSine:e=>1-Math.cos(e*Math.PI/2),easeOutSine:e=>Math.sin(e*Math.PI/2),easeInOutSine:e=>-(Math.cos(Math.PI*e)-1)/2,easeInExpo:e=>e===0?0:2**(10*e-10),easeOutExpo:e=>e===1?1:1-2**(-10*e),easeInOutExpo:e=>e===0?0:e===1?1:e<.5?2**(20*e-10)/2:(2-2**(-20*e+10))/2,easeInCirc:e=>1-Math.sqrt(1-e*e),easeOutCirc:e=>Math.sqrt(1-(e-1)**2),easeInOutCirc:e=>e<.5?(1-Math.sqrt(1-(2*e)**2))/2:(Math.sqrt(1-(-2*e+2)**2)+1)/2,easeInBack:e=>Sa*e*e*e-ba*e*e,easeOutBack:e=>1+Sa*(e-1)**3+ba*(e-1)**2,easeInOutBack:e=>e<.5?(2*e)**2*(7.189819*e-xa)/2:((2*e-2)**2*(3.5949095*(e*2-2)+xa)+2)/2,easeInElastic:e=>e===0?0:e===1?1:-(2**(10*e-10))*Math.sin((e*10-10.75)*Ca),easeOutElastic:e=>e===0?0:e===1?1:2**(-10*e)*Math.sin((e*10-.75)*Ca)+1,easeInOutElastic:e=>e===0?0:e===1?1:e<.5?-(2**(20*e-10)*Math.sin((20*e-11.125)*wa))/2:2**(-20*e+10)*Math.sin((20*e-11.125)*wa)/2+1,easeInBounce:Oa,easeOutBounce:Da,easeInOutBounce:e=>e<.5?(1-Oa(1-2*e))/2:(1+Oa(2*e-1))/2},Aa=Object.keys(ka);function ja(e){if(typeof e==`function`)return e;let t=ka[e];if(!t)throw Error(`[s3m] 未知的缓动曲线: ${String(e)}`);return t}var Ma=8,Na=.001,Pa=1e-7,Fa=12,Ia=(e,t)=>1-3*t+3*e,La=(e,t)=>3*t-6*e,Ra=e=>3*e;function za(e,t,n){return((Ia(t,n)*e+La(t,n))*e+Ra(t))*e}function Ba(e,t,n){return 3*Ia(t,n)*e*e+2*La(t,n)*e+Ra(t)}function Va(e,t,n,r){if(e===t&&n===r)return e=>e;let i=t=>{let r=t;for(let i=0;i<Ma;i++){let i=Ba(r,e,n);if(Math.abs(i)<Na)break;let a=za(r,e,n)-t;if(Math.abs(a)<Pa)return r;r-=a/i}let i=0,a=1;r=t;for(let o=0;o<Fa;o++){let o=za(r,e,n);if(Math.abs(o-t)<Pa)return r;o<t?i=r:a=r,r=(i+a)/2}return r};return e=>e<=0?0:e>=1?1:za(i(e),t,r)}function Ha(e,t=`end`){let n=Math.max(1,Math.floor(e));return e=>{let r=Math.min(1,Math.max(0,e));return t===`start`?Math.min(1,(Math.floor(r*n)+1)/n):Math.min(1,Math.floor(r*n)/n)}}y();var Ua=1e-4,Wa=.15;function Ga(e){return e<0?0:e>1?1:e}function Ka(e,t,n){let r=0;for(let i=0;i<n;i++){let n=Math.abs(e[i]-t[i]);n>r&&(r=n)}return r}var qa=class{constructor(e,t){v(this,`key`,void 0),v(this,`channel`,void 0),v(this,`dim`,void 0),v(this,`to`,new Float32Array(3)),v(this,`_cur`,new Float32Array(3)),v(this,`done`,!1),v(this,`onComplete`,void 0),this.key=e,this.channel=t,this.dim=t.dim}},Ja=class extends qa{constructor(...e){super(...e),v(this,`_from`,new Float32Array(3)),v(this,`_start`,0),v(this,`_duration`,0),v(this,`_delay`,0),v(this,`_ease`,ja(`linear`)),v(this,`_retarget`,`proportional`),v(this,`_span`,0),v(this,`_progress`,0)}get progress(){return this._progress}start(e,t,n){n?this._from.set(n.subarray(0,this.dim)):this.channel.read(this._from),this._start=e,this._delay=Math.max(0,t.delay??0),this._duration=Math.max(0,t.duration??0),this._ease=t.easing?ja(t.easing):ja(`linear`),this._retarget=t.retarget??`proportional`,this._span=Ka(this._from,this.to,this.dim),this._progress=0,this.done=!1}advance(e){let t=e-this._start-this._delay,n=this._duration<=0?1:Ga(t/this._duration);this._progress=n;let r=this._ease(n);for(let e=0;e<this.dim;e++)this._cur[e]=this._from[e]+(this.to[e]-this._from[e])*r;this.channel.write(this._cur),n>=1&&(this.done=!0)}retarget(e,t,n){this.channel.read(this._from),this.to.set(e.subarray(0,this.dim));let r=Math.max(0,n.duration??this._duration),i=r;if((n.retarget??this._retarget)!==`fixed`&&this._span>Ua){let e=Ka(this._from,this.to,this.dim)/this._span;i=Math.min(r,Math.max(r*Wa,r*e))}this._start=t,this._delay=Math.max(0,n.delay??0),this._duration=i,this._ease=n.easing?ja(n.easing):this._ease,this._span=Ka(this._from,this.to,this.dim),this._progress=0,this.done=!1}},Ya=class extends qa{constructor(...e){super(...e),v(this,`_x0`,new Float32Array(3)),v(this,`_v0`,new Float32Array(3)),v(this,`_vel`,new Float32Array(3)),v(this,`_start`,0),v(this,`_k`,120),v(this,`_c`,14),v(this,`_eps`,.001),v(this,`_progress`,0)}get progress(){return this._progress}start(e,t,n){let r=t.spring??{stiffness:120,damping:14};this._k=Math.max(.001,r.stiffness),this._c=Math.max(0,r.damping),this._eps=r.epsilon??.001,n?this._x0.set(n.subarray(0,this.dim)):this.channel.read(this._x0),this._v0.fill(0),this._vel.fill(0),this._start=e,this.done=!1,this._progress=0}advance(e){let t=Math.max(0,(e-this._start)/1e3),n=!0;for(let e=0;e<this.dim;e++){let{x:r,v:i}=Xa(this._x0[e]-this.to[e],this._v0[e],this._k,this._c,t);this._cur[e]=this.to[e]+r,this._vel[e]=i,(Math.abs(r)>this._eps||Math.abs(i)>this._eps)&&(n=!1)}if(this.channel.write(this._cur),n){for(let e=0;e<this.dim;e++)this._cur[e]=this.to[e];this.channel.write(this._cur),this.done=!0,this._progress=1}}retarget(e,t,n){this.channel.read(this._cur);let r=n.spring;r&&(this._k=Math.max(.001,r.stiffness),this._c=Math.max(0,r.damping),this._eps=r.epsilon??this._eps);let i=Math.max(0,(t-this._start)/1e3);for(let t=0;t<this.dim;t++){let n=Xa(this._x0[t]-this.to[t],this._v0[t],this._k,this._c,i);this._x0[t]=this._cur[t]-e[t],this._v0[t]=n.v}this.to.set(e.subarray(0,this.dim)),this._start=t,this.done=!1}};function Xa(e,t,n,r,i){let a=Math.sqrt(n),o=r/(2*a);if(o<1){let n=a*Math.sqrt(1-o*o),r=Math.exp(-o*a*i),s=Math.cos(n*i),c=Math.sin(n*i),l=e,u=(t+o*a*e)/n;return{x:r*(l*s+u*c),v:r*((u*n-o*a*l)*s+(-l*n-o*a*u)*c)}}let s=Math.exp(-a*i),c=t+a*e;return{x:(e+c*i)*s,v:(t-a*c*i)*s}}var Za=class{constructor(e=()=>performance.now()){v(this,`_channels`,new Map),v(this,`_tracks`,new Map),v(this,`_buf`,new Float32Array(3)),v(this,`_finished`,[]),v(this,`_now`,void 0),v(this,`_budgetMs`,2.5),v(this,`_lastTick`,-1/0),v(this,`_skipped`,0),v(this,`onActive`,void 0),this._now=e}set budgetMs(e){this._budgetMs=Math.max(0,e)}get budgetMs(){return this._budgetMs}get skippedLastTick(){return this._skipped}get activeCount(){return this._tracks.size}get active(){return this._tracks.size>0}register(e,t){this._channels.set(e,t)}unregister(e){this._channels.delete(e),this._tracks.delete(e)}unregisterPrefix(e){for(let t of[...this._channels.keys()])t.startsWith(e)&&(this._channels.delete(t),this._tracks.delete(t))}has(e){return this._channels.has(e)}isActive(e){return this._tracks.has(e)}to(e,t,n={}){let r=this._channels.get(e);if(!r)throw Error(`[s3m] 未注册的动画通道: ${e}`);let i=this._buf;if(r.dim===1)i[0]=typeof t==`number`?t:Number(t[0]),i[1]=0,i[2]=0;else{if(typeof t==`number`)throw Error(`[s3m] 通道 ${e} 需要三元数组目标值`);for(let e=0;e<3;e++)i[e]=Number(t[e]??0)}let a=!!n.spring,o=Math.max(0,n.duration??0);if(!a&&o<=0&&!n.delay){this._tracks.delete(e),r.write(i),this.onActive?.(),n.onComplete?.();return}let s=Math.max(this._now(),this._lastTick),c=this._tracks.get(e),l=a,u=c instanceof Ya;if(c&&c!=null&&u!==l&&(this._tracks.delete(e),c=void 0),c||this.onActive?.(),!c){let t=l?new Ya(e,r):new Ja(e,r);t.to.set(i.subarray(0,r.dim)),t.onComplete=n.onComplete,t.start(s,n),this._tracks.set(e,t)}else c.to.set(i.subarray(0,r.dim)),c.onComplete=n.onComplete,c.retarget(i,s,n)}cancel(e){this._tracks.delete(e)}finish(e){let t=this._tracks.get(e);t&&(this._tracks.delete(e),t.channel.write(t.to),this.onActive?.(),t.onComplete?.())}clear(){this._tracks.clear()}tick(e=this._now()){if(this._tracks.size===0)return this._lastTick=Math.max(this._lastTick,e),!1;this._lastTick=Math.max(this._lastTick,e);let t=performance.now(),n=0;for(let r of this._tracks.values())if(r.advance(e),n++,r.done&&this._finished.push(r),performance.now()-t>=this._budgetMs)break;if(this._finished.length>0){for(let e of this._finished)this._tracks.get(e.key)===e&&this._tracks.delete(e.key);let e=this._finished.splice(0,this._finished.length);for(let t of e)t.onComplete?.()}return this._skipped=Math.max(0,this._tracks.size-n),this._tracks.size>0}};mi(),Yr();function Qa(){return{uResolution:{value:new t.Vector2(1,1)},uDpr:{value:1}}}var $a=`
686
765
  attribute vec3 aOther;
687
766
  attribute float aSide;
688
767
  attribute float aBatchId;
@@ -771,9 +850,12 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
771
850
  if ( autoHeading ) {
772
851
  float c = cos( pathYaw );
773
852
  float s = sin( pathYaw );
853
+
854
+ // GLSL 的 mat3 是列优先:下面两行是「第 0 列 = (c, s)」,等价于绕 Z 转 +yaw,
855
+ // 把模型 +X 朝向对到切线方向(yaw = atan2(dy, dx))。写成 (c,-s; s,c) 会左右镜像。
774
856
  mat3 rotHeading = mat3(
775
- c, -s, 0.0,
776
- s, c, 0.0,
857
+ c, s, 0.0,
858
+ -s, c, 0.0,
777
859
  0.0, 0.0, 1.0
778
860
  );
779
861
  s3mRot = rotHeading * s3mRot;
@@ -813,7 +895,7 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
813
895
 
814
896
  gl_Position = vec4( ndc * clipA.w, clipA.z, clipA.w );
815
897
  }
816
- `,$a=`
898
+ `,eo=`
817
899
  uniform vec3 uColor;
818
900
  uniform float uOpacity;
819
901
 
@@ -821,9 +903,9 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
821
903
  if ( uOpacity <= 0.003 ) discard;
822
904
  gl_FragColor = vec4( uColor, uOpacity );
823
905
  }
824
- `;function eo(e,n={},r,i){let a=r??{uColor:{value:new t.Color(n.color??`#ffffff`)},uOpacity:{value:n.opacity??1},uWidth:{value:n.width??1.5},uElevation:{value:n.elevation??0}};n.color!==void 0&&r&&a.uColor.value.set(n.color),n.opacity!==void 0&&r&&(a.uOpacity.value=n.opacity),n.width!==void 0&&r&&(a.uWidth.value=n.width);let o={uBatchTex:i?.uBatchTex??{value:ri},uBatchTex2:i?.uBatchTex2??{value:ri},uBatchMix:i?.uBatchMix??{value:0},uBatchTexWidth:i?.uBatchTexWidth??{value:1},uBatchTexActive:i?.uBatchTexActive??{value:0},uPathTex:i?.uPathTex??{value:Jr.DUMMY_PATH_TEX},uPathCount:i?.uPathCount??{value:1},uPathTexActive:i?.uPathTexActive??{value:0},uPathTime:i?.uPathTime??{value:0}},s=new t.ShaderMaterial({uniforms:{uResolution:e.uResolution,uDpr:e.uDpr,uColor:a.uColor,uOpacity:a.uOpacity,uWidth:a.uWidth,uElevation:a.uElevation??{value:n.elevation??0},uTranslation:{value:new t.Vector3(0,0,0)},uBatchTex:o.uBatchTex,uBatchTex2:o.uBatchTex2,uBatchMix:o.uBatchMix,uBatchTexWidth:o.uBatchTexWidth,uBatchTexActive:o.uBatchTexActive,uPathTex:o.uPathTex,uPathCount:o.uPathCount,uPathTexActive:o.uPathTexActive,uPathTime:o.uPathTime},vertexShader:Qa,fragmentShader:$a,transparent:!0,depthWrite:!1,side:t.DoubleSide,polygonOffset:!0,polygonOffsetFactor:-2,polygonOffsetUnits:-2});return s.userData.isThickLine=!0,s}function to(e,n){let r=Math.floor(e.length/6),i=r*4,a=new Float32Array(i*3),o=new Float32Array(i*3),s=new Float32Array(i),c=new Float32Array(i),l=i>65535?new Uint32Array(r*6):new Uint16Array(r*6);for(let t=0;t<r;t++){let r=t*6,i=e[r],a=e[r+1],o=e[r+2],s=e[r+3],d=e[r+4],f=e[r+5],p=n?Number(n[t]??-1):-1,m=t*4;u(m,i,a,o,s,d,f,-1),u(m+1,i,a,o,s,d,f,1),u(m+2,s,d,f,i,a,o,1),u(m+3,s,d,f,i,a,o,-1);for(let e=0;e<4;e++)c[m+e]=p;let h=t*6;l[h]=m,l[h+1]=m+1,l[h+2]=m+2,l[h+3]=m,l[h+4]=m+2,l[h+5]=m+3}function u(e,t,n,r,i,c,l,u){let d=e*3;a[d]=t,a[d+1]=n,a[d+2]=r,o[d]=i,o[d+1]=c,o[d+2]=l,s[e]=u}let d=new t.BufferGeometry;return d.setAttribute(`position`,new t.BufferAttribute(a,3)),d.setAttribute(`aOther`,new t.BufferAttribute(o,3)),d.setAttribute(`aSide`,new t.BufferAttribute(s,1)),d.setAttribute(`aBatchId`,new t.BufferAttribute(c,1)),d.setIndex(new t.BufferAttribute(l,1)),d.computeBoundingSphere(),d}function no(e,t){let n=e.getAttribute(`position`),r=e.getAttribute(`aBatchId`);if(!n||!r||n.count===0||n.count!==r.count)return null;let i=1/Math.max(t,1e-9),a=new Map;for(let e=0;e<n.count;e++){let t=ro(n.getX(e),n.getY(e),n.getZ(e),i);a.has(t)||a.set(t,r.getX(e))}return a.size>0?a:null}function ro(e,t,n,r){return`${Math.round(e*r)},${Math.round(t*r)},${Math.round(n*r)}`}var io=6e4,ao=100;function oo(e,t,n=40){let r=e.getAttribute(`position`);if(!r)return null;let i=r.count;if(i<3)return null;let a=new Float32Array(i),o=new Float32Array(i),s=new Float32Array(i);for(let e=0;e<i;e++)a[e]=r.getX(e),o[e]=r.getY(e),s[e]=r.getZ(e);let c=null,l=null;if(!e.index){let e=new Map;c=new Uint32Array(i),l=new Uint32Array(i);let t=0;for(let n=0;n<i;n++){let r=`${Math.round(a[n]*ao)},${Math.round(o[n]*ao)},${Math.round(s[n]*ao)}`,i=e.get(r);i===void 0&&(i=t++,e.set(r,i),l[i]=n),c[n]=i}}let u=e=>c?c[e]:e,d=e=>l?l[e]:e,f=e.index,p=f?f.array:null,m=Math.floor(f?f.count/3:i/3);if(m<1)return null;let h=null;if(t&&t.length>0){h=new Uint8Array(i);for(let e of t){let t=Math.max(0,e.vertexOffset|0),n=Math.min(i,t+(e.vertexCount|0));n>t&&h.fill(1,t,n)}if(!h.includes(1))return null}let g=new Float32Array(m*3),_=new Map,v=i+1,y=[],b=Math.cos(n*Math.PI/180),x=-1,S=0,C=0,w=0,T=(e,t)=>{if(y.length>=io*6)return!1;let n=d(e),r=d(t);return y.push(a[n],o[n],s[n],a[r],o[r],s[r]),!0},E=(e,t)=>{if(e===t)return;let n=e<t?e:t,r=e<t?t:e,i=n*v+r,a=_.get(i);a===void 0?_.set(i,x):a<0||(S*g[a*3]+C*g[a*3+1]+w*g[a*3+2]<b?(T(n,r),_.set(i,-1)):_.set(i,-2))};for(x=0;x<m;x++){let e=p?p[x*3]:x*3,t=p?p[x*3+1]:x*3+1,n=p?p[x*3+2]:x*3+2;if(h&&!(h[e]&&h[t]&&h[n]))continue;let r=a[t]-a[e],i=o[t]-o[e],c=s[t]-s[e],l=a[n]-a[e],d=o[n]-o[e],f=s[n]-s[e];S=i*f-c*d,C=c*l-r*f,w=r*d-i*l;let m=Math.hypot(S,C,w);m<1e-12||(S/=m,C/=m,w/=m,g[x*3]=S,g[x*3+1]=C,g[x*3+2]=w,E(u(e),u(t)),E(u(t),u(n)),E(u(n),u(e)))}for(let[e,t]of _){if(t<0)continue;let n=Math.floor(e/v);if(!T(n,e-n*v))break}return y.length>0?new Float32Array(y):null}function so(e,t,n,r){return`${Math.round(e*r)},${Math.round(t*r)},${Math.round(n*r)}`}function co(e,n){let r=e.getAttribute(`position`);if(!r||r.count===0)return e;let i=1/Math.max(n,1e-9),a=new Map,o=[],s=new Int32Array(r.count);for(let e=0;e<r.count;e++){let t=r.getX(e),n=r.getY(e),c=r.getZ(e),l=so(t,n,c,i),u=a.get(l);u===void 0&&(u=o.length/3,o.push(t,n,c),a.set(l,u)),s[e]=u}let c=e.getIndex(),l=c?c.count:r.count,u=new Uint32Array(l);for(let e=0;e<l;e++)u[e]=s[c?c.getX(e):e];let d=new t.BufferGeometry;return d.setAttribute(`position`,new t.Float32BufferAttribute(o,3)),d.setIndex(new t.BufferAttribute(u,1)),d}y();var lo=class{constructor(){v(this,`datasets`,new Map),v(this,`sceneAnchor`,null),v(this,`totalMaxTiles`,0)}get(e){return this.datasets.get(e)}values(){return this.datasets.values()}registerDataset(e){let n=this.datasets.get(e.id);if(n)return n;let r=new t.Group;r.name=`s3m-dataset:${e.id}`,r.visible=e.visible!==!1;let i={id:e.id,name:e.name??e.id,options:e,root:r,tileset:null,anchor:null,baseAlignOffset:0,userOffset:e.heightOffset??0,heightOffset:e.heightOffset??0,offset:[0,0,0],visible:e.visible!==!1,error:null};return this.datasets.set(e.id,i),this.rebalanceBudgets(),i}rebalanceBudgets(e){let t=e??this.totalMaxTiles;if(!t||t<=0)return;this.totalMaxTiles=t;let n=Array.from(this.datasets.values()).filter(e=>e.visible&&e.tileset),r=Math.max(1,n.length),i=Math.max(8,Math.floor(t/r));for(let e of this.datasets.values())e.tileset&&(e.visible?(e.tileset.maxTiles=i,e.tileset.hardCap=i+Math.max(4,Math.ceil(i*.5))):(e.tileset.maxTiles=Math.min(4,e.tileset.maxTiles),e.tileset.hardCap=Math.min(6,e.tileset.hardCap)))}computeAlignOffset(e,t){if(!t||t===`origin`||!e)return 0;let n=e.heightRange;if(!n)return 0;switch(t){case`top`:return-n.max;case`bottom`:return-n.min;case`center`:return-(n.min+n.max)/2;default:return 0}}async addDataset(e,n,r,i,a,o,s,c,l){let u=this.datasets.get(e.id);if(u)return u;let d=new t.Group;d.name=`s3m-dataset:${e.id}`,d.visible=e.visible!==!1,n.add(d);let f={id:e.id,name:e.name??e.id,options:e,root:d,tileset:null,anchor:null,baseAlignOffset:0,userOffset:e.heightOffset??0,heightOffset:e.heightOffset??0,offset:[0,0,0],visible:e.visible!==!1,error:null};this.datasets.set(e.id,f);let p=new ia({configUrl:e.configUrl,maxTiles:e.maxTiles??s,maxConcurrent:c,lodRangeScale:e.lodRangeScale??a,buildTile:o??null,useWorker:e.useWorker,uniforms:i,onTile:e=>{l.onTile(e,f)},onTileRemoved:e=>{l.onTileRemoved(e,f)},onProgress:()=>{l.onStats(),l.triggerRepaint()},onError:e=>{f.error=e,l.onError(e),l.onStats()}});f.tileset=p,this.rebalanceBudgets();try{await p.init()}catch(e){return f.error=e,l.onError(e),f}return f.anchor=p.anchor,f.baseAlignOffset=this.computeAlignOffset(p,e.align),f.userOffset=e.heightOffset??0,f.heightOffset=f.baseAlignOffset+f.userOffset,this.layoutDataset(f,r),l.onReady(f),l.triggerRepaint(),f}removeDataset(e,t,n,r){let i=this.datasets.get(e);return i?(r(i),i.tileset?.dispose(),t.remove(i.root),this.datasets.delete(e),this.rebalanceBudgets(),this.datasets.size>0?this.recomputeAnchors(n):this.sceneAnchor=null,!0):!1}clearDatasets(e,t){for(let n of this.datasets.values())t(n),n.tileset?.dispose(),e.remove(n.root);this.datasets.clear(),this.sceneAnchor=null}layoutDataset(e,t){if(!e.anchor)return;this.sceneAnchor||(this.sceneAnchor=Pt(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0));let n=this.sceneAnchor.meterInMercator,r=Pt(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0);e.offset=[(r.x-this.sceneAnchor.x)/n,-(r.y-this.sceneAnchor.y)/n,(r.z-this.sceneAnchor.z)/n+(e.heightOffset??0)],e.root.position.set(e.offset[0],e.offset[1],e.offset[2]),e.root.updateMatrixWorld(!0)}recomputeAnchors(e){if(this.datasets.size!==0){this.sceneAnchor=null;for(let t of this.datasets.values())this.layoutDataset(t,e)}}getDatasetHeight(e){let t=e??this.datasets.keys().next().value;return t?this.datasets.get(t)?.userOffset??0:0}setDatasetHeight(e,t,n){let r=this.datasets.get(e);r&&(r.userOffset=t,r.heightOffset=r.baseAlignOffset+t,this.layoutDataset(r,n))}setDatasetAlign(e,t,n){let r=this.datasets.get(e);if(!r)return;let i=r.heightOffset-r.baseAlignOffset;r.baseAlignOffset=this.computeAlignOffset(r.tileset,t),r.userOffset=i,r.heightOffset=r.baseAlignOffset+i,r.options.align=t,this.layoutDataset(r,n)}setDatasetVisible(e,t){let n=this.datasets.get(e);n&&(n.visible=t,n.root.visible=t,this.rebalanceBudgets())}getBounds(){let e=1/0,t=1/0,n=-1/0,r=-1/0,i=!1;for(let a of this.datasets.values()){if(!a.visible||!a.tileset?.config)continue;let o=ta(a.tileset.config.geoBounds);o&&(e=Math.min(e,o.left),t=Math.min(t,o.bottom),n=Math.max(n,o.right),r=Math.max(r,o.top),i=!0)}return i?[[e,t],[n,r]]:null}};Tt(),y();function uo(e){if(e==null)return null;if(typeof e==`number`){let t=Math.cos(e),n=Math.sin(e);return[t,-n,0,n,t,0,0,0,1]}if(Array.isArray(e)){if(e.length===3){let n=new t.Euler(e[0],e[1],e[2]),r=new t.Matrix4().makeRotationFromEuler(n).elements;return[r[0],r[4],r[8],r[1],r[5],r[9],r[2],r[6],r[10]]}if(e.length===4){let n=new t.Quaternion(e[0],e[1],e[2],e[3]),r=new t.Matrix4().makeRotationFromQuaternion(n).elements;return[r[0],r[4],r[8],r[1],r[5],r[9],r[2],r[6],r[10]]}}if(e instanceof t.Euler){let n=new t.Matrix4().makeRotationFromEuler(e).elements;return[n[0],n[4],n[8],n[1],n[5],n[9],n[2],n[6],n[10]]}if(e instanceof t.Quaternion){let n=new t.Matrix4().makeRotationFromQuaternion(e).elements;return[n[0],n[4],n[8],n[1],n[5],n[9],n[2],n[6],n[10]]}if(e instanceof t.Matrix3){let t=e.elements;return[t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8]]}if(e instanceof t.Matrix4){let t=e.elements;return[t[0],t[4],t[8],t[1],t[5],t[9],t[2],t[6],t[10]]}return null}function fo(e){if(e==null)return[0,0,0];if(typeof e==`number`)return[0,0,e];if(Array.isArray(e)){if(e.length===3)return[e[0],e[1],e[2]];if(e.length===4){let n=new t.Quaternion(e[0],e[1],e[2],e[3]),r=new t.Euler().setFromQuaternion(n);return[r.x,r.y,r.z]}}if(e instanceof t.Euler)return[e.x,e.y,e.z];if(e instanceof t.Quaternion){let n=new t.Euler().setFromQuaternion(e);return[n.x,n.y,n.z]}if(e instanceof t.Matrix3){let n=new t.Matrix4().set(e.elements[0],e.elements[3],e.elements[6],0,e.elements[1],e.elements[4],e.elements[7],0,e.elements[2],e.elements[5],e.elements[8],0,0,0,0,1),r=new t.Euler().setFromRotationMatrix(n);return[r.x,r.y,r.z]}if(e instanceof t.Matrix4){let n=new t.Euler().setFromRotationMatrix(e);return[n.x,n.y,n.z]}return[0,0,0]}function po(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function mo(e,t){if(e.length<2)return e[0].clone();let n=Math.min(1,Math.max(0,t))*(e.length-1),r=Math.min(e.length-2,Math.floor(n));return e[r].clone().lerp(e[r+1],n-r)}function ho(e,t,n){if(n.keep&&!n.keep(e,t))return!1;if(n.values?.length){let t=e==null?``:String(e);if(!n.values.some(e=>String(e)===t))return!1}if(n.min!=null||n.max!=null){let t=Number(e);if(!Number.isFinite(t)||n.min!=null&&t<n.min||n.max!=null&&t>n.max)return!1}return!n.keep&&!n.values?.length&&n.min==null&&n.max==null?e!=null&&String(e)!==``:!0}function go(e){if(!Number.isFinite(e))return`—`;let t=Math.abs(e);return t>=100?e.toFixed(0):t>=10?e.toFixed(1):e.toFixed(2)}var _o=class{constructor(e,t,n,r,i,a=()=>!1){v(this,`_getLayerFloorHeight`,void 0),v(this,`_triggerRepaint`,void 0),v(this,`_onStyleChanged`,void 0),v(this,`_getAllMeshes`,void 0),v(this,`_applyOverrideHook`,void 0),v(this,`_isLayerTransparent`,void 0),v(this,`featureStyles`,new Map),v(this,`thematicColors`,new Map),v(this,`thematicElevation`,new Map),v(this,`thematicField`,null),v(this,`elevationField`,null),v(this,`filter`,null),v(this,`fieldFilter`,null),v(this,`_meshBatchTextures`,new WeakMap),v(this,`_markedMeshes`,new Set),v(this,`_dirtyAll`,!1),v(this,`_flushScheduled`,!1),v(this,`_batchConflictWarned`,!1),this._getLayerFloorHeight=e,this._triggerRepaint=t,this._onStyleChanged=n,this._getAllMeshes=r,this._applyOverrideHook=i,this._isLayerTransparent=a}setFeatureStyle(e,t,n){this.featureStyles.set(e,t),this.markOverridesDirty(n),this._onStyleChanged(),this._triggerRepaint()}setFeaturesStyle(e,t,n){for(let n of e)this.featureStyles.set(n,t);this.markOverridesDirty(n),this._onStyleChanged(),this._triggerRepaint()}getFeatureStyle(e){return this.featureStyles.get(e)??null}getFeatureEffectiveOffset(e){if(e==null)return{};let t=this.featureStyles.get(e),n=t?.elevation??this.thematicElevation.get(e);return{translation:t?.translation,elevation:n,rotation:t?.rotation,pivot:t?.pivot}}getFeatureStyles(){return new Map(this.featureStyles)}removeFeatureStyle(e,t){this.featureStyles.delete(e)&&(this.markOverridesDirty(t),this._onStyleChanged(),this._triggerRepaint())}clearFeatureStyles(){this.featureStyles.size>0&&(this.featureStyles.clear(),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint())}setThematicColors(e,t=`custom`){this.thematicColors=e&&e.size>0?new Map(e):new Map,this.thematicField=this.thematicColors.size>0?t:null,this.markOverridesDirty(),this._triggerRepaint()}clearThematicColors(){this.thematicColors.size!==0&&(this.thematicColors=new Map,this.thematicField=null,this.markOverridesDirty(),this._triggerRepaint())}setThematicElevation(e,t=`custom`){this.thematicElevation=e&&e.size>0?new Map([...e].filter(([,e])=>Number.isFinite(e)&&e>0)):new Map,this.elevationField=this.thematicElevation.size>0?t:null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint()}clearThematicElevation(){this.thematicElevation.size!==0&&(this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint())}setFilter(e,t){this.filter=e,e&&(e.minHeight!=null||e.maxHeight!=null)?(t.uFilterMinZ&&(t.uFilterMinZ.value=e.minHeight??-99999),t.uFilterMaxZ&&(t.uFilterMaxZ.value=e.maxHeight??99999),t.uFilterHeightActive&&(t.uFilterHeightActive.value=1)):t.uFilterHeightActive&&(t.uFilterHeightActive.value=0),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint()}clearFilter(e){this.setFilter(null,e)}async colorByField(e,n,r){if(!n)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let i=e.smids?.length?[...new Set(e.smids)]:r;if(!i.length)return this.clearThematicColors(),{field:e.field,type:`discrete`,matched:0,missing:0,legend:[]};let a=await n.queryBySmids(i),o=[],s=[];for(let t of i){let n=a.get(t),r=n?n[e.field]:void 0;if(r==null||r===``)continue;let i=Number(r);Number.isFinite(i)?o.push({smid:t,val:i}):s.push({smid:t,val:String(r)})}let c=o.length>=s.length&&o.length>0,l=new Map,u=[],d=e.defaultColor??`#64748b`,f=e.nullColor??`#334155`;if(c){let n=o.map(e=>e.val),r=Math.min(...n),i=Math.max(...n)-r||1,a=(e.ramp??[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`]).map(e=>new t.Color(e)),s=Math.max(2,e.stops??5);for(let e=0;e<s;e++){let t=e/s,n=(e+1)/s,o=mo(a,(t+n)/2),c=r+t*i,l=r+n*i;u.push({color:`#${o.getHexString()}`,label:`${go(c)} ~ ${go(l)}`,count:0,min:c,max:l})}for(let{smid:e,val:t}of o){let n=Math.min(1,Math.max(0,(t-r)/i)),a=Math.min(s-1,Math.floor(n*s)),o=u[a].color;l.set(e,o),u[a].count++}}else{let t=new Map;for(let{val:e}of s)t.set(e,(t.get(e)??0)+1);let n=[...t.entries()].sort((e,t)=>t[1]-e[1]),r=Array.isArray(e.colors)?e.colors:[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`,`#8b5cf6`,`#ec4899`,`#06b6d4`,`#84cc16`],i=!Array.isArray(e.colors)&&e.colors?e.colors:null;for(let e=0;e<n.length;e++){let[t,a]=n[e],o=i?.[t]??r[e%r.length];u.push({color:o,label:t,count:a})}let a=new Map(u.map(e=>[e.label,e.color]));for(let{smid:e,val:t}of s)l.set(e,a.get(t)??d)}let p=0;for(let e of i)l.has(e)||(l.set(e,f),p++);return p>0&&u.push({color:f,label:`无数据 / 缺失`,count:p}),this.setThematicColors(l,e.field),{field:e.field,type:c?`continuous`:`discrete`,matched:i.length-p,missing:p,legend:u}}async filterByField(e,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n,i=e.mode??`keep`,a=e.onMissing??`drop`,o={field:e.field,mode:i,matched:0,hidden:[]};if(!r.length)return this.fieldFilter=null,this.markOverridesDirty(),o;let s=await t.queryBySmids(r),c=new Set;for(let t of r){let n=s.get(t);n?ho(n[e.field]??null,n,e)&&c.add(t):a===`keep`&&c.add(t)}o.matched=c.size;let l=i===`keep`;return this.fieldFilter=c.size||l?{field:e.field,mode:l?`keep`:`drop`,matched:c}:null,o.hidden=r.filter(e=>l?!c.has(e):c.has(e)),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),o}clearFieldFilter(){this.fieldFilter&&(this.fieldFilter=null,this.markOverridesDirty(),this._triggerRepaint())}async elevateByField(e,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n,i={field:e.field,matched:0,missing:r.length,min:0,max:0,appliedMax:0};if(!r.length)return this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),i;let a=await t.queryBySmids(r),o=new Map;for(let t of r){let n=Number(a.get(t)?.[e.field]);Number.isFinite(n)&&o.set(t,n)}if(o.size===0)return this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),i;let s=[...o.values()],c=Math.min(...s),l=Math.max(...s),u=e.scale??1,d=e.offset??0,f=new Map,p=0;for(let[t,n]of o){let r=e.map?e.map(n,{min:c,max:l}):n*u+d;Number.isFinite(r)&&(e.max!=null&&r>e.max&&(r=e.max),!(r<=0)&&(f.set(t,r),r>p&&(p=r)))}return this.thematicElevation=f,this.elevationField=e.field,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),{field:e.field,matched:f.size,missing:r.length-o.size,min:c,max:l,appliedMax:p}}auditBatches(e){let t=[],n=new Set,r=0;for(let i of e){let e=i.mesh.userData.geoRef?.pickInfo;if(!e)continue;let a=new Map;for(let[t,n]of Object.entries(e)){let e=H(n);if(e<0)continue;let r=Number(t),i=a.get(e);i?i.push(r):a.set(e,[r])}r+=a.size;for(let[e,r]of a)if(!(r.length<2)){for(let e of r)n.add(e);t.push({datasetId:i.datasetId,batchId:e,smids:r})}}return{smids:0,batches:r,conflicts:t,conflictingSmids:n.size}}_bakeStylesIntoBuffer(e,n,r,i,a){let o=n;for(let t=0;t<o;t++){e[t*4+0]=-1,e[t*4+1]=-1,e[t*4+2]=-1,e[t*4+3]=0;let n=(o+t)*4;e[n+0]=0,e[n+1]=0,e[n+2]=0,e[n+3]=0;let r=(o*2+t)*4;e[r+0]=1,e[r+1]=0,e[r+2]=0,e[r+3]=0;let i=(o*3+t)*4;e[i+0]=0,e[i+1]=1,e[i+2]=0,e[i+3]=0;let a=(o*4+t)*4;e[a+0]=0,e[a+1]=0,e[a+2]=1,e[a+3]=0;let s=(o*5+t)*4;e[s+0]=-1,e[s+1]=0,e[s+2]=0,e[s+3]=0}let s=!1,c=new Set,l=new Map,u=new Map,d=new Map,f=new Map,p=new Map,m=new Map,h=new Map,g=new Map,_=this.filter,v=i.userData;for(let[e,t]of Object.entries(r)){let n=Number(e),r=H(t);if(r<0||r>=o)continue;g.set(r,(g.get(r)??0)+1);let s=!1;if(_&&(_.include&&_.include.length>0&&!_.include.includes(n)&&(s=!0),_.exclude&&_.exclude.length>0&&_.exclude.includes(n)&&(s=!0),_.predicate)){let{segments:e}=U(v.geoRef,r),t=Ct({smid:n,box:St(i.geometry,e),triangles:0,floorHeight:this._getLayerFloorHeight()});_.predicate({...t,smid:n})||(s=!0)}if(s){c.add(r);continue}if(this.fieldFilter){let e=this.fieldFilter.matched.has(n);if(this.fieldFilter.mode===`keep`?!e:e){c.add(r);continue}}let y=a.get(n);if(y?.hidden){c.add(r);continue}let b=y?.opacity;if(b!=null){if(b<=0){c.add(r);continue}b<1&&!h.has(r)&&h.set(r,b)}let x=y?.color??this.thematicColors.get(n);x&&!l.has(r)&&l.set(r,x);let S=y?.elevation??this.thematicElevation.get(n);if(S!=null&&!u.has(r)&&u.set(r,S),y?.translation&&!d.has(r)&&d.set(r,y.translation),y?.rotation!=null&&!f.has(r)){let e=uo(y.rotation);e&&f.set(r,e)}y?.pivot&&!p.has(r)&&p.set(r,y.pivot),y?.gpuPath&&!m.has(r)&&m.set(r,y.gpuPath)}for(let t of c)e[t*4+3]=-1,s=!0;let y=new t.Color;for(let[t,n]of l)c.has(t)||(y.set(n),e[t*4+0]=y.r,e[t*4+1]=y.g,e[t*4+2]=y.b,s=!0);for(let[t,n]of u){if(c.has(t))continue;e[t*4+3]=n;let r=(o+t)*4;e[r+2]=n,s=!0}for(let[t,n]of d){if(c.has(t))continue;let r=(o+t)*4;e[r+0]=n[0],e[r+1]=n[1],e[r+2]=n[2]+(u.get(t)??0),s=!0}let b=!1;for(let[t,n]of h)c.has(t)||(e[(o+t)*4+3]=n,s=!0,b=!0);for(let[t,n]of f){if(c.has(t))continue;let r=p.get(t)??[0,0,0],i=(o*2+t)*4;e[i+0]=n[0],e[i+1]=n[1],e[i+2]=n[2],e[i+3]=r[0];let a=(o*3+t)*4;e[a+0]=n[3],e[a+1]=n[4],e[a+2]=n[5],e[a+3]=r[1];let l=(o*4+t)*4;e[l+0]=n[6],e[l+1]=n[7],e[l+2]=n[8],e[l+3]=r[2],s=!0}for(let[t,n]of p)f.has(t)||c.has(t)||(e[(o*2+t)*4+3]=n[0],e[(o*3+t)*4+3]=n[1],e[(o*4+t)*4+3]=n[2],s=!0);for(let[t,n]of m){if(c.has(t))continue;let r=(o*5+t)*4;e[r+0]=n.pathId,e[r+1]=n.speed??0,e[r+2]=n.phase??0;let i=1;n.loop===`clamp`||n.loop===!1?i=2:n.loop===`pingpong`&&(i=3),n.autoHeading===!1&&(i+=3),e[r+3]=i,s=!0}let x=0;for(let[e,t]of g)t<2||(c.has(e)||l.has(e)||u.has(e)||f.has(e)||m.has(e))&&x++;return{hasActive:s,hasFade:b,conflicts:x}}applyOverridesToMesh(e){let n=po(e);if(!n)return;let r=e.userData.geoRef?.pickInfo,i=this.featureStyles.size>0||this.thematicColors.size>0||this.thematicElevation.size>0,a=this.filter,o=this.fieldFilter!=null||a!=null&&((a.include?.length??0)>0||(a.exclude?.length??0)>0||a.predicate!=null);if(!i&&!o||!r||Object.keys(r).length===0){n.userData.uBatchTexActive&&(n.userData.uBatchTexActive.value=0),n.transparent&&!this._isLayerTransparent()&&(n.transparent=!1);return}let s=0;for(let e of Object.values(r)){let t=H(e);t>s&&(s=t)}let c=Math.max(s+1,1),l=this._meshBatchTextures.get(e);if(!l||l.width<c){let r=new Float32Array(c*6*4),i=new t.DataTexture(r,c,6,t.RGBAFormat,t.FloatType);i.minFilter=t.NearestFilter,i.magFilter=t.NearestFilter,l={texture:i,data:r,width:c},this._meshBatchTextures.set(e,l),n.userData.uBatchTex.value=i,n.userData.uBatchTexWidth.value=c}let{data:u,texture:d}=l,{hasActive:f,hasFade:p,conflicts:m}=this._bakeStylesIntoBuffer(u,l.width,r,e,this.featureStyles);p&&!n.transparent?n.transparent=!0:!p&&n.transparent&&!this._isLayerTransparent()&&(n.transparent=!1),m>0&&!this._batchConflictWarned&&(this._batchConflictWarned=!0,console.warn(`[s3m] 有 ${m} 个单体状态写不进独立的 batch(多个 SMID 共用同一个 batchId,\n S3M 的单体化粒度只到 batch,无法单独隐藏/改色其中一部分)。
906
+ `;function to(e,n={},r,i){let a=r??{uColor:{value:new t.Color(n.color??`#ffffff`)},uOpacity:{value:n.opacity??1},uWidth:{value:n.width??1.5},uElevation:{value:n.elevation??0}};n.color!==void 0&&r&&a.uColor.value.set(n.color),n.opacity!==void 0&&r&&(a.uOpacity.value=n.opacity),n.width!==void 0&&r&&(a.uWidth.value=n.width);let o={uBatchTex:i?.uBatchTex??{value:ri},uBatchTex2:i?.uBatchTex2??{value:ri},uBatchMix:i?.uBatchMix??{value:0},uBatchTexWidth:i?.uBatchTexWidth??{value:1},uBatchTexActive:i?.uBatchTexActive??{value:0},uPathTex:i?.uPathTex??{value:Jr.DUMMY_PATH_TEX},uPathCount:i?.uPathCount??{value:1},uPathTexActive:i?.uPathTexActive??{value:0},uPathTime:i?.uPathTime??{value:0}},s=new t.ShaderMaterial({uniforms:{uResolution:e.uResolution,uDpr:e.uDpr,uColor:a.uColor,uOpacity:a.uOpacity,uWidth:a.uWidth,uElevation:a.uElevation??{value:n.elevation??0},uTranslation:{value:new t.Vector3(0,0,0)},uBatchTex:o.uBatchTex,uBatchTex2:o.uBatchTex2,uBatchMix:o.uBatchMix,uBatchTexWidth:o.uBatchTexWidth,uBatchTexActive:o.uBatchTexActive,uPathTex:o.uPathTex,uPathCount:o.uPathCount,uPathTexActive:o.uPathTexActive,uPathTime:o.uPathTime},vertexShader:$a,fragmentShader:eo,transparent:!0,depthWrite:!1,side:t.DoubleSide,polygonOffset:!0,polygonOffsetFactor:-2,polygonOffsetUnits:-2});return s.userData.isThickLine=!0,s}function no(e,n){let r=Math.floor(e.length/6),i=r*4,a=new Float32Array(i*3),o=new Float32Array(i*3),s=new Float32Array(i),c=new Float32Array(i),l=i>65535?new Uint32Array(r*6):new Uint16Array(r*6);for(let t=0;t<r;t++){let r=t*6,i=e[r],a=e[r+1],o=e[r+2],s=e[r+3],d=e[r+4],f=e[r+5],p=n?Number(n[t]??-1):-1,m=t*4;u(m,i,a,o,s,d,f,-1),u(m+1,i,a,o,s,d,f,1),u(m+2,s,d,f,i,a,o,1),u(m+3,s,d,f,i,a,o,-1);for(let e=0;e<4;e++)c[m+e]=p;let h=t*6;l[h]=m,l[h+1]=m+1,l[h+2]=m+2,l[h+3]=m,l[h+4]=m+2,l[h+5]=m+3}function u(e,t,n,r,i,c,l,u){let d=e*3;a[d]=t,a[d+1]=n,a[d+2]=r,o[d]=i,o[d+1]=c,o[d+2]=l,s[e]=u}let d=new t.BufferGeometry;return d.setAttribute(`position`,new t.BufferAttribute(a,3)),d.setAttribute(`aOther`,new t.BufferAttribute(o,3)),d.setAttribute(`aSide`,new t.BufferAttribute(s,1)),d.setAttribute(`aBatchId`,new t.BufferAttribute(c,1)),d.setIndex(new t.BufferAttribute(l,1)),d.computeBoundingSphere(),d}function ro(e,t){let n=e.getAttribute(`position`),r=e.getAttribute(`aBatchId`);if(!n||!r||n.count===0||n.count!==r.count)return null;let i=1/Math.max(t,1e-9),a=new Map;for(let e=0;e<n.count;e++){let t=io(n.getX(e),n.getY(e),n.getZ(e),i);a.has(t)||a.set(t,r.getX(e))}return a.size>0?a:null}function io(e,t,n,r){return`${Math.round(e*r)},${Math.round(t*r)},${Math.round(n*r)}`}var ao=6e4,oo=100;function so(e,t,n=40){let r=e.getAttribute(`position`);if(!r)return null;let i=r.count;if(i<3)return null;let a=new Float32Array(i),o=new Float32Array(i),s=new Float32Array(i);for(let e=0;e<i;e++)a[e]=r.getX(e),o[e]=r.getY(e),s[e]=r.getZ(e);let c=null,l=null;if(!e.index){let e=new Map;c=new Uint32Array(i),l=new Uint32Array(i);let t=0;for(let n=0;n<i;n++){let r=`${Math.round(a[n]*oo)},${Math.round(o[n]*oo)},${Math.round(s[n]*oo)}`,i=e.get(r);i===void 0&&(i=t++,e.set(r,i),l[i]=n),c[n]=i}}let u=e=>c?c[e]:e,d=e=>l?l[e]:e,f=e.index,p=f?f.array:null,m=Math.floor(f?f.count/3:i/3);if(m<1)return null;let h=null;if(t&&t.length>0){h=new Uint8Array(i);for(let e of t){let t=Math.max(0,e.vertexOffset|0),n=Math.min(i,t+(e.vertexCount|0));n>t&&h.fill(1,t,n)}if(!h.includes(1))return null}let g=new Float32Array(m*3),_=new Map,v=i+1,y=[],b=Math.cos(n*Math.PI/180),x=-1,S=0,C=0,w=0,T=(e,t)=>{if(y.length>=ao*6)return!1;let n=d(e),r=d(t);return y.push(a[n],o[n],s[n],a[r],o[r],s[r]),!0},E=(e,t)=>{if(e===t)return;let n=e<t?e:t,r=e<t?t:e,i=n*v+r,a=_.get(i);a===void 0?_.set(i,x):a<0||(S*g[a*3]+C*g[a*3+1]+w*g[a*3+2]<b?(T(n,r),_.set(i,-1)):_.set(i,-2))};for(x=0;x<m;x++){let e=p?p[x*3]:x*3,t=p?p[x*3+1]:x*3+1,n=p?p[x*3+2]:x*3+2;if(h&&!(h[e]&&h[t]&&h[n]))continue;let r=a[t]-a[e],i=o[t]-o[e],c=s[t]-s[e],l=a[n]-a[e],d=o[n]-o[e],f=s[n]-s[e];S=i*f-c*d,C=c*l-r*f,w=r*d-i*l;let m=Math.hypot(S,C,w);m<1e-12||(S/=m,C/=m,w/=m,g[x*3]=S,g[x*3+1]=C,g[x*3+2]=w,E(u(e),u(t)),E(u(t),u(n)),E(u(n),u(e)))}for(let[e,t]of _){if(t<0)continue;let n=Math.floor(e/v);if(!T(n,e-n*v))break}return y.length>0?new Float32Array(y):null}function co(e,t,n,r){return`${Math.round(e*r)},${Math.round(t*r)},${Math.round(n*r)}`}function lo(e,n){let r=e.getAttribute(`position`);if(!r||r.count===0)return e;let i=1/Math.max(n,1e-9),a=new Map,o=[],s=new Int32Array(r.count);for(let e=0;e<r.count;e++){let t=r.getX(e),n=r.getY(e),c=r.getZ(e),l=co(t,n,c,i),u=a.get(l);u===void 0&&(u=o.length/3,o.push(t,n,c),a.set(l,u)),s[e]=u}let c=e.getIndex(),l=c?c.count:r.count,u=new Uint32Array(l);for(let e=0;e<l;e++)u[e]=s[c?c.getX(e):e];let d=new t.BufferGeometry;return d.setAttribute(`position`,new t.Float32BufferAttribute(o,3)),d.setIndex(new t.BufferAttribute(u,1)),d}y();var uo=class{constructor(){v(this,`datasets`,new Map),v(this,`sceneAnchor`,null),v(this,`totalMaxTiles`,0)}get(e){return this.datasets.get(e)}values(){return this.datasets.values()}registerDataset(e){let n=this.datasets.get(e.id);if(n)return n;let r=new t.Group;r.name=`s3m-dataset:${e.id}`,r.visible=e.visible!==!1;let i={id:e.id,name:e.name??e.id,options:e,root:r,tileset:null,anchor:null,baseAlignOffset:0,userOffset:e.heightOffset??0,heightOffset:e.heightOffset??0,offset:[0,0,0],visible:e.visible!==!1,error:null};return this.datasets.set(e.id,i),this.rebalanceBudgets(),i}rebalanceBudgets(e){let t=e??this.totalMaxTiles;if(!t||t<=0)return;this.totalMaxTiles=t;let n=Array.from(this.datasets.values()).filter(e=>e.visible&&e.tileset),r=Math.max(1,n.length),i=Math.max(8,Math.floor(t/r));for(let e of this.datasets.values())e.tileset&&(e.visible?(e.tileset.maxTiles=i,e.tileset.hardCap=i+Math.max(4,Math.ceil(i*.5))):(e.tileset.maxTiles=Math.min(4,e.tileset.maxTiles),e.tileset.hardCap=Math.min(6,e.tileset.hardCap)))}computeAlignOffset(e,t){if(!t||t===`origin`||!e)return 0;let n=e.heightRange;if(!n)return 0;switch(t){case`top`:return-n.max;case`bottom`:return-n.min;case`center`:return-(n.min+n.max)/2;default:return 0}}async addDataset(e,n,r,i,a,o,s,c,l){let u=this.datasets.get(e.id);if(u)return u;let d=new t.Group;d.name=`s3m-dataset:${e.id}`,d.visible=e.visible!==!1,n.add(d);let f={id:e.id,name:e.name??e.id,options:e,root:d,tileset:null,anchor:null,baseAlignOffset:0,userOffset:e.heightOffset??0,heightOffset:e.heightOffset??0,offset:[0,0,0],visible:e.visible!==!1,error:null};this.datasets.set(e.id,f);let p=new ia({configUrl:e.configUrl,maxTiles:e.maxTiles??s,maxConcurrent:c,lodRangeScale:e.lodRangeScale??a,buildTile:o??null,useWorker:e.useWorker,uniforms:i,onTile:e=>{l.onTile(e,f)},onTileRemoved:e=>{l.onTileRemoved(e,f)},onProgress:()=>{l.onStats(),l.triggerRepaint()},onError:e=>{f.error=e,l.onError(e),l.onStats()}});f.tileset=p,this.rebalanceBudgets();try{await p.init()}catch(e){return f.error=e,l.onError(e),f}return f.anchor=p.anchor,f.baseAlignOffset=this.computeAlignOffset(p,e.align),f.userOffset=e.heightOffset??0,f.heightOffset=f.baseAlignOffset+f.userOffset,this.layoutDataset(f,r),l.onReady(f),l.triggerRepaint(),f}removeDataset(e,t,n,r){let i=this.datasets.get(e);return i?(r(i),i.tileset?.dispose(),t.remove(i.root),this.datasets.delete(e),this.rebalanceBudgets(),this.datasets.size>0?this.recomputeAnchors(n):this.sceneAnchor=null,!0):!1}clearDatasets(e,t){for(let n of this.datasets.values())t(n),n.tileset?.dispose(),e.remove(n.root);this.datasets.clear(),this.sceneAnchor=null}layoutDataset(e,t){if(!e.anchor)return;this.sceneAnchor||(this.sceneAnchor=Pt(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0));let n=this.sceneAnchor.meterInMercator,r=Pt(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0);e.offset=[(r.x-this.sceneAnchor.x)/n,-(r.y-this.sceneAnchor.y)/n,(r.z-this.sceneAnchor.z)/n+(e.heightOffset??0)],e.root.position.set(e.offset[0],e.offset[1],e.offset[2]),e.root.updateMatrixWorld(!0)}recomputeAnchors(e){if(this.datasets.size!==0){this.sceneAnchor=null;for(let t of this.datasets.values())this.layoutDataset(t,e)}}getDatasetHeight(e){let t=e??this.datasets.keys().next().value;return t?this.datasets.get(t)?.userOffset??0:0}setDatasetHeight(e,t,n){let r=this.datasets.get(e);r&&(r.userOffset=t,r.heightOffset=r.baseAlignOffset+t,this.layoutDataset(r,n))}setDatasetAlign(e,t,n){let r=this.datasets.get(e);if(!r)return;let i=r.heightOffset-r.baseAlignOffset;r.baseAlignOffset=this.computeAlignOffset(r.tileset,t),r.userOffset=i,r.heightOffset=r.baseAlignOffset+i,r.options.align=t,this.layoutDataset(r,n)}setDatasetVisible(e,t){let n=this.datasets.get(e);n&&(n.visible=t,n.root.visible=t,this.rebalanceBudgets())}getBounds(){let e=1/0,t=1/0,n=-1/0,r=-1/0,i=!1;for(let a of this.datasets.values()){if(!a.visible||!a.tileset?.config)continue;let o=ta(a.tileset.config.geoBounds);o&&(e=Math.min(e,o.left),t=Math.min(t,o.bottom),n=Math.max(n,o.right),r=Math.max(r,o.top),i=!0)}return i?[[e,t],[n,r]]:null}};Tt(),y();function fo(e){if(e==null)return null;if(typeof e==`number`){let t=Math.cos(e),n=Math.sin(e);return[t,-n,0,n,t,0,0,0,1]}if(Array.isArray(e)){if(e.length===3){let n=new t.Euler(e[0],e[1],e[2]),r=new t.Matrix4().makeRotationFromEuler(n).elements;return[r[0],r[4],r[8],r[1],r[5],r[9],r[2],r[6],r[10]]}if(e.length===4){let n=new t.Quaternion(e[0],e[1],e[2],e[3]),r=new t.Matrix4().makeRotationFromQuaternion(n).elements;return[r[0],r[4],r[8],r[1],r[5],r[9],r[2],r[6],r[10]]}}if(e instanceof t.Euler){let n=new t.Matrix4().makeRotationFromEuler(e).elements;return[n[0],n[4],n[8],n[1],n[5],n[9],n[2],n[6],n[10]]}if(e instanceof t.Quaternion){let n=new t.Matrix4().makeRotationFromQuaternion(e).elements;return[n[0],n[4],n[8],n[1],n[5],n[9],n[2],n[6],n[10]]}if(e instanceof t.Matrix3){let t=e.elements;return[t[0],t[3],t[6],t[1],t[4],t[7],t[2],t[5],t[8]]}if(e instanceof t.Matrix4){let t=e.elements;return[t[0],t[4],t[8],t[1],t[5],t[9],t[2],t[6],t[10]]}return null}function po(e){if(e==null)return[0,0,0];if(typeof e==`number`)return[0,0,e];if(Array.isArray(e)){if(e.length===3)return[e[0],e[1],e[2]];if(e.length===4){let n=new t.Quaternion(e[0],e[1],e[2],e[3]),r=new t.Euler().setFromQuaternion(n);return[r.x,r.y,r.z]}}if(e instanceof t.Euler)return[e.x,e.y,e.z];if(e instanceof t.Quaternion){let n=new t.Euler().setFromQuaternion(e);return[n.x,n.y,n.z]}if(e instanceof t.Matrix3){let n=new t.Matrix4().set(e.elements[0],e.elements[3],e.elements[6],0,e.elements[1],e.elements[4],e.elements[7],0,e.elements[2],e.elements[5],e.elements[8],0,0,0,0,1),r=new t.Euler().setFromRotationMatrix(n);return[r.x,r.y,r.z]}if(e instanceof t.Matrix4){let n=new t.Euler().setFromRotationMatrix(e);return[n.x,n.y,n.z]}return[0,0,0]}function mo(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function ho(e,t){if(e.length<2)return e[0].clone();let n=Math.min(1,Math.max(0,t))*(e.length-1),r=Math.min(e.length-2,Math.floor(n));return e[r].clone().lerp(e[r+1],n-r)}function go(e,t,n){if(n.keep&&!n.keep(e,t))return!1;if(n.values?.length){let t=e==null?``:String(e);if(!n.values.some(e=>String(e)===t))return!1}if(n.min!=null||n.max!=null){let t=Number(e);if(!Number.isFinite(t)||n.min!=null&&t<n.min||n.max!=null&&t>n.max)return!1}return!n.keep&&!n.values?.length&&n.min==null&&n.max==null?e!=null&&String(e)!==``:!0}function _o(e){if(!Number.isFinite(e))return`—`;let t=Math.abs(e);return t>=100?e.toFixed(0):t>=10?e.toFixed(1):e.toFixed(2)}var vo=class{constructor(e,t,n,r,i,a=()=>!1){v(this,`_getLayerFloorHeight`,void 0),v(this,`_triggerRepaint`,void 0),v(this,`_onStyleChanged`,void 0),v(this,`_getAllMeshes`,void 0),v(this,`_applyOverrideHook`,void 0),v(this,`_isLayerTransparent`,void 0),v(this,`featureStyles`,new Map),v(this,`thematicColors`,new Map),v(this,`thematicElevation`,new Map),v(this,`thematicField`,null),v(this,`elevationField`,null),v(this,`filter`,null),v(this,`fieldFilter`,null),v(this,`_meshBatchTextures`,new WeakMap),v(this,`_markedMeshes`,new Set),v(this,`_dirtyAll`,!1),v(this,`_flushScheduled`,!1),v(this,`_batchConflictWarned`,!1),this._getLayerFloorHeight=e,this._triggerRepaint=t,this._onStyleChanged=n,this._getAllMeshes=r,this._applyOverrideHook=i,this._isLayerTransparent=a}setFeatureStyle(e,t,n){this.featureStyles.set(e,t),this.markOverridesDirty(n),this._onStyleChanged(),this._triggerRepaint()}setFeaturesStyle(e,t,n){for(let n of e)this.featureStyles.set(n,t);this.markOverridesDirty(n),this._onStyleChanged(),this._triggerRepaint()}getFeatureStyle(e){return this.featureStyles.get(e)??null}getFeatureEffectiveOffset(e){if(e==null)return{};let t=this.featureStyles.get(e),n=t?.elevation??this.thematicElevation.get(e);return{translation:t?.translation,elevation:n,rotation:t?.rotation,pivot:t?.pivot}}getFeatureStyles(){return new Map(this.featureStyles)}removeFeatureStyle(e,t){this.featureStyles.delete(e)&&(this.markOverridesDirty(t),this._onStyleChanged(),this._triggerRepaint())}clearFeatureStyles(){this.featureStyles.size>0&&(this.featureStyles.clear(),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint())}setThematicColors(e,t=`custom`){this.thematicColors=e&&e.size>0?new Map(e):new Map,this.thematicField=this.thematicColors.size>0?t:null,this.markOverridesDirty(),this._triggerRepaint()}clearThematicColors(){this.thematicColors.size!==0&&(this.thematicColors=new Map,this.thematicField=null,this.markOverridesDirty(),this._triggerRepaint())}setThematicElevation(e,t=`custom`){this.thematicElevation=e&&e.size>0?new Map([...e].filter(([,e])=>Number.isFinite(e)&&e>0)):new Map,this.elevationField=this.thematicElevation.size>0?t:null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint()}clearThematicElevation(){this.thematicElevation.size!==0&&(this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint())}setFilter(e,t){this.filter=e,e&&(e.minHeight!=null||e.maxHeight!=null)?(t.uFilterMinZ&&(t.uFilterMinZ.value=e.minHeight??-99999),t.uFilterMaxZ&&(t.uFilterMaxZ.value=e.maxHeight??99999),t.uFilterHeightActive&&(t.uFilterHeightActive.value=1)):t.uFilterHeightActive&&(t.uFilterHeightActive.value=0),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint()}clearFilter(e){this.setFilter(null,e)}async colorByField(e,n,r){if(!n)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let i=e.smids?.length?[...new Set(e.smids)]:r;if(!i.length)return this.clearThematicColors(),{field:e.field,type:`discrete`,matched:0,missing:0,legend:[]};let a=await n.queryBySmids(i),o=[],s=[];for(let t of i){let n=a.get(t),r=n?n[e.field]:void 0;if(r==null||r===``)continue;let i=Number(r);Number.isFinite(i)?o.push({smid:t,val:i}):s.push({smid:t,val:String(r)})}let c=o.length>=s.length&&o.length>0,l=new Map,u=[],d=e.defaultColor??`#64748b`,f=e.nullColor??`#334155`;if(c){let n=o.map(e=>e.val),r=Math.min(...n),i=Math.max(...n)-r||1,a=(e.ramp??[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`]).map(e=>new t.Color(e)),s=Math.max(2,e.stops??5);for(let e=0;e<s;e++){let t=e/s,n=(e+1)/s,o=ho(a,(t+n)/2),c=r+t*i,l=r+n*i;u.push({color:`#${o.getHexString()}`,label:`${_o(c)} ~ ${_o(l)}`,count:0,min:c,max:l})}for(let{smid:e,val:t}of o){let n=Math.min(1,Math.max(0,(t-r)/i)),a=Math.min(s-1,Math.floor(n*s)),o=u[a].color;l.set(e,o),u[a].count++}}else{let t=new Map;for(let{val:e}of s)t.set(e,(t.get(e)??0)+1);let n=[...t.entries()].sort((e,t)=>t[1]-e[1]),r=Array.isArray(e.colors)?e.colors:[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`,`#8b5cf6`,`#ec4899`,`#06b6d4`,`#84cc16`],i=!Array.isArray(e.colors)&&e.colors?e.colors:null;for(let e=0;e<n.length;e++){let[t,a]=n[e],o=i?.[t]??r[e%r.length];u.push({color:o,label:t,count:a})}let a=new Map(u.map(e=>[e.label,e.color]));for(let{smid:e,val:t}of s)l.set(e,a.get(t)??d)}let p=0;for(let e of i)l.has(e)||(l.set(e,f),p++);return p>0&&u.push({color:f,label:`无数据 / 缺失`,count:p}),this.setThematicColors(l,e.field),{field:e.field,type:c?`continuous`:`discrete`,matched:i.length-p,missing:p,legend:u}}async filterByField(e,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n,i=e.mode??`keep`,a=e.onMissing??`drop`,o={field:e.field,mode:i,matched:0,hidden:[]};if(!r.length)return this.fieldFilter=null,this.markOverridesDirty(),o;let s=await t.queryBySmids(r),c=new Set;for(let t of r){let n=s.get(t);n?go(n[e.field]??null,n,e)&&c.add(t):a===`keep`&&c.add(t)}o.matched=c.size;let l=i===`keep`;return this.fieldFilter=c.size||l?{field:e.field,mode:l?`keep`:`drop`,matched:c}:null,o.hidden=r.filter(e=>l?!c.has(e):c.has(e)),this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),o}clearFieldFilter(){this.fieldFilter&&(this.fieldFilter=null,this.markOverridesDirty(),this._triggerRepaint())}async elevateByField(e,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n,i={field:e.field,matched:0,missing:r.length,min:0,max:0,appliedMax:0};if(!r.length)return this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),i;let a=await t.queryBySmids(r),o=new Map;for(let t of r){let n=Number(a.get(t)?.[e.field]);Number.isFinite(n)&&o.set(t,n)}if(o.size===0)return this.thematicElevation=new Map,this.elevationField=null,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),i;let s=[...o.values()],c=Math.min(...s),l=Math.max(...s),u=e.scale??1,d=e.offset??0,f=new Map,p=0;for(let[t,n]of o){let r=e.map?e.map(n,{min:c,max:l}):n*u+d;Number.isFinite(r)&&(e.max!=null&&r>e.max&&(r=e.max),!(r<=0)&&(f.set(t,r),r>p&&(p=r)))}return this.thematicElevation=f,this.elevationField=e.field,this.markOverridesDirty(),this._onStyleChanged(),this._triggerRepaint(),{field:e.field,matched:f.size,missing:r.length-o.size,min:c,max:l,appliedMax:p}}auditBatches(e){let t=[],n=new Set,r=0;for(let i of e){let e=i.mesh.userData.geoRef?.pickInfo;if(!e)continue;let a=new Map;for(let[t,n]of Object.entries(e)){let e=H(n);if(e<0)continue;let r=Number(t),i=a.get(e);i?i.push(r):a.set(e,[r])}r+=a.size;for(let[e,r]of a)if(!(r.length<2)){for(let e of r)n.add(e);t.push({datasetId:i.datasetId,batchId:e,smids:r})}}return{smids:0,batches:r,conflicts:t,conflictingSmids:n.size}}_bakeStylesIntoBuffer(e,n,r,i,a){let o=n;for(let t=0;t<o;t++){e[t*4+0]=-1,e[t*4+1]=-1,e[t*4+2]=-1,e[t*4+3]=0;let n=(o+t)*4;e[n+0]=0,e[n+1]=0,e[n+2]=0,e[n+3]=0;let r=(o*2+t)*4;e[r+0]=1,e[r+1]=0,e[r+2]=0,e[r+3]=0;let i=(o*3+t)*4;e[i+0]=0,e[i+1]=1,e[i+2]=0,e[i+3]=0;let a=(o*4+t)*4;e[a+0]=0,e[a+1]=0,e[a+2]=1,e[a+3]=0;let s=(o*5+t)*4;e[s+0]=-1,e[s+1]=0,e[s+2]=0,e[s+3]=0}let s=!1,c=new Set,l=new Map,u=new Map,d=new Map,f=new Map,p=new Map,m=new Map,h=new Map,g=new Map,_=this.filter,v=i.userData;for(let[e,t]of Object.entries(r)){let n=Number(e),r=H(t);if(r<0||r>=o)continue;g.set(r,(g.get(r)??0)+1);let s=!1;if(_&&(_.include&&_.include.length>0&&!_.include.includes(n)&&(s=!0),_.exclude&&_.exclude.length>0&&_.exclude.includes(n)&&(s=!0),_.predicate)){let{segments:e}=U(v.geoRef,r),t=Ct({smid:n,box:St(i.geometry,e),triangles:0,floorHeight:this._getLayerFloorHeight()});_.predicate({...t,smid:n})||(s=!0)}if(s){c.add(r);continue}if(this.fieldFilter){let e=this.fieldFilter.matched.has(n);if(this.fieldFilter.mode===`keep`?!e:e){c.add(r);continue}}let y=a.get(n);if(y?.hidden){c.add(r);continue}let b=y?.opacity;if(b!=null){if(b<=0){c.add(r);continue}b<1&&!h.has(r)&&h.set(r,b)}let x=y?.color??this.thematicColors.get(n);x&&!l.has(r)&&l.set(r,x);let S=y?.elevation??this.thematicElevation.get(n);if(S!=null&&!u.has(r)&&u.set(r,S),y?.translation&&!d.has(r)&&d.set(r,y.translation),y?.rotation!=null&&!f.has(r)){let e=fo(y.rotation);e&&f.set(r,e)}y?.pivot&&!p.has(r)&&p.set(r,y.pivot),y?.gpuPath&&!m.has(r)&&m.set(r,y.gpuPath)}for(let t of c)e[t*4+3]=-1,s=!0;let y=new t.Color;for(let[t,n]of l)c.has(t)||(y.set(n),e[t*4+0]=y.r,e[t*4+1]=y.g,e[t*4+2]=y.b,s=!0);for(let[t,n]of u){if(c.has(t))continue;e[t*4+3]=n;let r=(o+t)*4;e[r+2]=n,s=!0}for(let[t,n]of d){if(c.has(t))continue;let r=(o+t)*4;e[r+0]=n[0],e[r+1]=n[1],e[r+2]=n[2]+(u.get(t)??0),s=!0}let b=!1;for(let[t,n]of h)c.has(t)||(e[(o+t)*4+3]=n,s=!0,b=!0);for(let[t,n]of f){if(c.has(t))continue;let r=p.get(t)??[0,0,0],i=(o*2+t)*4;e[i+0]=n[0],e[i+1]=n[1],e[i+2]=n[2],e[i+3]=r[0];let a=(o*3+t)*4;e[a+0]=n[3],e[a+1]=n[4],e[a+2]=n[5],e[a+3]=r[1];let l=(o*4+t)*4;e[l+0]=n[6],e[l+1]=n[7],e[l+2]=n[8],e[l+3]=r[2],s=!0}for(let[t,n]of p)f.has(t)||c.has(t)||(e[(o*2+t)*4+3]=n[0],e[(o*3+t)*4+3]=n[1],e[(o*4+t)*4+3]=n[2],s=!0);for(let[t,n]of m){if(c.has(t))continue;let r=(o*5+t)*4;e[r+0]=n.pathId,e[r+1]=n.speed??0,e[r+2]=n.phase??0;let i=1;n.loop===`clamp`||n.loop===!1?i=2:n.loop===`pingpong`&&(i=3),n.autoHeading===!1&&(i+=3),e[r+3]=i,s=!0}let x=0;for(let[e,t]of g)t<2||(c.has(e)||l.has(e)||u.has(e)||f.has(e)||m.has(e))&&x++;return{hasActive:s,hasFade:b,conflicts:x}}applyOverridesToMesh(e){let n=mo(e);if(!n)return;let r=e.userData.geoRef?.pickInfo,i=this.featureStyles.size>0||this.thematicColors.size>0||this.thematicElevation.size>0,a=this.filter,o=this.fieldFilter!=null||a!=null&&((a.include?.length??0)>0||(a.exclude?.length??0)>0||a.predicate!=null);if(!i&&!o||!r||Object.keys(r).length===0){n.userData.uBatchTexActive&&(n.userData.uBatchTexActive.value=0),n.transparent&&!this._isLayerTransparent()&&(n.transparent=!1);return}let s=0;for(let e of Object.values(r)){let t=H(e);t>s&&(s=t)}let c=Math.max(s+1,1),l=this._meshBatchTextures.get(e);if(!l||l.width<c){let r=new Float32Array(c*6*4),i=new t.DataTexture(r,c,6,t.RGBAFormat,t.FloatType);i.minFilter=t.NearestFilter,i.magFilter=t.NearestFilter,l={texture:i,data:r,width:c},this._meshBatchTextures.set(e,l),n.userData.uBatchTex.value=i,n.userData.uBatchTexWidth.value=c}let{data:u,texture:d}=l,{hasActive:f,hasFade:p,conflicts:m}=this._bakeStylesIntoBuffer(u,l.width,r,e,this.featureStyles);p&&!n.transparent?n.transparent=!0:!p&&n.transparent&&!this._isLayerTransparent()&&(n.transparent=!1),m>0&&!this._batchConflictWarned&&(this._batchConflictWarned=!0,console.warn(`[s3m] 有 ${m} 个单体状态写不进独立的 batch(多个 SMID 共用同一个 batchId,\n S3M 的单体化粒度只到 batch,无法单独隐藏/改色其中一部分)。
825
907
  当前规则:任一 SMID 需要隐藏则整批隐藏,颜色 / 抬高取首个。
826
- 用 layer.auditBatches() 可以列出具体是哪些 SMID 共用了 batchId。`)),d.needsUpdate=!0,n.userData.uBatchTexActive&&(n.userData.uBatchTexActive.value=+!!f)}prepareCrossFade(e,n){for(let r of n){let n=po(r);if(!n)continue;let i=r.userData.geoRef?.pickInfo;if(!i||Object.keys(i).length===0)continue;let a=0;for(let e of Object.values(i)){let t=H(e);t>a&&(a=t)}let o=Math.max(a+1,1),s=this._meshBatchTextures.get(r);if(!s||s.width<o){let e=new Float32Array(o*6*4),i=new t.DataTexture(e,o,6,t.RGBAFormat,t.FloatType);i.minFilter=t.NearestFilter,i.magFilter=t.NearestFilter,s={texture:i,data:e,width:o},this._meshBatchTextures.set(r,s),n.userData.uBatchTex.value=i,n.userData.uBatchTexWidth.value=o}if(!s.texture2||!s.data2||s.data2.length<s.width*6*4){let e=new Float32Array(s.width*6*4),n=new t.DataTexture(e,s.width,6,t.RGBAFormat,t.FloatType);n.minFilter=t.NearestFilter,n.magFilter=t.NearestFilter,s.data2=e,s.texture2=n}this._bakeStylesIntoBuffer(s.data,s.width,i,r,this.featureStyles),s.texture.needsUpdate=!0;let c=this._bakeStylesIntoBuffer(s.data2,s.width,i,r,e);s.texture2.needsUpdate=!0,n.userData.uBatchTex2.value=s.texture2,n.userData.uBatchTexActive.value=1,c.hasFade&&!n.transparent&&(n.transparent=!0)}}commitCrossFade(e,t){this.featureStyles.clear();for(let[t,n]of e)this.featureStyles.set(t,n);for(let e of t){let t=po(e);if(!t)continue;let n=this._meshBatchTextures.get(e);n&&n.data2&&n.texture2&&(n.data.set(n.data2),n.texture.needsUpdate=!0,t.userData.uBatchTex2.value=t.userData.uBatchTex.value)}this._onStyleChanged(),this._triggerRepaint()}cancelCrossFade(e){for(let t of e){let e=po(t);e&&(e.userData.uBatchTex2.value=e.userData.uBatchTex.value)}this._triggerRepaint()}markOverridesDirty(e,t){if(e)for(let t of e)this._markedMeshes.add(t);else if(t)for(let e of t)this._markedMeshes.add(e);else this._dirtyAll=!0,this._markedMeshes.clear();this._flushScheduled||(this._flushScheduled=!0,queueMicrotask(()=>this.flushOverrides()))}disposeMesh(e){this._markedMeshes.delete(e);let t=this._meshBatchTextures.get(e);t&&(t.texture.dispose(),t.texture2?.dispose(),this._meshBatchTextures.delete(e))}flushOverrides(){if(!this._flushScheduled&&!this._dirtyAll&&this._markedMeshes.size===0)return;this._flushScheduled=!1;let e=this._applyOverrideHook??(e=>this.applyOverridesToMesh(e));if(this._dirtyAll){this._dirtyAll=!1,this._markedMeshes.clear();let t=this._getAllMeshes?this._getAllMeshes():[];for(let n of t)e(n);this._triggerRepaint()}else{for(let t of this._markedMeshes)e(t);this._markedMeshes.clear(),this._triggerRepaint()}}bindGPUPath(e,t,n={},r){let i=this.getFeatureStyle(e)??{};this.setFeatureStyle(e,{...i,gpuPath:{pathId:t,speed:n.speed??0,phase:n.phase??0,loop:n.loop??`loop`,autoHeading:n.autoHeading??!0}},r)}unbindGPUPath(e,t){let n=this.getFeatureStyle(e);if(!n||!n.gpuPath)return;let r={...n};delete r.gpuPath,this.setFeatureStyle(e,r,t)}setGPUPathProgress(e,t,n){let r=this.getFeatureStyle(e);r?.gpuPath&&this.setFeatureStyle(e,{...r,gpuPath:{...r.gpuPath,speed:0,phase:Math.min(1,Math.max(0,t))}},n)}};y();var vo=class{constructor(e={}){v(this,`mode`,void 0),v(this,`opacity`,void 0),v(this,`color`,void 0),v(this,`gridColor`,void 0),v(this,`gridSize`,void 0),v(this,`excavationBounds`,null),v(this,`size`,void 0),v(this,`groundHeight`,0),v(this,`occlude`,void 0),v(this,`trackHeight`,void 0),v(this,`group`,void 0),v(this,`_mesh`,null),v(this,`_material`,null),v(this,`_depthMesh`,null),v(this,`_depthMaterial`,null),v(this,`_geom`,null),v(this,`_occludeExplicit`,void 0),this.mode=e.mode??`none`,this.opacity=e.opacity??.62,this.color=new t.Color(e.color??`#0f172a`),this.gridColor=new t.Color(e.gridColor??`#38bdf8`),this.gridSize=e.gridSize??10,this.excavationBounds=e.excavationBounds??null,this.size=e.size??6e3,this._occludeExplicit=e.occlude!==void 0,this.occlude=e.occlude??this.mode===`excavate`,this.trackHeight=e.trackHeight??!0,this.group=new t.Group,this.group.name=`s3m-ground-surface`,this._initMesh(),this._applyMode()}_initMesh(){let e=new t.PlaneGeometry(this.size,this.size,1,1);this._geom=e;let n=new t.ShaderMaterial({transparent:!0,depthTest:!0,depthWrite:!1,side:t.DoubleSide,uniforms:{uColor:{value:this.color},uGridColor:{value:this.gridColor},uOpacity:{value:this.opacity},uGridSize:{value:this.gridSize},uMode:{value:this.mode===`excavate`?2:+(this.mode===`translucent`)},uHasExcavation:{value:0},uExcavationMin:{value:new t.Vector2(-9999,-9999)},uExcavationMax:{value:new t.Vector2(9999,9999)}},vertexShader:`
908
+ 用 layer.auditBatches() 可以列出具体是哪些 SMID 共用了 batchId。`)),d.needsUpdate=!0,n.userData.uBatchTexActive&&(n.userData.uBatchTexActive.value=+!!f)}prepareCrossFade(e,n){for(let r of n){let n=mo(r);if(!n)continue;let i=r.userData.geoRef?.pickInfo;if(!i||Object.keys(i).length===0)continue;let a=0;for(let e of Object.values(i)){let t=H(e);t>a&&(a=t)}let o=Math.max(a+1,1),s=this._meshBatchTextures.get(r);if(!s||s.width<o){let e=new Float32Array(o*6*4),i=new t.DataTexture(e,o,6,t.RGBAFormat,t.FloatType);i.minFilter=t.NearestFilter,i.magFilter=t.NearestFilter,s={texture:i,data:e,width:o},this._meshBatchTextures.set(r,s),n.userData.uBatchTex.value=i,n.userData.uBatchTexWidth.value=o}if(!s.texture2||!s.data2||s.data2.length<s.width*6*4){let e=new Float32Array(s.width*6*4),n=new t.DataTexture(e,s.width,6,t.RGBAFormat,t.FloatType);n.minFilter=t.NearestFilter,n.magFilter=t.NearestFilter,s.data2=e,s.texture2=n}this._bakeStylesIntoBuffer(s.data,s.width,i,r,this.featureStyles),s.texture.needsUpdate=!0;let c=this._bakeStylesIntoBuffer(s.data2,s.width,i,r,e);s.texture2.needsUpdate=!0,n.userData.uBatchTex2.value=s.texture2,n.userData.uBatchTexActive.value=1,c.hasFade&&!n.transparent&&(n.transparent=!0)}}commitCrossFade(e,t){this.featureStyles.clear();for(let[t,n]of e)this.featureStyles.set(t,n);for(let e of t){let t=mo(e);if(!t)continue;let n=this._meshBatchTextures.get(e);n&&n.data2&&n.texture2&&(n.data.set(n.data2),n.texture.needsUpdate=!0,t.userData.uBatchTex2.value=t.userData.uBatchTex.value)}this._onStyleChanged(),this._triggerRepaint()}cancelCrossFade(e){for(let t of e){let e=mo(t);e&&(e.userData.uBatchTex2.value=e.userData.uBatchTex.value)}this._triggerRepaint()}markOverridesDirty(e,t){if(e)for(let t of e)this._markedMeshes.add(t);else if(t)for(let e of t)this._markedMeshes.add(e);else this._dirtyAll=!0,this._markedMeshes.clear();this._flushScheduled||(this._flushScheduled=!0,queueMicrotask(()=>this.flushOverrides()))}disposeMesh(e){this._markedMeshes.delete(e);let t=this._meshBatchTextures.get(e);t&&(t.texture.dispose(),t.texture2?.dispose(),this._meshBatchTextures.delete(e))}flushOverrides(){if(!this._flushScheduled&&!this._dirtyAll&&this._markedMeshes.size===0)return;this._flushScheduled=!1;let e=this._applyOverrideHook??(e=>this.applyOverridesToMesh(e));if(this._dirtyAll){this._dirtyAll=!1,this._markedMeshes.clear();let t=this._getAllMeshes?this._getAllMeshes():[];for(let n of t)e(n);this._triggerRepaint()}else{for(let t of this._markedMeshes)e(t);this._markedMeshes.clear(),this._triggerRepaint()}}bindGPUPath(e,t,n={},r){let i=this.getFeatureStyle(e)??{};this.setFeatureStyle(e,{...i,gpuPath:{pathId:t,speed:n.speed??0,phase:n.phase??0,loop:n.loop??`loop`,autoHeading:n.autoHeading??!0}},r)}unbindGPUPath(e,t){let n=this.getFeatureStyle(e);if(!n||!n.gpuPath)return;let r={...n};delete r.gpuPath,this.setFeatureStyle(e,r,t)}setGPUPathProgress(e,t,n){let r=this.getFeatureStyle(e);r?.gpuPath&&this.setFeatureStyle(e,{...r,gpuPath:{...r.gpuPath,speed:0,phase:Math.min(1,Math.max(0,t))}},n)}};y();var yo=class{constructor(e={}){v(this,`mode`,void 0),v(this,`opacity`,void 0),v(this,`color`,void 0),v(this,`gridColor`,void 0),v(this,`gridSize`,void 0),v(this,`excavationBounds`,null),v(this,`size`,void 0),v(this,`groundHeight`,0),v(this,`occlude`,void 0),v(this,`trackHeight`,void 0),v(this,`group`,void 0),v(this,`_mesh`,null),v(this,`_material`,null),v(this,`_depthMesh`,null),v(this,`_depthMaterial`,null),v(this,`_geom`,null),v(this,`_occludeExplicit`,void 0),this.mode=e.mode??`none`,this.opacity=e.opacity??.62,this.color=new t.Color(e.color??`#0f172a`),this.gridColor=new t.Color(e.gridColor??`#38bdf8`),this.gridSize=e.gridSize??10,this.excavationBounds=e.excavationBounds??null,this.size=e.size??6e3,this._occludeExplicit=e.occlude!==void 0,this.occlude=e.occlude??this.mode===`excavate`,this.trackHeight=e.trackHeight??!0,this.group=new t.Group,this.group.name=`s3m-ground-surface`,this._initMesh(),this._applyMode()}_initMesh(){let e=new t.PlaneGeometry(this.size,this.size,1,1);this._geom=e;let n=new t.ShaderMaterial({transparent:!0,depthTest:!0,depthWrite:!1,side:t.DoubleSide,uniforms:{uColor:{value:this.color},uGridColor:{value:this.gridColor},uOpacity:{value:this.opacity},uGridSize:{value:this.gridSize},uMode:{value:this.mode===`excavate`?2:+(this.mode===`translucent`)},uHasExcavation:{value:0},uExcavationMin:{value:new t.Vector2(-9999,-9999)},uExcavationMax:{value:new t.Vector2(9999,9999)}},vertexShader:`
827
909
  varying vec2 vEnuPos;
828
910
  void main() {
829
911
  vec4 worldPos = modelMatrix * vec4(position, 1.0);
@@ -901,4 +983,4 @@ var S3M=(function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.
901
983
  }
902
984
  gl_FragColor = vec4(1.0);
903
985
  }
904
- `}),a=new t.Mesh(e,i);a.position.set(0,0,-.02),a.renderOrder=-1e3,a.name=`s3m-ground-depth`,a.visible=!1,this.group.add(a),this._depthMesh=a,this._depthMaterial=i,this._syncUniforms()}_applyMode(){this._mesh&&(this._mesh.visible=this.mode!==`none`),this._material&&(this._material.uniforms.uMode.value=this.mode===`excavate`?2:+(this.mode===`translucent`),this._material.depthWrite=this.mode===`excavate`),this._depthMesh&&(this._depthMesh.visible=this.occlude,this._depthMaterial&&(this._depthMaterial.uniforms.uPunchPit.value=+(this.mode===`excavate`)))}update(e){e&&this.group.position.set(e.position.x,e.position.y,this.groundHeight)}setGroundHeight(e){this.groundHeight=e,this.group.position.z=e}setMode(e){this.mode=e,this._occludeExplicit||(this.occlude=e===`excavate`),this._applyMode()}setOcclude(e){this.occlude=e,this._occludeExplicit=!0,this._applyMode()}setOpacity(e){this.opacity=Math.max(0,Math.min(1,e)),this._material&&(this._material.uniforms.uOpacity.value=this.opacity)}setColors(e,t){this.color.set(e),t&&this.gridColor.set(t),this._material&&(this._material.uniforms.uColor.value=this.color,this._material.uniforms.uGridColor.value=this.gridColor)}setExcavationBounds(e){this.excavationBounds=e,this._syncUniforms()}autoFitExcavation(e){let t=1/0,n=1/0,r=-1/0,i=-1/0,a=!1;for(let o of e){let e=o.tileset?.config,s=e?.rootTiles??e?.tiles;if(Array.isArray(s))for(let e of s){let s=e.boundingBox;if(!s)continue;let c=s.center??{x:0,y:0},l=s.xExtent?.x?Math.abs(s.xExtent.x):50,u=s.yExtent?.y?Math.abs(s.yExtent.y):50,d=c.x+o.offset[0]-l,f=c.x+o.offset[0]+l,p=c.y+o.offset[1]-u,m=c.y+o.offset[1]+u;d<t&&(t=d),f>r&&(r=f),p<n&&(n=p),m>i&&(i=m),a=!0}}a&&Number.isFinite(t)&&this.setExcavationBounds([t-5,n-5,r+5,i+5])}_syncUniforms(){let e=this.excavationBounds;if(this._material){let t=this._material.uniforms;e?(t.uHasExcavation.value=1,t.uExcavationMin.value.set(e[0],e[1]),t.uExcavationMax.value.set(e[2],e[3])):t.uHasExcavation.value=0}if(this._depthMaterial){let t=this._depthMaterial.uniforms;e?(t.uHasExcavation.value=1,t.uExcavationMin.value.set(e[0],e[1]),t.uExcavationMax.value.set(e[2],e[3])):t.uHasExcavation.value=0}}dispose(){this._geom?.dispose(),this._geom=null,this._material?.dispose(),this._material=null,this._depthMaterial?.dispose(),this._depthMaterial=null,this._mesh=null,this._depthMesh=null,this.group.clear()}};Wr(),mi(),Kr(),Yr(),Tt(),y();var yo=65534;function $(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function bo(e){return e.isPoints===!0}var xo=[`opacity`,`floorHeight`,`selectOpacity`,`selectEmissive`,`selectElevation`,`dimFactor`,`texMix`,`roofThreshold`,`ambientGain`,`edgeWidth`,`edgeOpacity`,`outlineWidth`],So=[`colorA`,`colorB`,`colorC`,`selectColor`,`edgeColor`],Co=[`translation`,`elevation`,`opacity`,`color`,`rotation`],wo=class e{get datasets(){return this._datasetManager.datasets}get sceneAnchor(){return this._datasetManager.sceneAnchor}set sceneAnchor(e){this._datasetManager.sceneAnchor=e}_requestRepaint(){this._onRequestRepaint()}triggerRepaint(){this._requestRepaint()}constructor(e={}){v(this,`options`,void 0),v(this,`pickable`,void 0),v(this,`onStats`,void 0),v(this,`onReady`,void 0),v(this,`onPick`,void 0),v(this,`onError`,void 0),v(this,`geo`,null),v(this,`canvas`,null),v(this,`renderer`,null),v(this,`scene`,null),v(this,`camera`,null),v(this,`picker`,null),v(this,`uniforms`,void 0),v(this,`style`,void 0),v(this,`_styleTarget`,void 0),v(this,`outlineMaterial`,void 0),v(this,`lineShared`,void 0),v(this,`edgeMaterial`,void 0),v(this,`selectionEdgeMaterial`,void 0),v(this,`_edgeStyleUniforms`,void 0),v(this,`_selEdgeStyleUniforms`,void 0),v(this,`groundManager`,void 0),v(this,`_datasetManager`,new lo),v(this,`_featureStyleManager`,void 0),v(this,`gpuPathManager`,new Jr),v(this,`_customPathTime`,!1),v(this,`_pickables`,new Map),v(this,`_pickSeq`,0),v(this,`_freePickIds`,[]),v(this,`_smidMeshes`,new Map),v(this,`_meshHeight`,new Map),v(this,`_heightMin`,1/0),v(this,`_heightMax`,-1/0),v(this,`_boxScratch`,new t.Box3),v(this,`_selection`,null),v(this,`_selectedMeshes`,[]),v(this,`_outlineMesh`,null),v(this,`_outlineMeshes`,[]),v(this,`_selectionEdges`,null),v(this,`_selectionEdgeMeshes`,[]),v(this,`_edgesEnabled`,!1),v(this,`_tileFadeSeq`,0),v(this,`_modeGen`,0),v(this,`_pathSpecs`,new Map),v(this,`_pathScratch`,new Float32Array(3)),v(this,`_creaseLines`,null),v(this,`_nativeEdgeLines`,new Set),v(this,`_pointClouds`,new Set),v(this,`_opacityTransparent`,!1),v(this,`animator`,new Xa),v(this,`attributeQuery`,null),v(this,`_enuMatrix`,new t.Matrix4),v(this,`_colorScratch`,new t.Color),v(this,`_needsRepaint`,!0),v(this,`_frame`,0),v(this,`_fps`,{value:0,last:0}),v(this,`_ambientLight`,void 0),v(this,`_hemiLight`,void 0),v(this,`_keyLight`,void 0),v(this,`_fillLight`,void 0),v(this,`_lightOptions`,{ambientIntensity:.4,ambientColor:16777215,hemisphereIntensity:.8,hemisphereColor:16777215,hemisphereGroundColor:11976907,keyLightIntensity:1,keyLightColor:16777215,fillLightIntensity:.35,fillLightColor:16777215,mode:`headlamp`,azimuth:150,altitude:50}),v(this,`_datasetQueue`,void 0),v(this,`_onRequestRepaint`,()=>{}),v(this,`_getBearing`,void 0),v(this,`_lodRangeScale`,1),this.options=e,this.pickable=e.pickable!==!1,this._lodRangeScale=e.lodRangeScale??1,e.light&&Object.assign(this._lightOptions,e.light),e.totalMaxTiles&&(this._datasetManager.totalMaxTiles=e.totalMaxTiles),this._onRequestRepaint=e.onRequestRepaint??(()=>{}),this._getBearing=e.getBearing,this.onStats=e.onStats??(()=>{}),this.onReady=e.onReady??(()=>{}),this.onPick=e.onPick??(()=>{}),this.onError=e.onError??(e=>console.warn(`[s3m]`,e)),this.groundManager=new vo(e.ground),this.scene||(this.scene=new t.Scene,this.scene.add(this.groundManager.group),this._addLights()),this._featureStyleManager=new _o(()=>this.style.floorHeight,()=>this._requestRepaint(),()=>{this._selection&&this._syncSelectionStyle()},()=>this.getAllMeshes(),e=>this._applyOverridesToMesh(e),()=>this._opacityTransparent),this.uniforms=Xr(),Ir(Bt),this.style={...ti,...e.style??{}},this._styleTarget={...this.style},this._opacityTransparent=(this.style.opacity??1)<.999,this._applyStyleUniforms(),this._registerAnimChannels(),this.animator.onActive=()=>this._requestRepaint(),this.outlineMaterial=Qr(this.uniforms),this.lineShared=Za(),this._edgeStyleUniforms={uColor:{value:new t.Color(this.style.edgeColor)},uWidth:{value:Math.max(.1,this.style.edgeWidth??1.5)},uOpacity:{value:.6}},this.edgeMaterial=eo(this.lineShared,{},this._edgeStyleUniforms),this._selEdgeStyleUniforms={uColor:{value:new t.Color(this.style.outlineColor??this.style.selectColor)},uWidth:{value:Math.max(.1,this.style.outlineWidthPx??3)},uOpacity:{value:1},uElevation:{value:this.style.selectElevation??0}},this.selectionEdgeMaterial=eo(this.lineShared,{},this._selEdgeStyleUniforms),this.setEdges(!!this.style.edges),this._fps.last=performance.now(),this._datasetQueue=this._normalizeDatasets(e),e.attributes&&(this.attributeQuery=new At(e.attributes))}_createRenderer(e,n){let r=new t.WebGLRenderer({canvas:e,context:n,antialias:!0});return r.autoClear=!1,r.setPixelRatio(1),r.toneMapping=this.options.toneMapping===void 0?t.NoToneMapping:this.options.toneMapping,r.toneMappingExposure=this.options.toneMappingExposure??1,r}_syncTextureCapabilities(e){let t=!!e.getExtension(`WEBGL_compressed_texture_s3tc`),n=!!e.getExtension(`WEBGL_compressed_texture_s3tc_srgb`);Fr(t&&n)}mount(e,n){this.canvas=e,this.renderer=this._createRenderer(e,n),Pr(this.renderer.capabilities.getMaxAnisotropy()),this._syncTextureCapabilities(n),this.scene=new t.Scene,this.scene.add(this.groundManager.group),this._addLights(),this.camera=new t.Camera,this.camera.matrixAutoUpdate=!1,this.picker=new va(this.renderer),this._applyStyleUniforms();for(let e of this._datasetQueue)this.addDataset(e).catch(e=>this.onError(e));this._recomputeAnchors()}restoreContext(e){if(!this.canvas)console.warn(`[s3m] restoreContext 调用过早(尚未 mount),按首次挂载处理`);else{try{this.renderer?.dispose()}catch{}this.renderer=this._createRenderer(this.canvas,e),Pr(this.renderer.capabilities.getMaxAnisotropy()),this._syncTextureCapabilities(e),this.picker?.dispose(),this.picker=new va(this.renderer),this._requestRepaint()}}unmount(){for(let e of[...this.datasets.keys()])this.removeDataset(e);this.clearCreases(),this.groundManager.dispose(),this.picker?.dispose(),this.picker=null,this.outlineMaterial.dispose(),this.edgeMaterial.dispose(),this.selectionEdgeMaterial.dispose(),this.scene?.clear(),this._selectedMeshes=[],this._outlineMeshes=[],this._selectionEdgeMeshes=[],this._outlineMesh=null,this._selectionEdges=null,this._smidMeshes.clear(),this._meshHeight.clear(),this.animator.clear(),this.animator.unregisterPrefix(`tile.`),this.animator.unregisterPrefix(`feature.`),this._pathSpecs.clear(),this._heightMin=1/0,this._heightMax=-1/0,this.renderer?.dispose(),this.renderer=null,this.canvas=null}_createLights(){this._ambientLight=new t.AmbientLight(this._lightOptions.ambientColor,this._lightOptions.ambientIntensity),this._hemiLight=new t.HemisphereLight(this._lightOptions.hemisphereColor,this._lightOptions.hemisphereGroundColor,this._lightOptions.hemisphereIntensity),this._keyLight=new t.DirectionalLight(this._lightOptions.keyLightColor,this._lightOptions.keyLightIntensity),this._fillLight=new t.DirectionalLight(this._lightOptions.fillLightColor,this._lightOptions.fillLightIntensity),this._updateLights()}_addLights(){this.scene&&(this._ambientLight||this._createLights(),this.scene.add(this._ambientLight,this._hemiLight,this._keyLight,this._fillLight))}_applyLightOptions(){this._ambientLight&&(this._ambientLight.intensity=this._lightOptions.ambientIntensity,this._ambientLight.color.set(this._lightOptions.ambientColor)),this._hemiLight&&(this._hemiLight.intensity=this._lightOptions.hemisphereIntensity,this._hemiLight.color.set(this._lightOptions.hemisphereColor),this._hemiLight.groundColor.set(this._lightOptions.hemisphereGroundColor)),this._keyLight&&(this._keyLight.intensity=this._lightOptions.keyLightIntensity,this._keyLight.color.set(this._lightOptions.keyLightColor)),this._fillLight&&(this._fillLight.intensity=this._lightOptions.fillLightIntensity,this._fillLight.color.set(this._lightOptions.fillLightColor))}setLight(e){let t={...e};t.mainColor!==void 0&&t.keyLightColor===void 0&&(t.keyLightColor=t.mainColor),t.mainIntensity!==void 0&&t.keyLightIntensity===void 0&&(t.keyLightIntensity=t.mainIntensity),Object.assign(this._lightOptions,t),this._applyLightOptions(),this._updateLights(),this._needsRepaint=!0,this.triggerRepaint()}getLight(){return{...this._lightOptions}}setToneMapping(e,t=1){this.options.toneMapping=e,this.options.toneMappingExposure=t,this.renderer&&(this.renderer.toneMapping=e,this.renderer.toneMappingExposure=t,this._needsRepaint=!0,this.triggerRepaint())}getToneMapping(){return{toneMapping:this.renderer?this.renderer.toneMapping:this.options.toneMapping??t.NoToneMapping,toneMappingExposure:this.renderer?this.renderer.toneMappingExposure:this.options.toneMappingExposure??1}}_updateLights(){if(!this._keyLight||!this._fillLight)return;let e=this._lightOptions.mode===`fixed`?0:(this._getBearing?.()??0)*Math.PI/180,t=(t,n,r)=>{if(!t)return;let i=e+n*Math.PI/180,a=r*Math.PI/180,o=Math.cos(a);t.position.set(Math.sin(i)*o,Math.cos(i)*o,Math.sin(a)).multiplyScalar(1e3)};t(this._keyLight,this._lightOptions.azimuth,this._lightOptions.altitude),t(this._fillLight,this._lightOptions.azimuth+65,Math.max(10,this._lightOptions.altitude-20))}_normalizeDatasets(e){return Array.isArray(e.datasets)?e.datasets.filter(e=>!!e?.configUrl):e.configUrl?[{id:`default`,name:`默认数据集`,configUrl:e.configUrl,useWorker:e.useWorker}]:[]}async addDataset(e){if(!this.scene)throw Error(`[s3m] 图层尚未 addLayer,不能添加数据集`);return await this._datasetManager.addDataset(e,this.scene,this.geo,this.uniforms,this._lodRangeScale,this.options.buildTile,this.options.maxTiles??64,this.options.maxConcurrent??4,{onTile:(e,t)=>{this._registerTile(e,t),this.onStats(this.stats),this._needsRepaint=!0,this._requestRepaint()},onTileRemoved:(e,t)=>{this._unregisterTile(e,t),this.onStats(this.stats),this._needsRepaint=!0,this._requestRepaint()},onStats:()=>{this.onStats(this.stats),this._requestRepaint()},onError:e=>{this.onError(e),this.onStats(this.stats)},onReady:e=>{this.onReady(e),this._refreshAllHeights(),this.groundManager.excavationBounds||this.groundManager.autoFitExcavation(this.datasets.values())},triggerRepaint:()=>{this._requestRepaint()}})}_lngLatFromWorld(e,t){return Ft(this.geo,e,t)}recomputeAnchors(){this._datasetManager.recomputeAnchors(this.geo),this._refreshAllHeights(),this._requestRepaint()}_recomputeAnchors(){this.recomputeAnchors()}getDatasetHeight(e){return this._datasetManager.getDatasetHeight(e)}setDatasetHeight(e,t){let n,r;typeof e==`number`?(n=this.datasets.keys().next().value??``,r=e):(n=e,r=t??0),this._datasetManager.setDatasetHeight(n,r,this.geo),this._syncGroundHeight(),this._refreshAllHeights(),this._requestRepaint()}_syncGroundHeight(){if(!this.groundManager.trackHeight)return;let e=this.datasets.keys().next().value;if(!e)return;let t=this._datasetManager.getDatasetHeight(e);this.groundManager.setGroundHeight(t)}setDatasetAlign(e,t){let n,r;t===void 0&&(e===`origin`||e===`bottom`||e===`top`||e===`center`)?(n=this.datasets.keys().next().value??``,r=e):(n=e,r=t??`origin`),this._datasetManager.setDatasetAlign(n,r,this.geo),this._refreshAllHeights(),this._requestRepaint()}_computeAlignOffset(e,t){return this._datasetManager.computeAlignOffset(e,t)}computeAlignOffset(e,t){return this._datasetManager.computeAlignOffset(e,t)}setFeatureStyle(e,t){this._featureStyleManager.setFeatureStyle(e,t,this._meshesOf([e]))}setFeaturesStyle(e,t){this._featureStyleManager.setFeaturesStyle(e,t,this._meshesOf(e))}moveFeature(e,t,n){let r=this._ensureFeatureChannel(e,`translation`);this.animator.to(r,t,n)}moveFeatureBy(e,t,n){let r=this._featureStyleManager.getFeatureStyle(e)?.translation??[0,0,0];this.moveFeature(e,[r[0]+t[0],r[1]+t[1],r[2]+t[2]],n)}rotateFeature(e,t,n,r){let i=this._featureStyleManager.getFeatureStyle(e)??{};n&&this._featureStyleManager.setFeatureStyle(e,{...i,pivot:n},this._meshesOf([e]));let a=fo(t),o=this._ensureFeatureChannel(e,`rotation`);this.animator.to(o,a,r)}rotateFeatureBy(e,t,n,r){let i=fo(this._featureStyleManager.getFeatureStyle(e)?.rotation),a=typeof t==`number`?[0,0,t]:t;this.rotateFeature(e,[i[0]+a[0],i[1]+a[1],i[2]+a[2]],n,r)}crossFadeStyles(e,t){let n=e instanceof Map?e:new Map(Object.entries(e).map(([e,t])=>[Number(e),t])),r=this.getAllMeshes();this._featureStyleManager.prepareCrossFade(n,r);let i=`batch.mix`;this.animator.has(i)||this.animator.register(i,{dim:1,read:e=>{e[0]=this.uniforms.uBatchMix?.value??0},write:e=>{this.uniforms.uBatchMix&&(this.uniforms.uBatchMix.value=e[0]),this.triggerRepaint()}}),(t?.duration??0)>0||t?.spring?(this.uniforms.uBatchMix&&(this.uniforms.uBatchMix.value=0),this.animator.to(i,1,{...t,onComplete:()=>{this.uniforms.uBatchMix&&(this.uniforms.uBatchMix.value=0),this._featureStyleManager.commitCrossFade(n,r),this.triggerRepaint(),t?.onComplete?.()}})):(this.animator.has(i)&&this.animator.cancel(i),this.uniforms.uBatchMix&&(this.uniforms.uBatchMix.value=0),this._featureStyleManager.commitCrossFade(n,r),this.triggerRepaint(),t?.onComplete?.())}followPath(e,t,n={}){let r=t instanceof Gr?t:new Gr(t,{closed:n.closed});if(r.length<=0)return;let i=n.offset??[0,0,0],a=n.duration??(n.speed&&n.speed>0?r.length/n.speed*1e3:2e3),o=`feature.${e}.path`;this._pathSpecs.set(o,{path:r,offset:i}),this.animator.has(o)||this.animator.register(o,{dim:1,read:e=>{e[0]=0},write:t=>{let n=this._pathSpecs.get(o);if(!n)return;n.path.sampleAt(t[0],this._pathScratch);let r=this._meshesOf([e]),i=this._featureStyleManager.getFeatureStyle(e)??{};this._featureStyleManager.setFeatureStyle(e,{...i,translation:[n.offset[0]+this._pathScratch[0],n.offset[1]+this._pathScratch[1],n.offset[2]+this._pathScratch[2]]},r);for(let e of r)e.frustumCulled=!1}});let s=()=>{this.animator.to(o,1,{duration:a,easing:n.easing??`linear`,onComplete:()=>{n.loop?s():n.onComplete?.()}})};s()}stopPath(e){let t=`feature.${e}.path`;this.animator.cancel(t),this.animator.unregister(t),this._pathSpecs.delete(t)}registerGPUPath(e,t={}){let n=this.gpuPathManager.registerPath(e,t);return this.gpuPathManager.updateUniforms(this.uniforms),n}unregisterGPUPath(e){let t=this.gpuPathManager.unregisterPath(e);return this.gpuPathManager.updateUniforms(this.uniforms),t}getGPUPathManager(){return this.gpuPathManager}bindGPUPath(e,t,n={}){let r;r=typeof t==`number`?t:this.registerGPUPath(t);let i=this._meshesOf([e]);this._featureStyleManager.bindGPUPath(e,r,n,i);for(let e of i)e.frustumCulled=!1;return this.gpuPathManager.updateUniforms(this.uniforms),r}unbindGPUPath(e){let t=this._meshesOf([e]);this._featureStyleManager.unbindGPUPath(e,t),this.gpuPathManager.updateUniforms(this.uniforms)}setGPUPathProgress(e,t){let n=this._meshesOf([e]);this._featureStyleManager.setGPUPathProgress(e,t,n);for(let e of n)e.frustumCulled=!1}setGPUPathTime(e,t=!1){this.uniforms.uPathTime&&(this.uniforms.uPathTime.value=e),this._customPathTime=!t}getGPUPathTime(){return this.uniforms.uPathTime?.value??0}animateFeature(e,t,n){if(t.translation&&this.moveFeature(e,t.translation,n),t.rotation!=null&&this.rotateFeature(e,t.rotation,t.pivot,n),t.elevation!=null&&this.animator.to(this._ensureFeatureChannel(e,`elevation`),t.elevation,n),t.opacity!=null&&this.animator.to(this._ensureFeatureChannel(e,`opacity`),t.opacity,n),t.color&&(this._colorScratch.set(t.color),this.animator.to(this._ensureFeatureChannel(e,`color`),[this._colorScratch.r,this._colorScratch.g,this._colorScratch.b],n)),t.hidden!=null){let n=this._featureStyleManager.getFeatureStyle(e)??{};this.setFeatureStyle(e,{...n,hidden:t.hidden})}}animateFeatures(e,t,n){let r=n?.stagger??0;if(r<=0){for(let r of e)this.animateFeature(r,t,n);return}let i=n?.delay??0;for(let a=0;a<e.length;a++)this.animateFeature(e[a],t,{...n,delay:i+a*r})}setMode(e,t={}){let n=Math.max(0,t.duration??300),r=Math.min(1,Math.max(.05,t.dim??.35));if(this.style.mode===e)return Promise.resolve();if(n<=0)return this.setStyle({mode:e}),Promise.resolve();let i=++this._modeGen;return new Promise(t=>{this.animator.to(`style.fade`,r,{duration:n,easing:`easeInOutQuad`,onComplete:()=>{i===this._modeGen?(this.setStyle({mode:e}),this.animator.to(`style.fade`,1,{duration:n,easing:`easeInOutQuad`,onComplete:t})):t()}})})}_ensureFeatureChannel(e,t){let n=`feature.${e}.${t}`;if(this.animator.has(n))return n;let r=t===`translation`||t===`color`||t===`rotation`?{dim:3,read:n=>{if(t===`translation`){let t=this._featureStyleManager.getFeatureStyle(e)?.translation;n[0]=t?.[0]??0,n[1]=t?.[1]??0,n[2]=t?.[2]??0}else if(t===`rotation`){let t=this._featureStyleManager.getFeatureStyle(e)?.rotation,r=fo(t);n[0]=r[0],n[1]=r[1],n[2]=r[2]}else{let t=this._featureStyleManager.getFeatureStyle(e)?.color??this.style.colorA;this._colorScratch.set(t),n[0]=this._colorScratch.r,n[1]=this._colorScratch.g,n[2]=this._colorScratch.b}},write:n=>{let r=this._meshesOf([e]),i=this._featureStyleManager.getFeatureStyle(e)??{};if(t===`translation`){this._featureStyleManager.setFeatureStyle(e,{...i,translation:[n[0],n[1],n[2]]},r);let t=Math.abs(n[0])>1e-6||Math.abs(n[1])>1e-6||Math.abs(n[2])>1e-6,a=fo(i.rotation),o=Math.abs(a[0])>1e-6||Math.abs(a[1])>1e-6||Math.abs(a[2])>1e-6;for(let e of r)e.frustumCulled=!(t||o)}else if(t===`rotation`){this._featureStyleManager.setFeatureStyle(e,{...i,rotation:[n[0],n[1],n[2]]},r);let t=Math.abs(n[0])>1e-6||Math.abs(n[1])>1e-6||Math.abs(n[2])>1e-6,a=i.translation??[0,0,0],o=Math.abs(a[0])>1e-6||Math.abs(a[1])>1e-6||Math.abs(a[2])>1e-6;for(let e of r)e.frustumCulled=!(t||o)}else{let t=this._colorScratch.setRGB(n[0],n[1],n[2]);this._featureStyleManager.setFeatureStyle(e,{...i,color:`#${t.getHexString()}`},r)}}}:{dim:1,read:n=>{let r=this._featureStyleManager.getFeatureStyle(e);n[0]=(t===`elevation`?r?.elevation:r?.opacity)??+(t===`opacity`)},write:n=>{let r=this._featureStyleManager.getFeatureStyle(e)??{},i=t===`elevation`?{...r,elevation:n[0]}:{...r,opacity:n[0]};this._featureStyleManager.setFeatureStyle(e,i,this._meshesOf([e]))}};return this.animator.register(n,r),n}_releaseFeatureChannels(e){for(let t of Co)this.animator.unregister(`feature.${e}.${t}`);let t=`feature.${e}.path`;this.animator.unregister(t),this._pathSpecs.delete(t)}getFeatureStyle(e){return this._featureStyleManager.getFeatureStyle(e)}getFeatureStyles(){return this._featureStyleManager.getFeatureStyles()}removeFeatureStyle(e){this._releaseFeatureChannels(e),this._featureStyleManager.removeFeatureStyle(e,this._meshesOf([e]))}clearFeatureStyles(){for(let e of this._featureStyleManager.getFeatureStyles().keys())this._releaseFeatureChannels(e);this._featureStyleManager.clearFeatureStyles()}setAttributeSource(e){this.attributeQuery=e?new At(e):null}getLoadedSmids(){return[...this._smidMeshes.keys()]}auditBatches(){let e=this._featureStyleManager.auditBatches(this._pickables.values());return e.smids=this._smidMeshes.size,e}getThematicField(){return this._featureStyleManager.thematicField}setThematicColors(e,t=`custom`){this._featureStyleManager.setThematicColors(e,t)}clearThematic(){this._featureStyleManager.clearThematicColors()}getFilterField(){return this._featureStyleManager.fieldFilter?.field??null}filterByField(e){return this._featureStyleManager.filterByField(e,this.attributeQuery,this.getLoadedSmids())}clearFieldFilter(){this._featureStyleManager.clearFieldFilter()}getElevationField(){return this._featureStyleManager.elevationField}elevateByField(e){return this._featureStyleManager.elevateByField(e,this.attributeQuery,this.getLoadedSmids())}setThematicElevation(e,t=`custom`){this._featureStyleManager.setThematicElevation(e,t)}clearThematicElevation(){this._featureStyleManager.clearThematicElevation()}colorByField(e){return this._featureStyleManager.colorByField(e,this.attributeQuery,this.getLoadedSmids())}setFilter(e){this._featureStyleManager.setFilter(e,this.uniforms)}getFilter(){return this._featureStyleManager.filter}clearFilter(){this._featureStyleManager.clearFilter(this.uniforms)}setGroundMode(e){this.groundManager.setMode(e),this._requestRepaint()}setGroundOpacity(e){this.groundManager.setOpacity(e),this._requestRepaint()}setExcavationBounds(e){this.groundManager.setExcavationBounds(e),this._requestRepaint()}setGroundOcclude(e){this.groundManager.setOcclude(e),this._requestRepaint()}_isFeatureHidden(e,t){if(e==null)return!1;let n=this._featureStyleManager.fieldFilter;if(n){let t=n.matched.has(e);if(n.mode===`keep`?!t:t)return!0}let r=this._featureStyleManager.filter;return!!(r&&(r.include&&r.include.length>0&&!r.include.includes(e)||r.exclude&&r.exclude.length>0&&r.exclude.includes(e))||this._featureStyleManager.featureStyles.get(e)?.hidden)}getAllMeshes(){let e=[];for(let t of this._pickables.values())e.push(t.mesh);return e}_meshesOf(e){let t=new Set;for(let n of e){let e=this._smidMeshes.get(n);if(e)for(let n of e)t.add(n)}return t}_markOverridesDirty(e=`all`){e===`all`?this._featureStyleManager.markOverridesDirty(void 0,this.getAllMeshes()):this._featureStyleManager.markOverridesDirty(e)}flushOverrides(){this._featureStyleManager.flushOverrides()}_applyOverridesToMesh(e){this._featureStyleManager.applyOverridesToMesh(e)}removeDataset(e){if(this.datasets.get(e)){this._selection?.datasetId===e&&this.select(null),this._datasetManager.removeDataset(e,this.scene,this.geo,e=>{e.root.traverse(e=>{let t=e,n=t.userData;n.pickId!=null&&(this._pickables.delete(n.pickId),this._releasePickId(n.pickId),n.pickId=void 0),this._unindexMeshSmids(t),this._removeMeshHeight(t),t.geometry?.dispose?.();let r=$(t);r&&r.dispose(),fa(t.material)&&t.material.dispose(),this._featureStyleManager.disposeMesh(t)})});for(let[t,n]of this._pickables)n.datasetId===e&&this._pickables.delete(t);this.onStats(this.stats),this._requestRepaint()}}clearDatasets(){for(let e of[...this.datasets.keys()])this.removeDataset(e)}setDatasetVisible(e,t){this._datasetManager.setDatasetVisible(e,t),!t&&this._selection?.datasetId===e&&this.select(null),this._requestRepaint()}_registerTile(e,t){t.root.add(e.group),e.group.updateMatrixWorld(!0);let n=e.group.userData.hasNativeEdges===!0;for(let r of e.group.children){if(r.isLineSegments&&r.userData.isEdgeLines){r.visible=this._edgesEnabled,this._nativeEdgeLines.add(r),this._styleEdgeLine(r);continue}let i=bo(r),a=r;if(!a.isMesh&&!i)continue;i&&this._pointClouds.add(r);let o=a.userData;if(o.pickId=this._allocPickId(),o.datasetId=t.id,o.nativeEdges=n,this._pickables.set(o.pickId,{datasetId:t.id,mesh:a,tile:e.tile,skeletonName:o.skeletonName??``}),this._indexMeshSmids(a),this._addMeshHeight(a),!n&&!i&&this._datasetEdgesEnabled(t)&&!this._shouldSkipAutoEdges(o,t.name)&&this._ensureEdges(a),i)this._applyPointCloudStyle(r);else{let e=$(a);if(e){let t=Math.min(1,Math.max(.05,this.style.opacity??1));e.transparent=t<.999,e.depthWrite=t>=.999,e.flatShading=this.style.shading!==`smooth`,e.needsUpdate=!0,this._featureStyleManager.applyOverridesToMesh(a),this._startTileFade(a,e)}}this._replaySelectionOnto(a)}}_startTileFade(e,t){let n=this.style.fadeIn??0;if(n<=0)return;let r=t.userData.uTileFade;if(!r)return;r.value=0,t.transparent=!0,t.depthWrite=!0;let i=`tile.${this._tileFadeSeq++}.fade`;e.userData.tileFadeKey=i,this.animator.register(i,{dim:1,read:e=>{e[0]=r.value},write:e=>{r.value=e[0]}}),this.animator.to(i,1,{duration:n,easing:`easeOutQuad`,onComplete:()=>{r.value=1,e.userData.tileFadeKey=void 0,this.animator.unregister(i),this._featureStyleManager.applyOverridesToMesh(e),t.transparent||(t.depthWrite=!0),this._requestRepaint()}})}_isMeshCoveringSelection(e,n){if(!n.point)return!1;let r=e.geometry;if(!r||(r.boundingBox||r.computeBoundingBox(),!r.boundingBox))return!1;let i=new t.Vector3(n.point[0],n.point[1],n.point[2]);e.updateWorldMatrix(!0,!1);let a=e.matrixWorld.clone().invert(),o=i.applyMatrix4(a);return r.boundingBox.clone().expandByScalar(.5).containsPoint(o)}_replaySelectionOnto(e){let t=this._selection;if(!t)return;let n=$(e);if(!n)return;let r=e.userData,i=-1;if(t.smid!=null){let e=r.geoRef?.pickInfo,n=e?.[t.smid]??e?.[String(t.smid)];i=n?H(n):-1}if(e===t.mesh&&(i=t.batchId),i<0&&e!==t.mesh){if(t.smid==null&&r.datasetId===t.datasetId&&this._isMeshCoveringSelection(e,t))i=-1;else return}n.userData.uSelBatch.value=i,n.userData.uSelWhole.value=+(i<0),this._selectedMeshes.includes(e)||this._selectedMeshes.push(e),bo(e)&&this._applyPointCloudStyle(e,!0),this.uniforms.uSelMix.value=1,this.uniforms.uDim.value=+!!this.style.dimOthers}_unregisterTile(e,t){e.group.traverse(e=>{let t=e;if(e.isLineSegments&&t.userData?.isEdgeLines&&this._nativeEdgeLines.delete(e),bo(e)&&this._pointClouds.delete(e),t.userData?.tileFadeKey&&(this.animator.unregister(t.userData.tileFadeKey),t.userData.tileFadeKey=void 0),t.userData?.pickId!=null&&(this._pickables.delete(t.userData.pickId),this._releasePickId(t.userData.pickId),t.userData.pickId=void 0),t.isMesh){this._selectedMeshes.includes(t)&&(this._selectedMeshes=this._selectedMeshes.filter(e=>e!==t));let e=this._selection;if(e&&e.mesh===t){let n=e.smid,r=n==null?this._selectedMeshes.find(e=>e!==t&&e.parent&&e.parent.visible)??this._selectedMeshes.find(e=>e!==t&&e.parent):[...this._smidMeshes.get(n)??[]].find(e=>e!==t&&e.parent);r?(this._selection={...e,mesh:r},this._replaySelectionOnto(r)):this.select(null)}this._unindexMeshSmids(t),this._removeMeshHeight(t),this._featureStyleManager.disposeMesh(t),$(t)?.dispose?.()}fa(t.material)?t.material.dispose():t.material&&(Array.isArray(t.material)?t.material.forEach(e=>e?.dispose?.()):t.material.dispose?.()),t.geometry?.dispose?.()}),t.root.remove(e.group)}_allocPickId(){let e=this._freePickIds.pop();if(e!==void 0)return e;if(this._pickSeq>yo){for(let e=0;e<=yo;e++)if(!this._pickables.has(e))return e;throw Error(`[s3m] 可拾取网格超过 65535 个,2 字节 ID 编码不够用`)}return this._pickSeq++}_releasePickId(e){this._freePickIds.push(e)}setOpacity(e,t){this.setStyle({opacity:e},t)}setStyle(e={},t){Object.assign(this._styleTarget,e);let n=t?.duration??0,r=n>0||!!t?.spring,i=e;if(`edges`in e){let{edges:n,...a}=e;if(i=a,this.setEdges(!!n,r?t:void 0),Object.keys(i).length===0){this._requestRepaint();return}}let a=[],o={};for(let e of Object.keys(i))r&&this.animator.has(`style.${String(e)}`)?a.push(String(e)):o[e]=i[e];Object.keys(o).length>0&&(Object.assign(this.style,o),this._applyStyleEffects(o));for(let e of a)this.animator.to(`style.${e}`,this._animTargetOf(e,i),{...t,duration:n});this._requestRepaint()}getStyle(){return{...this._styleTarget,modeLabel:$r[this._styleTarget.mode]}}_animTargetOf(e,t){let n=t[e];return this._animDimOf(e)===1?Number(n):(this._colorScratch.set(String(n)),[this._colorScratch.r,this._colorScratch.g,this._colorScratch.b])}_animDimOf(e){return So.includes(e)?3:1}_registerAnimChannels(){for(let e of xo)this.animator.register(`style.${e}`,{dim:1,read:t=>{t[0]=Number(this.style[e]??0)},write:t=>{this.style[e]=t[0],this._onStyleChannelWrote(e)}});for(let e of So)this.animator.register(`style.${e}`,{dim:3,read:t=>{let n=this._uniformColorOf(e);t[0]=n.r,t[1]=n.g,t[2]=n.b},write:t=>{let n=this._uniformColorOf(e);n.setRGB(t[0],t[1],t[2]),this.style[e]=`#${n.getHexString()}`,this._onStyleChannelWrote(e)}});this.animator.register(`style.edgeFade`,{dim:1,read:e=>{e[0]=this.uniforms.uEdgeFade?.value??1},write:e=>{this.uniforms.uEdgeFade&&(this.uniforms.uEdgeFade.value=e[0]),this._syncEdgeStyle()}}),this.animator.register(`style.fade`,{dim:1,read:e=>{e[0]=this.uniforms.uFade?.value??1},write:e=>{this.uniforms.uFade&&(this.uniforms.uFade.value=e[0]),this._requestRepaint()}})}_onStyleChannelWrote(e){e===`opacity`?this._applyOpacity():(this._applyStyleUniforms(),(e===`edgeColor`||e===`edgeWidth`||e===`edgeOpacity`)&&this._refreshEdgeLines())}_uniformColorOf(e){let t=this.uniforms;switch(e){case`colorA`:return t.uColorA.value;case`colorB`:return t.uColorB.value;case`colorC`:return t.uColorC.value;case`selectColor`:return t.uSelColor.value;case`edgeColor`:return this.edgeMaterial.uniforms.uColor.value;default:return t.uColorA.value}}_applyStyleEffects(e){this._applyStyleUniforms(),(`opacity`in e||`depthWrite`in e)&&this._applyOpacity(),`mode`in e&&this._applyPointCloudStyles(),`shading`in e&&this._applyShading(),`edgeThreshold`in e&&this._edgesEnabled?(this._disposeEdges(),this.setEdges(!0)):(`edgeColor`in e||`edgeWidth`in e||`opacity`in e||`edgeOpacity`in e)&&this._refreshEdgeLines(),this._selection&&(`outline`in e||`outlineStyle`in e?this.select(this._selection,{silent:!0}):this._syncSelectionStyle())}_applyStyleUniforms(){let e=this.uniforms,t=this.style;e.uMode.value=t.mode,e.uColorA.value.set(t.colorA),e.uColorB.value.set(t.colorB),e.uColorC.value.set(t.colorC),e.uSelColor.value.set(t.selectColor),e.uFloorHeight.value=t.floorHeight;let n=t.selectMode??Q.OVERLAY;e.uSelMode&&(e.uSelMode.value=n===Q.REPLACE?0:n===Q.MULTIPLY?2:n===Q.GLOW_ONLY?3:1),e.uSelOpacity&&t.selectOpacity!=null&&(e.uSelOpacity.value=t.selectOpacity),e.uSelEmissive&&t.selectEmissive!=null&&(e.uSelEmissive.value=t.selectEmissive),e.uSelElevation&&t.selectElevation!=null&&(e.uSelElevation.value=t.selectElevation),e.uDimFactor&&t.dimFactor!=null&&(e.uDimFactor.value=t.dimFactor),e.uRoofThreshold&&t.roofThreshold!=null&&(e.uRoofThreshold.value=t.roofThreshold),e.uTexMix&&t.texMix!=null&&(e.uTexMix.value=t.texMix),e.uAmbientGain&&t.ambientGain!=null&&(e.uAmbientGain.value=t.ambientGain),this.outlineMaterial&&(this.outlineMaterial.uniforms.uElevation&&t.selectElevation!=null&&(this.outlineMaterial.uniforms.uElevation.value=t.selectElevation),t.outlineWidth!=null&&(this.outlineMaterial.uniforms.uWidth.value=t.outlineWidth),t.outlineColor==null?this.outlineMaterial.uniforms.uColor.value.set(t.selectColor):this.outlineMaterial.uniforms.uColor.value.set(t.outlineColor))}_applyOpacity(){let e=Math.min(1,Math.max(.05,this.style.opacity??1));this.uniforms.uOpacity&&(this.uniforms.uOpacity.value=e);let t=e<.999;if(t!==this._opacityTransparent){this._opacityTransparent=t;let e=this.style.depthWrite!==!1;for(let n of this._pickables.values()){if(bo(n.mesh))continue;let r=$(n.mesh);r&&(r.userData.uBatchTexActive?.value||(r.userData.uTileFade?.value??1)<1||(r.transparent=t,r.depthWrite=!t||e))}}for(let e of this._pointClouds)this._applyPointCloudStyle(e);this._syncEdgeStyle(),this._requestRepaint()}_applyPointCloudStyle(e,t=this._selectedMeshes.includes(e)){da(e,this.style,this.uniforms,t)}_applyPointCloudStyles(){for(let e of this._pointClouds)this._applyPointCloudStyle(e);this._requestRepaint()}_applyShading(){let e=this.style.shading!==`smooth`;for(let t of this._pickables.values()){let n=$(t.mesh);n&&n.flatShading!==e&&(n.flatShading=e,n.needsUpdate=!0)}this._requestRepaint()}_addMeshHeight(e){let t=e.geometry?.boundingBox;if(!t)return;this._boxScratch.copy(t).applyMatrix4(e.matrixWorld);let n=this._boxScratch.min.z,r=this._boxScratch.max.z;Number.isFinite(n)&&Number.isFinite(r)&&(this._meshHeight.set(e,{min:n,max:r}),n<this._heightMin&&(this._heightMin=n),r>this._heightMax&&(this._heightMax=r),this._pushHeightRange())}_removeMeshHeight(e){let t=this._meshHeight.get(e);t&&(this._meshHeight.delete(e),t.min===this._heightMin||t.max===this._heightMax?this._recomputeHeightRange():this._pushHeightRange())}_refreshAllHeights(){if(this._meshHeight.size===0)return;let e=[...this._meshHeight.keys()];this._meshHeight.clear(),this._heightMin=1/0,this._heightMax=-1/0;for(let t of e)this._addMeshHeight(t);this._pushHeightRange()}_recomputeHeightRange(){let e=1/0,t=-1/0;for(let n of this._meshHeight.values())n.min<e&&(e=n.min),n.max>t&&(t=n.max);this._heightMin=e,this._heightMax=t,this._pushHeightRange()}_pushHeightRange(){let e=this._heightMin,t=this._heightMax;(!Number.isFinite(e)||!Number.isFinite(t)||t<=e)&&(e=0,t=100),this.uniforms.uHeightMin.value=e,this.uniforms.uHeightMax.value=t}_indexMeshSmids(e){let t=e.userData.geoRef?.pickInfo;if(t)for(let n of Object.keys(t)){let t=Number(n);if(!Number.isFinite(t)||t<0)continue;let r=this._smidMeshes.get(t);r||this._smidMeshes.set(t,r=new Set),r.add(e)}}_unindexMeshSmids(e){let t=e.userData.geoRef?.pickInfo;if(t)for(let n of Object.keys(t)){let t=Number(n),r=this._smidMeshes.get(t);r&&(r.delete(e),r.size===0&&this._smidMeshes.delete(t))}}setEdges(e,t){let n=!!t&&((t.duration??0)>0||!!t.spring);this._edgesEnabled=e,this.style.edges=e,this._styleTarget.edges=e;for(let t of this.datasets.values())t.root.traverse(t=>{t.userData.isEdgeLines&&(t.visible=e,this._styleEdgeLine(t))});if(this._syncEdgeStyle(),!e){n?this.animator.to(`style.edgeFade`,0,{...t,onComplete:()=>{this._disposeEdges(),this._requestRepaint(),t?.onComplete?.()}}):(this._setEdgeFade(1),this._disposeEdges()),this._requestRepaint();return}let r=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e.userData;return!t.edges&&!t.nativeEdges&&!bo(e)}),i=0,a=()=>{let e=performance.now();for(;i<r.length&&performance.now()-e<8;)this._ensureEdges(r[i++]);i<r.length?setTimeout(a,0):this._requestRepaint()};a(),n?(this._setEdgeFade(0),this.animator.to(`style.edgeFade`,1,t)):this._setEdgeFade(1)}_setEdgeFade(e){this.uniforms.uEdgeFade&&(this.uniforms.uEdgeFade.value=e),this._syncEdgeStyle()}_disposeEdges(){for(let e of this._pickables.values())this._removeEdges(e.mesh)}async loadCreases(e){let n=await fetch(e);if(!n.ok)throw Error(`[s3m] 棱线缓存加载失败: ${n.status} ${e}`);let r=await n.arrayBuffer(),i=new Float32Array(r);if(i.length<6)return;let a=new t.BufferGeometry;a.setAttribute(`position`,new t.BufferAttribute(i,3));let o=this.style,s=new t.LineBasicMaterial({color:new t.Color(o.edgeColor),transparent:!0,opacity:Math.min(1,Math.max(0,o.edgeOpacity??.6))*Math.min(1,Math.max(.05,o.opacity??1)),depthWrite:!1}),c=new t.LineSegments(a,s);c.renderOrder=2,c.frustumCulled=!1,c.raycast=()=>{},this.clearCreases(),this._creaseLines=c,this.scene?.add(c),this._requestRepaint()}clearCreases(){this._creaseLines&&(this.scene?.remove(this._creaseLines),this._creaseLines.geometry.dispose(),this._creaseLines.material?.dispose?.(),this._creaseLines=null,this._requestRepaint())}_syncEdgeStyle(){let e=this.style,t=this.uniforms.uEdgeFade?.value??1,n=Math.min(1,Math.max(0,e.edgeOpacity??.6))*Math.min(1,Math.max(.05,e.opacity??1))*t,r=this.edgeMaterial.uniforms;if(r.uColor.value.set(e.edgeColor),r.uWidth.value=Math.max(.1,e.edgeWidth??1.5),r.uOpacity.value=n,this._creaseLines){let t=this._creaseLines.material;t.color.set(e.edgeColor),t.opacity=n}}_styleEdgeLine(e){let t=e.material;t&&t.color&&(t.color.set(this.style.edgeColor),t.opacity=(this.style.edgeOpacity??.6)*Math.min(1,Math.max(.05,this.style.opacity??1))*(this.uniforms.uEdgeFade?.value??1),t.transparent=!0,t.polygonOffset=!0,t.polygonOffsetFactor=-1,t.polygonOffsetUnits=-1,t.needsUpdate=!0)}_refreshEdgeLines(){this._syncEdgeStyle();for(let e of this._nativeEdgeLines)e.parent&&this._styleEdgeLine(e)}_datasetEdgesEnabled(e){let t=e.options?.enableEdges;return t===!0||t!==!1&&this._edgesEnabled}_shouldSkipAutoEdges(t,n){let r=`${t.skeletonName??``} ${n}`.toLowerCase();return e._EDGE_SKIP_KEYWORDS.some(e=>r.includes(e))}_ensureEdges(e){let n=e.userData;if(n.edges||n.nativeEdges||!e.geometry||this._shouldSkipAutoEdges(n,``))return;let r=e.geometry.getAttribute(`position`);if((e.geometry.index?.count??(r?r.count:0))>12e4)return;let i=co(e.geometry,.005),a=this.style.edgeThreshold??55,o=new t.EdgesGeometry(i,a);i.dispose();let s=o.getAttribute(`position`),c=s?s.array:null;if(o.dispose(),!c||c.length<6)return;let l=.005,u=no(e.geometry,l),d;if(u){let e=c.length/6;d=new Float32Array(e);for(let t=0;t<e;t++){let e=t*6;d[t]=u.get(ro(c[e],c[e+1],c[e+2],1/l))??-1}}let f=new t.Mesh(to(c,d),this._createEdgeMaterial(e));f.renderOrder=2,f.frustumCulled=!1,f.raycast=()=>{},f.userData.isThickEdge=!0,n.edges=f,e.add(f)}_createEdgeMaterial(e){let t=$(e),n=t?.userData?.uBatchTex?{uBatchTex:t.userData.uBatchTex,uBatchTex2:t.userData.uBatchTex2,uBatchMix:this.uniforms.uBatchMix,uBatchTexWidth:t.userData.uBatchTexWidth,uBatchTexActive:t.userData.uBatchTexActive,uPathTex:this.uniforms.uPathTex,uPathCount:this.uniforms.uPathCount,uPathTexActive:this.uniforms.uPathTexActive,uPathTime:this.uniforms.uPathTime}:void 0;return eo(this.lineShared,{},this._edgeStyleUniforms,n)}_createSelectionEdgeMaterial(e){let t=$(e),n=t?.userData?.uBatchTex?{uBatchTex:t.userData.uBatchTex,uBatchTex2:t.userData.uBatchTex2,uBatchMix:this.uniforms.uBatchMix,uBatchTexWidth:t.userData.uBatchTexWidth,uBatchTexActive:t.userData.uBatchTexActive,uPathTex:this.uniforms.uPathTex,uPathCount:this.uniforms.uPathCount,uPathTexActive:this.uniforms.uPathTexActive,uPathTime:this.uniforms.uPathTime}:void 0;return eo(this.lineShared,{},this._selEdgeStyleUniforms,n)}_removeEdges(e){let t=e.userData,n=t.edges;if(!n)return;e.remove(n),n.geometry?.dispose();let r=n.material;Array.isArray(r)?r.forEach(e=>e?.dispose?.()):r?.dispose?.(),t.edges=null}getRayAt(e,n){if(!this.camera||!this.canvas)return null;let r=this.canvas,i=r.clientWidth||r.width,a=r.clientHeight||r.height;if(!i||!a)return null;let o=e/i*2-1,s=-(n/a)*2+1,c=new t.Vector3(o,s,-1).unproject(this.camera),l=new t.Vector3(o,s,1).unproject(this.camera).clone().sub(c).normalize();return new t.Ray(c,l)}_intersectMeshAtRay(e,n,r){let i=new t.Raycaster;i.ray.copy(n);let a=i.intersectObject(e,!1);if(!a.length)return null;if(r!=null){let e=a.find(e=>e.instanceId===r);return e?e.point:a[0].point}return a[0].point}_buildPickResult(e,n,r,i){let a=n.mesh.userData,o=null,s=e.batchId,c=e.instanceIndex,l=a.geoRef,u=[];if(c!=null){let e=this._instanceFeature(n.mesh,l,c);if(!e)return null;o=e.smid,s=e.batchId}else{l=a.geoByBatchId?.get(e.batchId)??a.geoRef;let t=U(l,e.batchId);o=t.smid,u=t.segments}if(this._isFeatureHidden(o,s))return null;let d=null,f=0;if(c!=null)d=this._instanceBox(n.mesh,c),f=n.mesh.geometry.index?Math.round(n.mesh.geometry.index.count/3):0;else if(o!=null&&this._smidMeshes.has(o)){let e=this._smidMeshes.get(o),t=1/0,n=1/0,r=1/0,i=-1/0,a=-1/0,s=-1/0,c=0;for(let l of e){let e=l.userData,u=e.geoRef?.pickInfo,d=u?.[o]??u?.[String(o)],p=d?H(d):-1,m=d?.segments??(p>=0?U(e.geoRef,p).segments:[]),h=St(l.geometry,m);h&&(h.minX<t&&(t=h.minX),h.minY<n&&(n=h.minY),h.minZ<r&&(r=h.minZ),h.maxX>i&&(i=h.maxX),h.maxY>a&&(a=h.maxY),h.maxZ>s&&(s=h.maxZ),c+=h.count,f+=h.triangles)}c>0&&(d={minX:t,minY:n,minZ:r,maxX:i,maxY:a,maxZ:s,count:c,triangles:f})}if(!d&&(d=St(n.mesh.geometry,u),!d&&n.mesh.geometry)){n.mesh.geometry.boundingBox||n.mesh.geometry.computeBoundingBox();let e=n.mesh.geometry.boundingBox;e&&(d={minX:e.min.x,maxX:e.max.x,minY:e.min.y,maxY:e.max.y,minZ:e.min.z,maxZ:e.max.z,count:0,triangles:0})}let p=n.mesh.geometry,m=f>0?f:p.index?Math.round(p.index.count/3):0,h=Ct({smid:o,box:d,triangles:m,floorHeight:this.style.floorHeight}),g=null;if(d&&this.sceneAnchor){let e=new t.Vector3((d.minX+d.maxX)/2,(d.minY+d.maxY)/2,(d.minZ+d.maxZ)/2);e.applyMatrix4(n.mesh.matrixWorld);let r=this.sceneAnchor.meterInMercator;g=this._lngLatFromWorld(e.x*r+this.sceneAnchor.x,-e.y*r+this.sceneAnchor.y)}let _=r??null;!_&&i&&(_=this._intersectMeshAtRay(n.mesh,i,c));let v=null,y=null,b=null;if(_&&this.sceneAnchor){let e=o==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(o),n=e.translation,r=e.elevation,i=_.clone();if(e.rotation){let n=uo(e.rotation);if(n){let r=new t.Matrix3().set(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8]),a=e.pivot?new t.Vector3(e.pivot[0],e.pivot[1],e.pivot[2]):new t.Vector3(0,0,0);i.sub(a).applyMatrix3(r).add(a)}}n?i.add(new t.Vector3(n[0],n[1],n[2])):r&&(i.z+=r),v=[i.x,i.y,i.z];let a=this.sceneAnchor.meterInMercator;y=this._lngLatFromWorld(i.x*a+this.sceneAnchor.x,-i.y*a+this.sceneAnchor.y),b=i.z+(this.sceneAnchor.altitude??0)}else g&&d&&this.sceneAnchor&&(y=g,b=(d.minZ+d.maxZ)/2+(this.sceneAnchor.altitude??0));return{datasetId:n.datasetId,datasetName:this.datasets.get(n.datasetId)?.name??n.datasetId,objectId:e.objectId,batchId:s,instanceIndex:c,skeletonName:n.skeletonName,centerLngLat:g,point:v,lngLat:y,altitude:b,...h,mesh:n.mesh}}pick(e,t){if(!this.picker||!this.scene||!this.camera||!this.sceneAnchor)return null;let n=this.picker.pick(this.scene,this.camera,e,t);if(!n)return null;let r=this._pickables.get(n.objectId);if(!r)return null;let i=this.getRayAt(e,t);return this._buildPickResult(n,r,void 0,i??void 0)}pickPosition(e,n){if(!this.camera||!this.sceneAnchor)return null;let r=this.pick(e,n);if(r?.point&&r?.lngLat&&r.altitude!=null)return{lngLat:r.lngLat,altitude:r.altitude,point:r.point};let i=this.getRayAt(e,n);if(!i)return null;let a=new t.Plane(new t.Vector3(0,0,1),0),o=new t.Vector3,s=i.intersectPlane(a,o);if(s){let e=this.sceneAnchor.meterInMercator;return{lngLat:this._lngLatFromWorld(s.x*e+this.sceneAnchor.x,-s.y*e+this.sceneAnchor.y),altitude:s.z+(this.sceneAnchor.altitude??0),point:[s.x,s.y,s.z]}}return null}drillPick(e,n,r=10){if(!this.sceneAnchor||!this.camera)return[];let i=this.getRayAt(e,n);if(!i)return[];let a=new t.Raycaster;a.ray.copy(i);let o=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e;for(;t;){if(!t.visible)return!1;t=t.parent}return!0}),s=a.intersectObjects(o,!1);if(!s.length)return[];let c=[],l=new Set,u=new Set;for(let e of s){if(c.length>=r)break;let t=e.object,n=t.userData;if(n.pickId==null)continue;let i=this._pickables.get(n.pickId);if(!i)continue;let a=null,o=-1,s=e.instanceId;if(s!=null){let e=this._instanceFeature(t,n.geoRef,s);if(!e)continue;a=e.smid,o=e.batchId}else if(e.faceIndex!=null){let r=t.geometry.attributes.aBatchId;if(r){let i=t.geometry.index?t.geometry.index.getX(e.faceIndex*3):e.faceIndex*3;o=Math.round(r.getX(i)),a=U(n.geoByBatchId?.get(o)??n.geoRef,o).smid}}if(a!=null){if(l.has(a))continue;l.add(a)}else{let e=`${n.pickId}:${o}:${s??-1}`;if(u.has(e))continue;u.add(e)}if(this._isFeatureHidden(a,o))continue;let d={objectId:n.pickId,batchId:o,instanceIndex:s},f=this._buildPickResult(d,i,e.point);f&&c.push(f)}return c}getFeatureBounds(e){if(!this.sceneAnchor)return null;let n=1/0,r=-1/0,i=1/0,a=-1/0,o=!1;for(let s of this._pickables.values()){let c=s.mesh,l=c.userData,u=l.geoRef,d=u?.pickInfo;if(!d)continue;let f=null;if(c.isInstancedMesh){let t=l.instanceLookup;t||(t=xt(d),l.instanceLookup=t);for(let[n,r]of t)if(r.smid===e){f=this._instanceBox(c,n);break}}else{let t=d,n=t[e]??t[String(e)];if(n){let e=U(u,H(n));if(f=St(c.geometry,e.segments),!f&&c.geometry){c.geometry.boundingBox||c.geometry.computeBoundingBox();let e=c.geometry.boundingBox;e&&(f={minX:e.min.x,maxX:e.max.x,minY:e.min.y,maxY:e.max.y,minZ:e.min.z,maxZ:e.max.z,count:0,triangles:0})}}}if(f){o=!0;let s=[new t.Vector3(f.minX,f.minY,f.minZ),new t.Vector3(f.maxX,f.minY,f.minZ),new t.Vector3(f.minX,f.maxY,f.minZ),new t.Vector3(f.maxX,f.maxY,f.minZ),new t.Vector3(f.minX,f.minY,f.maxZ),new t.Vector3(f.maxX,f.minY,f.maxZ),new t.Vector3(f.minX,f.maxY,f.maxZ),new t.Vector3(f.maxX,f.maxY,f.maxZ)],l=e==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(e),u=l.translation,d=l.elevation,p=l.rotation?uo(l.rotation):null,m=null,h=null;p&&(m=new t.Matrix3().set(p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8]),h=l.pivot?new t.Vector3(l.pivot[0],l.pivot[1],l.pivot[2]):new t.Vector3(0,0,0));for(let e of s){m&&h&&e.sub(h).applyMatrix3(m).add(h),u?e.add(new t.Vector3(u[0],u[1],u[2])):d&&(e.z+=d),e.applyMatrix4(c.matrixWorld);let o=this.sceneAnchor.meterInMercator,[s,l]=this._lngLatFromWorld(e.x*o+this.sceneAnchor.x,-e.y*o+this.sceneAnchor.y);s<n&&(n=s),s>r&&(r=s),l<i&&(i=l),l>a&&(a=l)}}}return o?[[n,i],[r,a]]:null}_instanceFeature(e,t,n){let r=e.userData;return r.instanceLookup||(r.instanceLookup=xt(t?.pickInfo)),r.instanceLookup.get(n)??null}_instanceBox(e,n){let r=e;if(!r.isInstancedMesh)return null;let i=e.geometry;i.boundingBox||i.computeBoundingBox();let a=i.boundingBox;if(!a)return null;let o=new t.Matrix4;r.getMatrixAt(n,o);let s=a.clone().applyMatrix4(o);return{minX:s.min.x,minY:s.min.y,minZ:s.min.z,maxX:s.max.x,maxY:s.max.y,maxZ:s.max.z,count:i.getAttribute(`position`)?.count??0,triangles:i.index?Math.round(i.index.count/3):0}}select(e,{silent:t=!1}={}){if(this._selection){for(let e of this._selectedMeshes){if(bo(e)){this._applyPointCloudStyle(e,!1);continue}let t=$(e);t&&(t.userData.uSelBatch.value=-1,t.userData.uSelWhole.value=0)}this._selectedMeshes=[],this._clearSelectionDecoration(),this._selection=null}if(!e){this.uniforms.uSelMix.value=0,this.uniforms.uDim.value=0,this.outlineMaterial.uniforms.uSelBatch.value=-1,this.outlineMaterial.uniforms.uSelWhole.value=0,this.outlineMaterial.uniforms.uElevation.value=0,this._requestRepaint(),t||this.onPick(null);return}this._selection=e;let n=new Set;if(e.smid!=null){let t=this._smidMeshes.get(e.smid);if(t)for(let e of t)n.add(e)}n.add(e.mesh);for(let t of n){let n=$(t);if(!n)continue;let r=e.batchId;if(e.instanceIndex!=null&&t===e.mesh)r=e.batchId;else if(e.smid!=null){let n=t.userData.geoRef?.pickInfo,i=n?.[e.smid]??n?.[String(e.smid)],a=i?H(i):-1;r=a>=0?a:t===e.mesh?e.batchId:-1}n.userData.uSelBatch.value=r,n.userData.uSelWhole.value=+(r<0),this._selectedMeshes.push(t)}for(let e of this._selectedMeshes)bo(e)&&this._applyPointCloudStyle(e,!0);if(this.uniforms.uSelMix.value=1,this.uniforms.uDim.value=+!!this.style.dimOthers,this.style.outline){let t=[...n].filter(e=>!bo(e));t.length&&((this.style.outlineStyle??`edges`)===`edges`?this._addSelectionEdges(e,t):this._addSelectionHull(e,t))}this._requestRepaint()}_addSelectionEdges(e,n){this._syncSelectionStyle();for(let r of n){let n=r.userData,i=n.geoRef,a=[],o=-1;if(r===e.mesh&&e.instanceIndex!=null){a=[{vertexOffset:0,vertexCount:r.geometry.getAttribute(`position`)?.count??0}];let t=i?.pickInfo,n=t?.[e.smid??``]??t?.[String(e.smid)];o=n?H(n):-1}else if(e.smid!=null){let t=i?.pickInfo,n=t?.[e.smid]??t?.[String(e.smid)],r=n?H(n):-1;o=r,a=n?.segments??(r>=0?U(i,r).segments:[])}else r===e.mesh&&(a=U(n.geoByBatchId?.get(e.batchId)??i,e.batchId).segments,o=e.batchId);let s=oo(r.geometry,a);if(s&&s.length>0){let n=o>=0?new Float32Array(s.length/6).fill(o):void 0,i=new t.Mesh(to(s,n),this._createSelectionEdgeMaterial(r));i.renderOrder=4,i.frustumCulled=!1,i.raycast=()=>{},i.userData.isSelectionEdge=!0,r===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(i,e),r.add(i),this._selectionEdgeMeshes.push(i)}}this._selectionEdgeMeshes.length===0?this._addSelectionHull(e,n):this._selectionEdges=this._selectionEdgeMeshes[0]??null}_applyInstanceTransform(e,n){let r=n.mesh;if(n.instanceIndex==null||!r.isInstancedMesh)return;let i=new t.Matrix4;r.getMatrixAt(n.instanceIndex,i),i.decompose(e.position,e.quaternion,e.scale)}_addSelectionHull(e,n){let r=e.instanceIndex!=null;this.outlineMaterial.uniforms.uSelBatch.value=r?-1:e.batchId,this.outlineMaterial.uniforms.uSelWhole.value=r||e.batchId<0?1:0,this.outlineMaterial.uniforms.uElevation.value=r?this._selectionElevation(e):this.style.selectElevation??0;for(let r of n){let n=$(r);n?.userData?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=n.userData.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=n.userData.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=n.userData.uBatchTexActive.value);let i=new t.Mesh(r.geometry,this.outlineMaterial);i.renderOrder=3,i.frustumCulled=!1,i.raycast=()=>{},r===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(i,e),r.add(i),this._outlineMeshes.push(i)}this._outlineMesh=this._outlineMeshes[0]??null}_syncSelectionStyle(){let e=this.style,t=this.selectionEdgeMaterial.uniforms;t.uColor.value.set(e.outlineColor??e.selectColor),t.uWidth.value=Math.max(.1,e.outlineWidthPx??3),t.uOpacity.value=Math.min(1,Math.max(.05,e.opacity??1)),t.uElevation&&(t.uElevation.value=e.selectElevation??0);for(let e of this._outlineMeshes){let t=e.parent,n=t?$(t)?.userData:null;n?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=n.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=n.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=n.uBatchTexActive.value)}}_selectionElevation(e){let t=this.style.selectElevation??0;if(e.smid!=null){let n=this._featureStyleManager.getFeatureEffectiveOffset(e.smid);n.elevation&&(t+=n.elevation)}return t}_clearSelectionDecoration(){for(let e of this._outlineMeshes)e.parent?.remove(e);this._outlineMeshes=[],this._outlineMesh=null;for(let e of this._selectionEdgeMeshes)e.parent?.remove(e),e.geometry.dispose();this._selectionEdgeMeshes=[],this._selectionEdges=null}_updateLineResolution(e){let t=e.width||1,n=e.height||1,r=e.clientWidth||t;this.lineShared.uResolution.value.set(t,n),this.lineShared.uDpr.value=Math.max(1,t/r)}get lodRangeScale(){return this._lodRangeScale}setLodRangeScale(e,t){if(!(e<=0)){if(t){let n=this.datasets.get(t);n?.tileset&&(n.tileset.lodRangeScale=e)}else{this._lodRangeScale=e;for(let t of this.datasets.values())t.tileset&&(t.tileset.lodRangeScale=e)}this._requestRepaint()}}renderFrame(e){if(!this.renderer||!this.scene||!this.camera||!this.sceneAnchor||!this.canvas)return!1;let n=this.renderer.getContext();if(n&&typeof n.isContextLost==`function`&&n.isContextLost())return!1;let r=this.animator.tick();this.flushOverrides();let i=this.canvas,a=this.sceneAnchor.meterInMercator;this._enuMatrix.set(a,0,0,this.sceneAnchor.x,0,-a,0,this.sceneAnchor.y,0,0,a,this.sceneAnchor.z,0,0,0,1);let o=new t.Matrix4().fromArray(e.mvp);o.multiply(this._enuMatrix),this.camera.projectionMatrix.copy(o),this.camera.projectionMatrixInverse.copy(o).invert();let s=e.cameraEnu;this.camera.position.set(s[0],s[1],s[2]),this.camera.matrixWorld.setPosition(s[0],s[1],s[2]),this.camera.matrixWorldInverse.copy(this.camera.matrixWorld).invert(),this.groundManager.update(this.camera);let c=!1;for(let t of this.datasets.values()){if(!t.visible||!t.tileset)continue;let n=[s[0]-t.offset[0],s[1]-t.offset[1],s[2]-t.offset[2]];t.tileset.update(n,e.fovRad,e.canvasHeight)&&(c=!0)}this.style.mode===Z.DYNAMIC&&(this.uniforms.uTime.value+=.016*(this.style.speed??1)),this.gpuPathManager.updateUniforms(this.uniforms);let l=(this.uniforms.uPathTexActive?.value??0)>0;l&&!this._customPathTime&&this.uniforms.uPathTime&&(this.uniforms.uPathTime.value+=.016),this._updateLights(),this._updateLineResolution(i),this.renderer.setViewport(0,0,i.width,i.height),this.renderer.resetState(),this.renderer.render(this.scene,this.camera),this._frame++;let u=performance.now();return u-this._fps.last>500&&(this._fps.value=Math.round(this._frame*1e3/(u-this._fps.last)),this._frame=0,this._fps.last=u),r||this.style.mode===Z.DYNAMIC||l||this.stats.loading>0||c}get fps(){return this._fps.value}get stats(){let e={tiles:0,loading:0,failed:0,meshes:0,vertices:0,triangles:0,datasets:this.datasets.size};for(let t of this.datasets.values()){let n=t.tileset?.stats;n&&(e.tiles+=n.tiles,e.loading+=n.loading,e.failed+=n.failed,e.meshes+=n.meshes,e.vertices+=n.vertices,e.triangles+=n.triangles)}return e}getBounds(){let e=1/0,t=1/0,n=-1/0,r=-1/0;for(let i of this.datasets.values()){let a=ta(i.tileset?.config?.geoBounds);a&&(e=Math.min(e,a.left),n=Math.max(n,a.right),t=Math.min(t,a.bottom),r=Math.max(r,a.top))}return isFinite(e)?[[e,t],[n,r]]:null}dispose(){this.unmount()}};v(wo,`_EDGE_SKIP_KEYWORDS`,[`terrain`,`ground`,`vegetation`,`green`,`road`,`dem`,`绿地`,`道路`,`地面`,`地形`,`植被`,`铺装`]),Ji();var To=1e-4;function Eo(e,t){let n=e.elements;for(let e=0;e<16;e++){let r=Math.max(1,Math.abs(n[e]),Math.abs(t[e]));if(Math.abs(n[e]-t[e])>To*r)return!1}return!0}function Do(e){let t=e.elements,n=1;for(let e=0;e<16;e++){let r=Math.abs(t[e]);r>n&&(n=r)}let r=1e-6*n;return Math.abs(t[3])<r&&Math.abs(t[7])<r&&Math.abs(t[11])<r&&Math.abs(t[15]-1)<r}function Oo(e,t){return t>0&&Math.abs(e.elements[5]*Math.tan(t/2)-1)<.001}function ko(e){if(!e||typeof e!=`object`)return null;let t=e;return t.defaultProjectionData?.projectionMatrix??t.projectionMatrix??null}function Ao(e){let t={nearZ:null,farZ:null};if(!e||typeof e!=`object`)return t;let n=e,r=n.defaultProjectionData,i=e=>{let t=n[e];if(typeof t==`number`&&Number.isFinite(t))return t;let i=r?.[e];return typeof i==`number`&&Number.isFinite(i)?i:null};return{nearZ:i(`nearZ`),farZ:i(`farZ`)}}function jo(e,t){if(e&&typeof e==`object`){let t=e.fov;if(typeof t==`number`&&Number.isFinite(t)&&t>0)return t}return typeof t==`number`&&Number.isFinite(t)&&t>0?t:null}function Mo(e,n){let r=e.projectionMatrix;if(!r||r.length<16)return null;let i=new t.Matrix4().fromArray(Array.from(r)),a=new t.Matrix4().fromArray(Array.from(e.mvp));if(i.determinant()===0||!Oo(i,n.fov))return null;let o=i.clone().invert().multiply(a);if(!Eo(i.clone().multiply(o),Array.from(e.mvp))||!Do(o)||!Oo(i,n.fov))return null;let{distance:s,fov:c,aspect:l}=n;if(!(s>0)||!(c>0)||!(l>0))return null;let u=s*Math.tan(c/2),d=u*l,f=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,p=e.farZ!=null&&e.farZ>f?e.farZ:s*4+1e3;p>f||(p=f+1e3);let m=new t.OrthographicCamera(-d,d,u,-u,f,p);return m.updateProjectionMatrix(),{matrix:m.projectionMatrix.clone().multiply(o),view:o}}function No(e,n,r){let i=e.projectionMatrix;if(!i||i.length<16)return null;let a=new t.Matrix4().fromArray(Array.from(i)),o=new t.Matrix4().fromArray(Array.from(e.mvp));if(a.determinant()===0||!Oo(a,n.fov))return null;let s=a.clone().invert().multiply(o);if(!Eo(a.clone().multiply(s),Array.from(e.mvp))||!Do(s))return null;let c=Math.max(0,Math.min(1,r));if(c<=0)return{matrix:o,view:s};let{distance:l,fov:u,aspect:d}=n;if(!(l>0)||!(u>0)||!(d>0))return null;let f=l*Math.tan(u/2),p=f*d,m=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,h=e.farZ!=null&&e.farZ>m?e.farZ:l*4+1e3;h>m||(h=m+1e3);let g=new t.OrthographicCamera(-p,p,f,-f,m,h);if(g.updateProjectionMatrix(),c>=1)return{matrix:g.projectionMatrix.clone().multiply(s),view:s};let _=new t.Matrix4,v=a.elements,y=g.projectionMatrix.elements,b=_.elements;for(let e=0;e<16;e++)b[e]=(1-c)*v[e]+c*y[e];return{matrix:_.multiply(s),view:s}}var Po=u({Animator:()=>Xa,AttributeQuery:()=>At,BinaryReader:()=>b,DEFAULT_FLOOR_HEIGHT:()=>wt,DEFAULT_STYLE:()=>ti,DatasetManager:()=>lo,EARTH_RADIUS:()=>jt,EASING_NAMES:()=>ka,FeatureStyleManager:()=>_o,GPUPathManager:()=>Jr,GroundManager:()=>vo,Path:()=>Gr,Picker:()=>va,PixelFormat:()=>G,S3MFormatError:()=>yt,S3MTileset:()=>ia,S3MViewer:()=>wo,S3M_VERSION:()=>Ue,SAMPLES_PER_PATH:()=>256,SELECT_MODE:()=>Q,SELECT_MODE_LABELS:()=>ei,STYLE:()=>Z,STYLE_LABELS:()=>$r,TextureCompress:()=>K,VertexTag:()=>B,VertexTagV3:()=>We,buildAttributes:()=>Ct,buildBlendedMVP:()=>No,buildFeatureEdgeSegments:()=>oo,buildOrthoMVP:()=>Mo,buildThickLineGeometry:()=>to,buildTileObjects:()=>Gi,createLineSharedUniforms:()=>Za,createOutlineMaterial:()=>Qr,createSharedUniforms:()=>Xr,createStyledMaterial:()=>Zr,createTexture:()=>Br,createThickLineMaterial:()=>eo,cubicBezier:()=>Ba,default:()=>wo,dxtPixelFormatOf:()=>Cn,easing:()=>Aa,extractEulerAngles:()=>fo,extractFovRadians:()=>jo,extractNearFar:()=>Ao,extractProjectionMatrix:()=>ko,isS3M1Buffer:()=>Me,lngLatFromMercator:()=>Nt,lngLatFromWorld:()=>Ft,measureSegments:()=>St,mercatorFromLngLat:()=>Mt,parseS3M1:()=>He,parseS3MB:()=>bt,resolveFeature:()=>U,resolveRotationMatrix:()=>uo,resolveTextureKind:()=>Sn,setMaxAnisotropy:()=>Pr,steps:()=>Va,worldFromLngLat:()=>Pt});Tt(),mi(),Yr(),Wr(),En(),Kr(),Tt(),En(),Wr(),Kr(),Yr(),mi(),Ji();var Fo=globalThis;return Fo.THREE||(Fo.THREE=t),Fo.S3M=Po,e.Animator=Xa,e.AttributeQuery=At,e.BinaryReader=b,e.DEFAULT_FLOOR_HEIGHT=wt,e.DEFAULT_STYLE=ti,e.DatasetManager=lo,e.EARTH_RADIUS=jt,e.EASING_NAMES=ka,e.FeatureStyleManager=_o,e.GPUPathManager=Jr,e.GroundManager=vo,e.Path=Gr,e.Picker=va,e.PixelFormat=G,e.S3MFormatError=yt,e.S3MTileset=ia,e.S3MViewer=wo,e.default=wo,e.S3M_VERSION=Ue,e.SAMPLES_PER_PATH=qr,e.SELECT_MODE=Q,e.SELECT_MODE_LABELS=ei,e.STYLE=Z,e.STYLE_LABELS=$r,e.TextureCompress=K,e.VertexTag=B,e.VertexTagV3=We,e.buildAttributes=Ct,e.buildBlendedMVP=No,e.buildFeatureEdgeSegments=oo,e.buildOrthoMVP=Mo,e.buildThickLineGeometry=to,e.buildTileObjects=Gi,e.createLineSharedUniforms=Za,e.createOutlineMaterial=Qr,e.createSharedUniforms=Xr,e.createStyledMaterial=Zr,e.createTexture=Br,e.createThickLineMaterial=eo,e.cubicBezier=Ba,e.dxtPixelFormatOf=Cn,e.easing=Aa,e.extractEulerAngles=fo,e.extractFovRadians=jo,e.extractNearFar=Ao,e.extractProjectionMatrix=ko,e.isS3M1Buffer=Me,e.lngLatFromMercator=Nt,e.lngLatFromWorld=Ft,e.measureSegments=St,e.mercatorFromLngLat=Mt,e.parseS3M1=He,e.parseS3MB=bt,e.resolveFeature=U,e.resolveRotationMatrix=uo,e.resolveTextureKind=Sn,e.setMaxAnisotropy=Pr,e.steps=Va,e.worldFromLngLat=Pt,e})({},THREE);
986
+ `}),a=new t.Mesh(e,i);a.position.set(0,0,-.02),a.renderOrder=-1e3,a.name=`s3m-ground-depth`,a.visible=!1,this.group.add(a),this._depthMesh=a,this._depthMaterial=i,this._syncUniforms()}_applyMode(){this._mesh&&(this._mesh.visible=this.mode!==`none`),this._material&&(this._material.uniforms.uMode.value=this.mode===`excavate`?2:+(this.mode===`translucent`),this._material.depthWrite=this.mode===`excavate`),this._depthMesh&&(this._depthMesh.visible=this.occlude,this._depthMaterial&&(this._depthMaterial.uniforms.uPunchPit.value=+(this.mode===`excavate`)))}update(e){e&&this.group.position.set(e.position.x,e.position.y,this.groundHeight)}setGroundHeight(e){this.groundHeight=e,this.group.position.z=e}setMode(e){this.mode=e,this._occludeExplicit||(this.occlude=e===`excavate`),this._applyMode()}setOcclude(e){this.occlude=e,this._occludeExplicit=!0,this._applyMode()}setOpacity(e){this.opacity=Math.max(0,Math.min(1,e)),this._material&&(this._material.uniforms.uOpacity.value=this.opacity)}setColors(e,t){this.color.set(e),t&&this.gridColor.set(t),this._material&&(this._material.uniforms.uColor.value=this.color,this._material.uniforms.uGridColor.value=this.gridColor)}setExcavationBounds(e){this.excavationBounds=e,this._syncUniforms()}autoFitExcavation(e){let t=1/0,n=1/0,r=-1/0,i=-1/0,a=!1;for(let o of e){let e=o.tileset?.config,s=e?.rootTiles??e?.tiles;if(Array.isArray(s))for(let e of s){let s=e.boundingBox;if(!s)continue;let c=s.center??{x:0,y:0},l=s.xExtent?.x?Math.abs(s.xExtent.x):50,u=s.yExtent?.y?Math.abs(s.yExtent.y):50,d=c.x+o.offset[0]-l,f=c.x+o.offset[0]+l,p=c.y+o.offset[1]-u,m=c.y+o.offset[1]+u;d<t&&(t=d),f>r&&(r=f),p<n&&(n=p),m>i&&(i=m),a=!0}}a&&Number.isFinite(t)&&this.setExcavationBounds([t-5,n-5,r+5,i+5])}_syncUniforms(){let e=this.excavationBounds;if(this._material){let t=this._material.uniforms;e?(t.uHasExcavation.value=1,t.uExcavationMin.value.set(e[0],e[1]),t.uExcavationMax.value.set(e[2],e[3])):t.uHasExcavation.value=0}if(this._depthMaterial){let t=this._depthMaterial.uniforms;e?(t.uHasExcavation.value=1,t.uExcavationMin.value.set(e[0],e[1]),t.uExcavationMax.value.set(e[2],e[3])):t.uHasExcavation.value=0}}dispose(){this._geom?.dispose(),this._geom=null,this._material?.dispose(),this._material=null,this._depthMaterial?.dispose(),this._depthMaterial=null,this._mesh=null,this._depthMesh=null,this.group.clear()}};Wr(),mi(),Kr(),Yr(),Tt(),y();var bo=65534;function $(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function xo(e){return e.isPoints===!0}function So(e){let t=e??1;return t<0?0:t>1?1:t}var Co=.001,wo=[`opacity`,`floorHeight`,`selectOpacity`,`selectEmissive`,`selectElevation`,`dimFactor`,`texMix`,`roofThreshold`,`ambientGain`,`edgeWidth`,`edgeOpacity`,`outlineWidth`],To=[`colorA`,`colorB`,`colorC`,`selectColor`,`edgeColor`],Eo=[`translation`,`elevation`,`opacity`,`color`,`rotation`],Do=class e{get datasets(){return this._datasetManager.datasets}get sceneAnchor(){return this._datasetManager.sceneAnchor}set sceneAnchor(e){this._datasetManager.sceneAnchor=e}_requestRepaint(){this._onRequestRepaint()}triggerRepaint(){this._requestRepaint()}constructor(e={}){v(this,`options`,void 0),v(this,`pickable`,void 0),v(this,`onStats`,void 0),v(this,`onReady`,void 0),v(this,`onPick`,void 0),v(this,`onError`,void 0),v(this,`geo`,null),v(this,`canvas`,null),v(this,`renderer`,null),v(this,`scene`,null),v(this,`camera`,null),v(this,`picker`,null),v(this,`uniforms`,void 0),v(this,`style`,void 0),v(this,`_styleTarget`,void 0),v(this,`outlineMaterial`,void 0),v(this,`lineShared`,void 0),v(this,`edgeMaterial`,void 0),v(this,`selectionEdgeMaterial`,void 0),v(this,`_edgeStyleUniforms`,void 0),v(this,`_selEdgeStyleUniforms`,void 0),v(this,`groundManager`,void 0),v(this,`_datasetManager`,new uo),v(this,`_featureStyleManager`,void 0),v(this,`gpuPathManager`,new Jr),v(this,`_customPathTime`,!1),v(this,`_pickables`,new Map),v(this,`_pickSeq`,0),v(this,`_freePickIds`,[]),v(this,`_smidMeshes`,new Map),v(this,`_meshHeight`,new Map),v(this,`_heightMin`,1/0),v(this,`_heightMax`,-1/0),v(this,`_boxScratch`,new t.Box3),v(this,`_selection`,null),v(this,`_selectedMeshes`,[]),v(this,`_outlineMesh`,null),v(this,`_outlineMeshes`,[]),v(this,`_selectionEdges`,null),v(this,`_selectionEdgeMeshes`,[]),v(this,`_edgesEnabled`,!1),v(this,`_tileFadeSeq`,0),v(this,`_modeGen`,0),v(this,`_shadingPrewarmed`,!1),v(this,`_prewarmShadingEnabled`,!0),v(this,`_prewarming`,!1),v(this,`_pathSpecs`,new Map),v(this,`_pathScratch`,new Float32Array(3)),v(this,`_pathScratch2`,new Float32Array(3)),v(this,`_creaseLines`,null),v(this,`_nativeEdgeLines`,new Set),v(this,`_pointClouds`,new Set),v(this,`_opacityTransparent`,!1),v(this,`animator`,new Za),v(this,`attributeQuery`,null),v(this,`_enuMatrix`,new t.Matrix4),v(this,`_colorScratch`,new t.Color),v(this,`_needsRepaint`,!0),v(this,`_frame`,0),v(this,`_fps`,{value:0,last:0}),v(this,`_ambientLight`,void 0),v(this,`_hemiLight`,void 0),v(this,`_keyLight`,void 0),v(this,`_fillLight`,void 0),v(this,`_lightOptions`,{ambientIntensity:.4,ambientColor:16777215,hemisphereIntensity:.8,hemisphereColor:16777215,hemisphereGroundColor:11976907,keyLightIntensity:1,keyLightColor:16777215,fillLightIntensity:.35,fillLightColor:16777215,mode:`headlamp`,azimuth:150,altitude:50}),v(this,`_datasetQueue`,void 0),v(this,`_onRequestRepaint`,()=>{}),v(this,`_getBearing`,void 0),v(this,`_lodRangeScale`,1),this.options=e,this.pickable=e.pickable!==!1,this._lodRangeScale=e.lodRangeScale??1,e.light&&Object.assign(this._lightOptions,e.light),e.totalMaxTiles&&(this._datasetManager.totalMaxTiles=e.totalMaxTiles),this._onRequestRepaint=e.onRequestRepaint??(()=>{}),this._getBearing=e.getBearing,this.onStats=e.onStats??(()=>{}),this.onReady=e.onReady??(()=>{}),this.onPick=e.onPick??(()=>{}),this.onError=e.onError??(e=>console.warn(`[s3m]`,e)),this._prewarmShadingEnabled=e.prewarmShading!==!1,this.groundManager=new yo(e.ground),this.scene||(this.scene=new t.Scene,this.scene.add(this.groundManager.group),this._addLights()),this._featureStyleManager=new vo(()=>this.style.floorHeight,()=>this._requestRepaint(),()=>{this._selection&&this._syncSelectionStyle()},()=>this.getAllMeshes(),e=>this._applyOverridesToMesh(e),()=>this._opacityTransparent),this.uniforms=Xr(),Ir(Bt),this.style={...ti,...e.style??{}},this._styleTarget={...this.style},this._opacityTransparent=(this.style.opacity??1)<.999,this._applyStyleUniforms(),this._registerAnimChannels(),this.animator.onActive=()=>this._requestRepaint(),this.outlineMaterial=Qr(this.uniforms),this.lineShared=Qa(),this._edgeStyleUniforms={uColor:{value:new t.Color(this.style.edgeColor)},uWidth:{value:Math.max(.1,this.style.edgeWidth??1.5)},uOpacity:{value:.6}},this.edgeMaterial=to(this.lineShared,{},this._edgeStyleUniforms),this._selEdgeStyleUniforms={uColor:{value:new t.Color(this.style.outlineColor??this.style.selectColor)},uWidth:{value:Math.max(.1,this.style.outlineWidthPx??3)},uOpacity:{value:1},uElevation:{value:this.style.selectElevation??0}},this.selectionEdgeMaterial=to(this.lineShared,{},this._selEdgeStyleUniforms),this.setEdges(!!this.style.edges),this._applyOpacity(),this._fps.last=performance.now(),this._datasetQueue=this._normalizeDatasets(e),e.attributes&&(this.attributeQuery=new At(e.attributes))}_createRenderer(e,n){let r=new t.WebGLRenderer({canvas:e,context:n,antialias:!0});return r.autoClear=!1,r.setPixelRatio(1),r.toneMapping=this.options.toneMapping===void 0?t.NoToneMapping:this.options.toneMapping,r.toneMappingExposure=this.options.toneMappingExposure??1,r}_syncTextureCapabilities(e){let t=!!e.getExtension(`WEBGL_compressed_texture_s3tc`),n=!!e.getExtension(`WEBGL_compressed_texture_s3tc_srgb`);Fr(t&&n)}mount(e,n){this.canvas=e,this.renderer=this._createRenderer(e,n),Pr(this.renderer.capabilities.getMaxAnisotropy()),this._syncTextureCapabilities(n),this.scene=new t.Scene,this.scene.add(this.groundManager.group),this._addLights(),this.camera=new t.Camera,this.camera.matrixAutoUpdate=!1,this.picker=new ya(this.renderer),this._applyStyleUniforms();for(let e of this._datasetQueue)this.addDataset(e).catch(e=>this.onError(e));this._recomputeAnchors()}restoreContext(e){if(!this.canvas)console.warn(`[s3m] restoreContext 调用过早(尚未 mount),按首次挂载处理`);else{try{this.renderer?.dispose?.()}catch{}this.renderer=this._createRenderer(this.canvas,e),Pr(this.renderer.capabilities.getMaxAnisotropy()),this._syncTextureCapabilities(e),this.picker?.dispose(),this.picker=new ya(this.renderer),this._requestRepaint()}}unmount(){for(let e of[...this.datasets.keys()])this.removeDataset(e);this.clearCreases(),this.groundManager.dispose(),this.picker?.dispose(),this.picker=null,this.outlineMaterial.dispose(),this.edgeMaterial.dispose(),this.selectionEdgeMaterial.dispose(),this.scene?.clear(),this._selectedMeshes=[],this._outlineMeshes=[],this._selectionEdgeMeshes=[],this._outlineMesh=null,this._selectionEdges=null,this._smidMeshes.clear(),this._meshHeight.clear(),this.animator.clear(),this.animator.unregisterPrefix(`tile.`),this.animator.unregisterPrefix(`feature.`),this._pathSpecs.clear(),this._heightMin=1/0,this._heightMax=-1/0,this.renderer?.dispose?.(),this.renderer=null,this.canvas=null}_createLights(){this._ambientLight=new t.AmbientLight(this._lightOptions.ambientColor,this._lightOptions.ambientIntensity),this._hemiLight=new t.HemisphereLight(this._lightOptions.hemisphereColor,this._lightOptions.hemisphereGroundColor,this._lightOptions.hemisphereIntensity),this._keyLight=new t.DirectionalLight(this._lightOptions.keyLightColor,this._lightOptions.keyLightIntensity),this._fillLight=new t.DirectionalLight(this._lightOptions.fillLightColor,this._lightOptions.fillLightIntensity),this._updateLights()}_addLights(){this.scene&&(this._ambientLight||this._createLights(),this.scene.add(this._ambientLight,this._hemiLight,this._keyLight,this._fillLight))}_applyLightOptions(){this._ambientLight&&(this._ambientLight.intensity=this._lightOptions.ambientIntensity,this._ambientLight.color.set(this._lightOptions.ambientColor)),this._hemiLight&&(this._hemiLight.intensity=this._lightOptions.hemisphereIntensity,this._hemiLight.color.set(this._lightOptions.hemisphereColor),this._hemiLight.groundColor.set(this._lightOptions.hemisphereGroundColor)),this._keyLight&&(this._keyLight.intensity=this._lightOptions.keyLightIntensity,this._keyLight.color.set(this._lightOptions.keyLightColor)),this._fillLight&&(this._fillLight.intensity=this._lightOptions.fillLightIntensity,this._fillLight.color.set(this._lightOptions.fillLightColor))}setLight(e){let t={...e};t.mainColor!==void 0&&t.keyLightColor===void 0&&(t.keyLightColor=t.mainColor),t.mainIntensity!==void 0&&t.keyLightIntensity===void 0&&(t.keyLightIntensity=t.mainIntensity),Object.assign(this._lightOptions,t),this._applyLightOptions(),this._updateLights(),this._needsRepaint=!0,this.triggerRepaint()}getLight(){return{...this._lightOptions}}setToneMapping(e,t=1){this.options.toneMapping=e,this.options.toneMappingExposure=t,this.renderer&&(this.renderer.toneMapping=e,this.renderer.toneMappingExposure=t,this._needsRepaint=!0,this.triggerRepaint())}getToneMapping(){return{toneMapping:this.renderer?this.renderer.toneMapping:this.options.toneMapping??t.NoToneMapping,toneMappingExposure:this.renderer?this.renderer.toneMappingExposure:this.options.toneMappingExposure??1}}_updateLights(){if(!this._keyLight||!this._fillLight)return;let e=this._lightOptions.mode===`fixed`?0:(this._getBearing?.()??0)*Math.PI/180,t=(t,n,r)=>{if(!t)return;let i=e+n*Math.PI/180,a=r*Math.PI/180,o=Math.cos(a);t.position.set(Math.sin(i)*o,Math.cos(i)*o,Math.sin(a)).multiplyScalar(1e3)};t(this._keyLight,this._lightOptions.azimuth,this._lightOptions.altitude),t(this._fillLight,this._lightOptions.azimuth+65,Math.max(10,this._lightOptions.altitude-20))}_normalizeDatasets(e){return Array.isArray(e.datasets)?e.datasets.filter(e=>!!e?.configUrl):e.configUrl?[{id:`default`,name:`默认数据集`,configUrl:e.configUrl,useWorker:e.useWorker}]:[]}async addDataset(e){if(!this.scene)throw Error(`[s3m] 图层尚未 addLayer,不能添加数据集`);return await this._datasetManager.addDataset(e,this.scene,this.geo,this.uniforms,this._lodRangeScale,this.options.buildTile,this.options.maxTiles??64,this.options.maxConcurrent??4,{onTile:(e,t)=>{this._registerTile(e,t),this.onStats(this.stats),this._needsRepaint=!0,this._requestRepaint()},onTileRemoved:(e,t)=>{this._unregisterTile(e,t),this.onStats(this.stats),this._needsRepaint=!0,this._requestRepaint()},onStats:()=>{this.onStats(this.stats),this._requestRepaint()},onError:e=>{this.onError(e),this.onStats(this.stats)},onReady:e=>{this.onReady(e),this._refreshAllHeights(),this.groundManager.excavationBounds||this.groundManager.autoFitExcavation(this.datasets.values())},triggerRepaint:()=>{this._requestRepaint()}})}_lngLatFromWorld(e,t){return Ft(this.geo,e,t)}recomputeAnchors(){this._datasetManager.recomputeAnchors(this.geo),this._refreshAllHeights(),this._requestRepaint()}_recomputeAnchors(){this.recomputeAnchors()}getDatasetHeight(e){return this._datasetManager.getDatasetHeight(e)}setDatasetHeight(e,t){let n,r;typeof e==`number`?(n=this.datasets.keys().next().value??``,r=e):(n=e,r=t??0),this._datasetManager.setDatasetHeight(n,r,this.geo),this._syncGroundHeight(),this._refreshAllHeights(),this._requestRepaint()}_syncGroundHeight(){if(!this.groundManager.trackHeight)return;let e=this.datasets.keys().next().value;if(!e)return;let t=this._datasetManager.getDatasetHeight(e);this.groundManager.setGroundHeight(t)}setDatasetAlign(e,t){let n,r;t===void 0&&(e===`origin`||e===`bottom`||e===`top`||e===`center`)?(n=this.datasets.keys().next().value??``,r=e):(n=e,r=t??`origin`),this._datasetManager.setDatasetAlign(n,r,this.geo),this._refreshAllHeights(),this._requestRepaint()}_computeAlignOffset(e,t){return this._datasetManager.computeAlignOffset(e,t)}computeAlignOffset(e,t){return this._datasetManager.computeAlignOffset(e,t)}setFeatureStyle(e,t){this._featureStyleManager.setFeatureStyle(e,t,this._meshesOf([e]))}setFeaturesStyle(e,t){this._featureStyleManager.setFeaturesStyle(e,t,this._meshesOf(e))}moveFeature(e,t,n){let r=this._ensureFeatureChannel(e,`translation`);this.animator.to(r,t,n)}moveFeatureBy(e,t,n){let r=this._featureStyleManager.getFeatureStyle(e)?.translation??[0,0,0];this.moveFeature(e,[r[0]+t[0],r[1]+t[1],r[2]+t[2]],n)}rotateFeature(e,t,n,r){let i=this._featureStyleManager.getFeatureStyle(e)??{};n&&this._featureStyleManager.setFeatureStyle(e,{...i,pivot:n},this._meshesOf([e]));let a=po(t),o=this._ensureFeatureChannel(e,`rotation`);this.animator.to(o,a,r)}rotateFeatureBy(e,t,n,r){let i=po(this._featureStyleManager.getFeatureStyle(e)?.rotation),a=typeof t==`number`?[0,0,t]:t;this.rotateFeature(e,[i[0]+a[0],i[1]+a[1],i[2]+a[2]],n,r)}crossFadeStyles(e,t){let n=e instanceof Map?e:new Map(Object.entries(e).map(([e,t])=>[Number(e),t])),r=this.getAllMeshes();this._featureStyleManager.prepareCrossFade(n,r);let i=`batch.mix`;this.animator.has(i)||this.animator.register(i,{dim:1,read:e=>{e[0]=this.uniforms.uBatchMix?.value??0},write:e=>{this.uniforms.uBatchMix&&(this.uniforms.uBatchMix.value=e[0]),this.triggerRepaint()}}),(t?.duration??0)>0||t?.spring?(this.uniforms.uBatchMix&&(this.uniforms.uBatchMix.value=0),this.animator.to(i,1,{...t,onComplete:()=>{this.uniforms.uBatchMix&&(this.uniforms.uBatchMix.value=0),this._featureStyleManager.commitCrossFade(n,r),this.triggerRepaint(),t?.onComplete?.()}})):(this.animator.has(i)&&this.animator.cancel(i),this.uniforms.uBatchMix&&(this.uniforms.uBatchMix.value=0),this._featureStyleManager.commitCrossFade(n,r),this.triggerRepaint(),t?.onComplete?.())}followPath(e,t,n={}){let r=t instanceof Gr?t:new Gr(t,{closed:n.closed});if(r.length<=0)return;let i=n.offset??[0,0,0],a=n.duration??(n.speed&&n.speed>0?r.length/n.speed*1e3:2e3),o=`feature.${e}.path`;this._pathSpecs.set(o,{path:r,offset:i}),this.animator.has(o)||this.animator.register(o,{dim:1,read:e=>{e[0]=0},write:t=>{let n=this._pathSpecs.get(o);if(!n)return;n.path.sampleAt(t[0],this._pathScratch);let r=this._meshesOf([e]),i=this._featureStyleManager.getFeatureStyle(e)??{};this._featureStyleManager.setFeatureStyle(e,{...i,translation:[n.offset[0]+this._pathScratch[0],n.offset[1]+this._pathScratch[1],n.offset[2]+this._pathScratch[2]]},r);for(let e of r)e.frustumCulled=!1}});let s=()=>{this.animator.to(o,1,{duration:a,easing:n.easing??`linear`,onComplete:()=>{n.loop?s():n.onComplete?.()}})};s()}stopPath(e){let t=`feature.${e}.path`;this.animator.cancel(t),this.animator.unregister(t),this._pathSpecs.delete(t)}_gpuPathPoseAt(e){let t=this._featureStyleManager.getFeatureStyle(e)?.gpuPath;if(!t)return null;let n=this.gpuPathManager.getPath(t.pathId);if(!n||n.length<=0)return null;let r=this.uniforms.uPathTime?.value??0,i=(t.phase??0)+r*(t.speed??0),a=t.loop;a===`clamp`||a===!1?i=Math.min(1,Math.max(0,i)):a===`pingpong`?(i%=2,i<0&&(i+=2),i=i>1?2-i:i):i-=Math.floor(i),n.sampleAt(i,this._pathScratch);let o=[this._pathScratch[0],this._pathScratch[1],this._pathScratch[2]],s=0;if(t.autoHeading!==!1){let e=.001;n.sampleAt(Math.min(1,i+e),this._pathScratch2);let t=this._pathScratch2[0]-o[0],r=this._pathScratch2[1]-o[1];t*t+r*r<1e-8&&(n.sampleAt(Math.max(0,i-e),this._pathScratch2),t=o[0]-this._pathScratch2[0],r=o[1]-this._pathScratch2[1]),t*t+r*r>=1e-8&&(s=Math.atan2(r,t))}return{pos:o,yaw:s}}registerGPUPath(e,t={}){let n=this.gpuPathManager.registerPath(e,t);return this.gpuPathManager.updateUniforms(this.uniforms),n}unregisterGPUPath(e){let t=this.gpuPathManager.unregisterPath(e);return this.gpuPathManager.updateUniforms(this.uniforms),t}getGPUPathManager(){return this.gpuPathManager}bindGPUPath(e,t,n={}){let r;r=typeof t==`number`?t:this.registerGPUPath(t);let i=this._meshesOf([e]);this._featureStyleManager.bindGPUPath(e,r,n,i);for(let e of i)e.frustumCulled=!1;return this.gpuPathManager.updateUniforms(this.uniforms),r}unbindGPUPath(e){let t=this._meshesOf([e]);this._featureStyleManager.unbindGPUPath(e,t),this.gpuPathManager.updateUniforms(this.uniforms)}setGPUPathProgress(e,t){let n=this._meshesOf([e]);this._featureStyleManager.setGPUPathProgress(e,t,n);for(let e of n)e.frustumCulled=!1}setGPUPathTime(e,t=!1){this.uniforms.uPathTime&&(this.uniforms.uPathTime.value=e),this._customPathTime=!t}getGPUPathTime(){return this.uniforms.uPathTime?.value??0}animateFeature(e,t,n){if(t.translation&&this.moveFeature(e,t.translation,n),t.rotation!=null&&this.rotateFeature(e,t.rotation,t.pivot,n),t.elevation!=null&&this.animator.to(this._ensureFeatureChannel(e,`elevation`),t.elevation,n),t.opacity!=null&&this.animator.to(this._ensureFeatureChannel(e,`opacity`),t.opacity,n),t.color&&(this._colorScratch.set(t.color),this.animator.to(this._ensureFeatureChannel(e,`color`),[this._colorScratch.r,this._colorScratch.g,this._colorScratch.b],n)),t.hidden!=null){let n=this._featureStyleManager.getFeatureStyle(e)??{};this.setFeatureStyle(e,{...n,hidden:t.hidden})}}animateFeatures(e,t,n){let r=n?.stagger??0;if(r<=0){for(let r of e)this.animateFeature(r,t,n);return}let i=n?.delay??0;for(let a=0;a<e.length;a++)this.animateFeature(e[a],t,{...n,delay:i+a*r})}setMode(e,t={}){let n=Math.max(0,t.duration??300),r=Math.min(1,Math.max(.05,t.dim??.35));if(this.style.mode===e)return Promise.resolve();if(n<=0)return this.setStyle({mode:e}),Promise.resolve();let i=++this._modeGen;return new Promise(t=>{this.animator.to(`style.fade`,r,{duration:n,easing:`easeInOutQuad`,onComplete:()=>{i===this._modeGen?(this.setStyle({mode:e}),this.animator.to(`style.fade`,1,{duration:n,easing:`easeInOutQuad`,onComplete:t})):t()}})})}_ensureFeatureChannel(e,t){let n=`feature.${e}.${t}`;if(this.animator.has(n))return n;let r=t===`translation`||t===`color`||t===`rotation`?{dim:3,read:n=>{if(t===`translation`){let t=this._featureStyleManager.getFeatureStyle(e)?.translation;n[0]=t?.[0]??0,n[1]=t?.[1]??0,n[2]=t?.[2]??0}else if(t===`rotation`){let t=this._featureStyleManager.getFeatureStyle(e)?.rotation,r=po(t);n[0]=r[0],n[1]=r[1],n[2]=r[2]}else{let t=this._featureStyleManager.getFeatureStyle(e)?.color??this.style.colorA;this._colorScratch.set(t),n[0]=this._colorScratch.r,n[1]=this._colorScratch.g,n[2]=this._colorScratch.b}},write:n=>{let r=this._meshesOf([e]),i=this._featureStyleManager.getFeatureStyle(e)??{};if(t===`translation`){this._featureStyleManager.setFeatureStyle(e,{...i,translation:[n[0],n[1],n[2]]},r);let t=Math.abs(n[0])>1e-6||Math.abs(n[1])>1e-6||Math.abs(n[2])>1e-6,a=po(i.rotation),o=Math.abs(a[0])>1e-6||Math.abs(a[1])>1e-6||Math.abs(a[2])>1e-6;for(let e of r)e.frustumCulled=!(t||o)}else if(t===`rotation`){this._featureStyleManager.setFeatureStyle(e,{...i,rotation:[n[0],n[1],n[2]]},r);let t=Math.abs(n[0])>1e-6||Math.abs(n[1])>1e-6||Math.abs(n[2])>1e-6,a=i.translation??[0,0,0],o=Math.abs(a[0])>1e-6||Math.abs(a[1])>1e-6||Math.abs(a[2])>1e-6;for(let e of r)e.frustumCulled=!(t||o)}else{let t=this._colorScratch.setRGB(n[0],n[1],n[2]);this._featureStyleManager.setFeatureStyle(e,{...i,color:`#${t.getHexString()}`},r)}}}:{dim:1,read:n=>{let r=this._featureStyleManager.getFeatureStyle(e);n[0]=(t===`elevation`?r?.elevation:r?.opacity)??+(t===`opacity`)},write:n=>{let r=this._featureStyleManager.getFeatureStyle(e)??{},i=t===`elevation`?{...r,elevation:n[0]}:{...r,opacity:n[0]};this._featureStyleManager.setFeatureStyle(e,i,this._meshesOf([e]))}};return this.animator.register(n,r),n}_releaseFeatureChannels(e){for(let t of Eo)this.animator.unregister(`feature.${e}.${t}`);let t=`feature.${e}.path`;this.animator.unregister(t),this._pathSpecs.delete(t)}getFeatureStyle(e){return this._featureStyleManager.getFeatureStyle(e)}getFeatureStyles(){return this._featureStyleManager.getFeatureStyles()}removeFeatureStyle(e){this._releaseFeatureChannels(e),this._featureStyleManager.removeFeatureStyle(e,this._meshesOf([e]))}clearFeatureStyles(){for(let e of this._featureStyleManager.getFeatureStyles().keys())this._releaseFeatureChannels(e);this._featureStyleManager.clearFeatureStyles()}setAttributeSource(e){this.attributeQuery=e?new At(e):null}getLoadedSmids(){return[...this._smidMeshes.keys()]}auditBatches(){let e=this._featureStyleManager.auditBatches(this._pickables.values());return e.smids=this._smidMeshes.size,e}getThematicField(){return this._featureStyleManager.thematicField}setThematicColors(e,t=`custom`){this._featureStyleManager.setThematicColors(e,t)}clearThematic(){this._featureStyleManager.clearThematicColors()}getFilterField(){return this._featureStyleManager.fieldFilter?.field??null}filterByField(e){return this._featureStyleManager.filterByField(e,this.attributeQuery,this.getLoadedSmids())}clearFieldFilter(){this._featureStyleManager.clearFieldFilter()}getElevationField(){return this._featureStyleManager.elevationField}elevateByField(e){return this._featureStyleManager.elevateByField(e,this.attributeQuery,this.getLoadedSmids())}setThematicElevation(e,t=`custom`){this._featureStyleManager.setThematicElevation(e,t)}clearThematicElevation(){this._featureStyleManager.clearThematicElevation()}colorByField(e){return this._featureStyleManager.colorByField(e,this.attributeQuery,this.getLoadedSmids())}setFilter(e){this._featureStyleManager.setFilter(e,this.uniforms)}getFilter(){return this._featureStyleManager.filter}clearFilter(){this._featureStyleManager.clearFilter(this.uniforms)}setGroundMode(e){this.groundManager.setMode(e),this._requestRepaint()}setGroundOpacity(e){this.groundManager.setOpacity(e),this._requestRepaint()}setExcavationBounds(e){this.groundManager.setExcavationBounds(e),this._requestRepaint()}setGroundOcclude(e){this.groundManager.setOcclude(e),this._requestRepaint()}_isFeatureHidden(e,t){if(e==null)return!1;let n=this._featureStyleManager.fieldFilter;if(n){let t=n.matched.has(e);if(n.mode===`keep`?!t:t)return!0}let r=this._featureStyleManager.filter;return!!(r&&(r.include&&r.include.length>0&&!r.include.includes(e)||r.exclude&&r.exclude.length>0&&r.exclude.includes(e))||this._featureStyleManager.featureStyles.get(e)?.hidden)}getAllMeshes(){let e=[];for(let t of this._pickables.values())e.push(t.mesh);return e}_meshesOf(e){let t=new Set;for(let n of e){let e=this._smidMeshes.get(n);if(e)for(let n of e)t.add(n)}return t}_markOverridesDirty(e=`all`){e===`all`?this._featureStyleManager.markOverridesDirty(void 0,this.getAllMeshes()):this._featureStyleManager.markOverridesDirty(e)}flushOverrides(){this._featureStyleManager.flushOverrides()}_applyOverridesToMesh(e){this._featureStyleManager.applyOverridesToMesh(e)}removeDataset(e){if(this.datasets.get(e)){this._selection?.datasetId===e&&this.select(null),this._datasetManager.removeDataset(e,this.scene,this.geo,e=>{e.root.traverse(e=>{let t=e,n=t.userData;n.pickId!=null&&(this._pickables.delete(n.pickId),this._releasePickId(n.pickId),n.pickId=void 0),this._unindexMeshSmids(t),this._removeMeshHeight(t),t.geometry?.dispose?.();let r=$(t);r&&r.dispose(),fa(t.material)&&t.material.dispose(),this._featureStyleManager.disposeMesh(t)})});for(let[t,n]of this._pickables)n.datasetId===e&&this._pickables.delete(t);this.onStats(this.stats),this._requestRepaint()}}clearDatasets(){for(let e of[...this.datasets.keys()])this.removeDataset(e)}setDatasetVisible(e,t){this._datasetManager.setDatasetVisible(e,t),!t&&this._selection?.datasetId===e&&this.select(null),this._requestRepaint()}_registerTile(e,t){t.root.add(e.group),e.group.updateMatrixWorld(!0);let n=e.group.userData.hasNativeEdges===!0;for(let r of e.group.children){if(r.isLineSegments&&r.userData.isEdgeLines){r.visible=this._edgesEnabled,this._nativeEdgeLines.add(r),this._styleEdgeLine(r);continue}let i=xo(r),a=r;if(!a.isMesh&&!i)continue;i&&this._pointClouds.add(r);let o=a.userData;if(o.pickId=this._allocPickId(),o.datasetId=t.id,o.nativeEdges=n,this._pickables.set(o.pickId,{datasetId:t.id,mesh:a,tile:e.tile,skeletonName:o.skeletonName??``}),this._indexMeshSmids(a),this._addMeshHeight(a),!n&&!i&&this._datasetEdgesEnabled(t)&&!this._shouldSkipAutoEdges(o,t.name)&&this._ensureEdges(a),i)this._applyPointCloudStyle(r);else{let e=$(a);if(e){e.transparent=So(this.style.opacity)<.999;let t=this.style.depthWrite!==!1;e.depthWrite=e.transparent?t:this.style.depthWrite!==!1,e.flatShading=this.style.shading!==`smooth`,e.needsUpdate=!0,this._featureStyleManager.applyOverridesToMesh(a),this._startTileFade(a,e)}}this._replaySelectionOnto(a)}}_startTileFade(e,t){let n=this.style.fadeIn??0;if(n<=0)return;let r=t.userData.uTileFade;if(!r)return;r.value=0,t.transparent=!0,t.depthWrite=!0;let i=`tile.${this._tileFadeSeq++}.fade`;e.userData.tileFadeKey=i,this.animator.register(i,{dim:1,read:e=>{e[0]=r.value},write:e=>{r.value=e[0]}}),this.animator.to(i,1,{duration:n,easing:`easeOutQuad`,onComplete:()=>{r.value=1,e.userData.tileFadeKey=void 0,this.animator.unregister(i),this._featureStyleManager.applyOverridesToMesh(e),t.depthWrite=this.style.depthWrite!==!1,this._requestRepaint()}})}_isMeshCoveringSelection(e,n){if(!n.point)return!1;let r=e.geometry;if(!r||(r.boundingBox||r.computeBoundingBox(),!r.boundingBox))return!1;let i=new t.Vector3(n.point[0],n.point[1],n.point[2]);e.updateWorldMatrix(!0,!1);let a=e.matrixWorld.clone().invert(),o=i.applyMatrix4(a);return r.boundingBox.clone().expandByScalar(.5).containsPoint(o)}_replaySelectionOnto(e){let t=this._selection;if(!t)return;let n=$(e);if(!n)return;let r=e.userData,i=-1;if(t.smid!=null){let e=r.geoRef?.pickInfo,n=e?.[t.smid]??e?.[String(t.smid)];i=n?H(n):-1}if(e===t.mesh&&(i=t.batchId),i<0&&e!==t.mesh){if(t.smid==null&&r.datasetId===t.datasetId&&this._isMeshCoveringSelection(e,t))i=-1;else return}n.userData.uSelBatch.value=i,n.userData.uSelWhole.value=+(i<0),this._selectedMeshes.includes(e)||this._selectedMeshes.push(e),xo(e)&&this._applyPointCloudStyle(e,!0),this.uniforms.uSelMix.value=1,this.uniforms.uDim.value=+!!this.style.dimOthers}_unregisterTile(e,t){e.group.traverse(e=>{let t=e;if(e.isLineSegments&&t.userData?.isEdgeLines&&this._nativeEdgeLines.delete(e),xo(e)&&this._pointClouds.delete(e),t.userData?.tileFadeKey&&(this.animator.unregister(t.userData.tileFadeKey),t.userData.tileFadeKey=void 0),t.userData?.pickId!=null&&(this._pickables.delete(t.userData.pickId),this._releasePickId(t.userData.pickId),t.userData.pickId=void 0),t.isMesh){this._selectedMeshes.includes(t)&&(this._selectedMeshes=this._selectedMeshes.filter(e=>e!==t));let e=this._selection;if(e&&e.mesh===t){let n=e.smid,r=n==null?this._selectedMeshes.find(e=>e!==t&&e.parent&&e.parent.visible)??this._selectedMeshes.find(e=>e!==t&&e.parent):[...this._smidMeshes.get(n)??[]].find(e=>e!==t&&e.parent);r?(this._selection={...e,mesh:r},this._replaySelectionOnto(r)):this.select(null)}this._unindexMeshSmids(t),this._removeMeshHeight(t),this._featureStyleManager.disposeMesh(t),$(t)?.dispose?.()}fa(t.material)?t.material.dispose():t.material&&(Array.isArray(t.material)?t.material.forEach(e=>e?.dispose?.()):t.material.dispose?.()),t.geometry?.dispose?.()}),t.root.remove(e.group)}_allocPickId(){let e=this._freePickIds.pop();if(e!==void 0)return e;if(this._pickSeq>bo){for(let e=0;e<=bo;e++)if(!this._pickables.has(e))return e;throw Error(`[s3m] 可拾取网格超过 65535 个,2 字节 ID 编码不够用`)}return this._pickSeq++}_releasePickId(e){this._freePickIds.push(e)}setOpacity(e,t){this.setStyle({opacity:e},t)}setStyle(e={},t){Object.assign(this._styleTarget,e);let n=t?.duration??0,r=n>0||!!t?.spring,i=e;if(`edges`in e){let{edges:n,...a}=e;if(i=a,this.setEdges(!!n,r?t:void 0),Object.keys(i).length===0){this._requestRepaint();return}}let a=[],o={};for(let e of Object.keys(i))r&&this.animator.has(`style.${String(e)}`)?a.push(String(e)):o[e]=i[e];Object.keys(o).length>0&&(Object.assign(this.style,o),this._applyStyleEffects(o));for(let e of a)this.animator.to(`style.${e}`,this._animTargetOf(e,i),{...t,duration:n});this._requestRepaint()}getStyle(){return{...this._styleTarget,modeLabel:$r[this._styleTarget.mode]}}_animTargetOf(e,t){let n=t[e];return this._animDimOf(e)===1?Number(n):(this._colorScratch.set(String(n)),[this._colorScratch.r,this._colorScratch.g,this._colorScratch.b])}_animDimOf(e){return To.includes(e)?3:1}_registerAnimChannels(){for(let e of wo)this.animator.register(`style.${e}`,{dim:1,read:t=>{t[0]=Number(this.style[e]??0)},write:t=>{this.style[e]=t[0],this._onStyleChannelWrote(e)}});for(let e of To)this.animator.register(`style.${e}`,{dim:3,read:t=>{let n=this._uniformColorOf(e);t[0]=n.r,t[1]=n.g,t[2]=n.b},write:t=>{let n=this._uniformColorOf(e);n.setRGB(t[0],t[1],t[2]),this.style[e]=`#${n.getHexString()}`,this._onStyleChannelWrote(e)}});this.animator.register(`style.edgeFade`,{dim:1,read:e=>{e[0]=this.uniforms.uEdgeFade?.value??1},write:e=>{this.uniforms.uEdgeFade&&(this.uniforms.uEdgeFade.value=e[0]),this._syncEdgeStyle()}}),this.animator.register(`style.fade`,{dim:1,read:e=>{e[0]=this.uniforms.uFade?.value??1},write:e=>{this.uniforms.uFade&&(this.uniforms.uFade.value=e[0]),this._requestRepaint()}})}_onStyleChannelWrote(e){e===`opacity`?this._applyOpacity():(this._applyStyleUniforms(),(e===`edgeColor`||e===`edgeWidth`||e===`edgeOpacity`)&&this._refreshEdgeLines())}_uniformColorOf(e){let t=this.uniforms;switch(e){case`colorA`:return t.uColorA.value;case`colorB`:return t.uColorB.value;case`colorC`:return t.uColorC.value;case`selectColor`:return t.uSelColor.value;case`edgeColor`:return this.edgeMaterial.uniforms.uColor.value;default:return t.uColorA.value}}_applyStyleEffects(e){this._applyStyleUniforms(),(`opacity`in e||`depthWrite`in e)&&this._applyOpacity(),`mode`in e&&this._applyPointCloudStyles(),`shading`in e&&this._applyShading(),`edgeThreshold`in e&&this._edgesEnabled?(this._disposeEdges(),this.setEdges(!0)):(`edgeColor`in e||`edgeWidth`in e||`opacity`in e||`edgeOpacity`in e)&&this._refreshEdgeLines(),this._selection&&(`outline`in e||`outlineStyle`in e?this.select(this._selection,{silent:!0}):this._syncSelectionStyle())}_applyStyleUniforms(){let e=this.uniforms,t=this.style;e.uMode.value=t.mode,e.uColorA.value.set(t.colorA),e.uColorB.value.set(t.colorB),e.uColorC.value.set(t.colorC),e.uSelColor.value.set(t.selectColor),e.uFloorHeight.value=t.floorHeight;let n=t.selectMode??Q.OVERLAY;e.uSelMode&&(e.uSelMode.value=n===Q.REPLACE?0:n===Q.MULTIPLY?2:n===Q.GLOW_ONLY?3:1),e.uSelOpacity&&t.selectOpacity!=null&&(e.uSelOpacity.value=t.selectOpacity),e.uSelEmissive&&t.selectEmissive!=null&&(e.uSelEmissive.value=t.selectEmissive),e.uSelElevation&&t.selectElevation!=null&&(e.uSelElevation.value=t.selectElevation),e.uDimFactor&&t.dimFactor!=null&&(e.uDimFactor.value=t.dimFactor),e.uRoofThreshold&&t.roofThreshold!=null&&(e.uRoofThreshold.value=t.roofThreshold),e.uTexMix&&t.texMix!=null&&(e.uTexMix.value=t.texMix),e.uAmbientGain&&t.ambientGain!=null&&(e.uAmbientGain.value=t.ambientGain),e.uOpacity&&t.opacity!=null&&(e.uOpacity.value=So(t.opacity)),this.outlineMaterial&&(this.outlineMaterial.uniforms.uElevation&&t.selectElevation!=null&&(this.outlineMaterial.uniforms.uElevation.value=t.selectElevation),t.outlineWidth!=null&&(this.outlineMaterial.uniforms.uWidth.value=t.outlineWidth),t.outlineColor==null?this.outlineMaterial.uniforms.uColor.value.set(t.selectColor):this.outlineMaterial.uniforms.uColor.value.set(t.outlineColor))}_applyOpacity(){let e=So(this.style.opacity);this.uniforms.uOpacity&&(this.uniforms.uOpacity.value=e);let t=e<.999;if(t!==this._opacityTransparent){this._opacityTransparent=t;let e=this.style.depthWrite!==!1;for(let n of this._pickables.values()){if(xo(n.mesh))continue;let r=$(n.mesh);r&&(r.userData.uBatchTexActive?.value||(r.userData.uTileFade?.value??1)<1||(r.transparent=t,r.depthWrite=!t||e))}}for(let e of this._pointClouds)this._applyPointCloudStyle(e);this._syncEdgeStyle(),this._requestRepaint()}_applyPointCloudStyle(e,t=this._selectedMeshes.includes(e)){da(e,this.style,this.uniforms,t)}_applyPointCloudStyles(){for(let e of this._pointClouds)this._applyPointCloudStyle(e);this._requestRepaint()}_applyShading(){let e=this.style.shading!==`smooth`;for(let t of this._pickables.values()){let n=$(t.mesh);n&&n.flatShading!==e&&(n.flatShading=e,n.needsUpdate=!0)}this._requestRepaint()}async prewarmShading(){if(this._shadingPrewarmed||this._prewarming)return;let e=this.renderer,t=this.scene,n=this.camera;if(!e||!t||!n)return;let r=[],i=new Set;for(let e of this._pickables.values()){let t=$(e.mesh);t&&!i.has(t)&&(i.add(t),r.push(t))}if(r.length===0)return;this._shadingPrewarmed=!0,this._prewarming=!0;let a=this.style.shading===`smooth`,o=r.map(e=>e.flatShading);for(let e of r)e.flatShading=a;try{let r=e;typeof r.compileAsync==`function`?await r.compileAsync(t,n):e.compile(t,n)}catch{}finally{for(let e=0;e<r.length;e++)r[e].flatShading=o[e],r[e].needsUpdate=!0;this._prewarming=!1,this._requestRepaint()}}_addMeshHeight(e){let t=e.geometry?.boundingBox;if(!t)return;this._boxScratch.copy(t).applyMatrix4(e.matrixWorld);let n=this._boxScratch.min.z,r=this._boxScratch.max.z;Number.isFinite(n)&&Number.isFinite(r)&&(this._meshHeight.set(e,{min:n,max:r}),n<this._heightMin&&(this._heightMin=n),r>this._heightMax&&(this._heightMax=r),this._pushHeightRange())}_removeMeshHeight(e){let t=this._meshHeight.get(e);t&&(this._meshHeight.delete(e),t.min===this._heightMin||t.max===this._heightMax?this._recomputeHeightRange():this._pushHeightRange())}_refreshAllHeights(){if(this._meshHeight.size===0)return;let e=[...this._meshHeight.keys()];this._meshHeight.clear(),this._heightMin=1/0,this._heightMax=-1/0;for(let t of e)this._addMeshHeight(t);this._pushHeightRange()}_recomputeHeightRange(){let e=1/0,t=-1/0;for(let n of this._meshHeight.values())n.min<e&&(e=n.min),n.max>t&&(t=n.max);this._heightMin=e,this._heightMax=t,this._pushHeightRange()}_pushHeightRange(){let e=this._heightMin,t=this._heightMax;(!Number.isFinite(e)||!Number.isFinite(t)||t<=e)&&(e=0,t=100),this.uniforms.uHeightMin.value=e,this.uniforms.uHeightMax.value=t}_indexMeshSmids(e){let t=e.userData.geoRef?.pickInfo;if(t)for(let n of Object.keys(t)){let t=Number(n);if(!Number.isFinite(t)||t<0)continue;let r=this._smidMeshes.get(t);r||this._smidMeshes.set(t,r=new Set),r.add(e)}}_unindexMeshSmids(e){let t=e.userData.geoRef?.pickInfo;if(t)for(let n of Object.keys(t)){let t=Number(n),r=this._smidMeshes.get(t);r&&(r.delete(e),r.size===0&&this._smidMeshes.delete(t))}}setEdges(e,t){let n=!!t&&((t.duration??0)>0||!!t.spring);this._edgesEnabled=e,this.style.edges=e,this._styleTarget.edges=e;for(let t of this.datasets.values())t.root.traverse(t=>{t.userData.isEdgeLines&&(t.visible=e,this._styleEdgeLine(t))});if(this._syncEdgeStyle(),!e){n?this.animator.to(`style.edgeFade`,0,{...t,onComplete:()=>{this._disposeEdges(),this._requestRepaint(),t?.onComplete?.()}}):(this._setEdgeFade(1),this._disposeEdges()),this._requestRepaint();return}let r=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e.userData;return!t.edges&&!t.nativeEdges&&!xo(e)}),i=0,a=()=>{let e=performance.now();for(;i<r.length&&performance.now()-e<8;)this._ensureEdges(r[i++]);i<r.length?setTimeout(a,0):this._requestRepaint()};a(),n?(this._setEdgeFade(0),this.animator.to(`style.edgeFade`,1,t)):this._setEdgeFade(1)}_setEdgeFade(e){this.uniforms.uEdgeFade&&(this.uniforms.uEdgeFade.value=e),this._syncEdgeStyle()}_disposeEdges(){for(let e of this._pickables.values())this._removeEdges(e.mesh)}async loadCreases(e){let n=await fetch(e);if(!n.ok)throw Error(`[s3m] 棱线缓存加载失败: ${n.status} ${e}`);let r=await n.arrayBuffer(),i=new Float32Array(r);if(i.length<6)return;let a=new t.BufferGeometry;a.setAttribute(`position`,new t.BufferAttribute(i,3));let o=this.style,s=new t.LineBasicMaterial({color:new t.Color(o.edgeColor),transparent:!0,opacity:Math.min(1,Math.max(0,o.edgeOpacity??.6))*So(o.opacity),depthWrite:!1}),c=new t.LineSegments(a,s);c.renderOrder=2,c.frustumCulled=!1,c.raycast=()=>{},this.clearCreases(),this._creaseLines=c,this.scene?.add(c),this._requestRepaint()}clearCreases(){this._creaseLines&&(this.scene?.remove(this._creaseLines),this._creaseLines.geometry.dispose(),this._creaseLines.material?.dispose?.(),this._creaseLines=null,this._requestRepaint())}_syncEdgeStyle(){let e=this.style,t=this.uniforms.uEdgeFade?.value??1,n=Math.min(1,Math.max(0,e.edgeOpacity??.6))*So(e.opacity)*t,r=this.edgeMaterial.uniforms;if(r.uColor.value.set(e.edgeColor),r.uWidth.value=Math.max(.1,e.edgeWidth??1.5),r.uOpacity.value=n,this._creaseLines){let t=this._creaseLines.material;t.color.set(e.edgeColor),t.opacity=n}}_styleEdgeLine(e){let t=e.material;t&&t.color&&(t.color.set(this.style.edgeColor),t.opacity=(this.style.edgeOpacity??.6)*So(this.style.opacity)*(this.uniforms.uEdgeFade?.value??1),t.transparent=!0,t.polygonOffset=!0,t.polygonOffsetFactor=-1,t.polygonOffsetUnits=-1,t.needsUpdate=!0)}_refreshEdgeLines(){this._syncEdgeStyle();for(let e of this._nativeEdgeLines)e.parent&&this._styleEdgeLine(e)}_datasetEdgesEnabled(e){let t=e.options?.enableEdges;return t===!0||t!==!1&&this._edgesEnabled}_shouldSkipAutoEdges(t,n){let r=`${t.skeletonName??``} ${n}`.toLowerCase();return e._EDGE_SKIP_KEYWORDS.some(e=>r.includes(e))}_ensureEdges(e){let n=e.userData;if(n.edges||n.nativeEdges||!e.geometry||this._shouldSkipAutoEdges(n,``))return;let r=e.geometry.getAttribute(`position`);if((e.geometry.index?.count??(r?r.count:0))>12e4)return;let i=lo(e.geometry,.005),a=this.style.edgeThreshold??55,o=new t.EdgesGeometry(i,a);i.dispose();let s=o.getAttribute(`position`),c=s?s.array:null;if(o.dispose(),!c||c.length<6)return;let l=.005,u=ro(e.geometry,l),d;if(u){let e=c.length/6;d=new Float32Array(e);for(let t=0;t<e;t++){let e=t*6;d[t]=u.get(io(c[e],c[e+1],c[e+2],1/l))??-1}}let f=new t.Mesh(no(c,d),this._createEdgeMaterial(e));f.renderOrder=2,f.frustumCulled=!1,f.raycast=()=>{},f.userData.isThickEdge=!0,n.edges=f,e.add(f)}_createEdgeMaterial(e){let t=$(e),n=t?.userData?.uBatchTex?{uBatchTex:t.userData.uBatchTex,uBatchTex2:t.userData.uBatchTex2,uBatchMix:this.uniforms.uBatchMix,uBatchTexWidth:t.userData.uBatchTexWidth,uBatchTexActive:t.userData.uBatchTexActive,uPathTex:this.uniforms.uPathTex,uPathCount:this.uniforms.uPathCount,uPathTexActive:this.uniforms.uPathTexActive,uPathTime:this.uniforms.uPathTime}:void 0;return to(this.lineShared,{},this._edgeStyleUniforms,n)}_createSelectionEdgeMaterial(e){let t=$(e),n=t?.userData?.uBatchTex?{uBatchTex:t.userData.uBatchTex,uBatchTex2:t.userData.uBatchTex2,uBatchMix:this.uniforms.uBatchMix,uBatchTexWidth:t.userData.uBatchTexWidth,uBatchTexActive:t.userData.uBatchTexActive,uPathTex:this.uniforms.uPathTex,uPathCount:this.uniforms.uPathCount,uPathTexActive:this.uniforms.uPathTexActive,uPathTime:this.uniforms.uPathTime}:void 0;return to(this.lineShared,{},this._selEdgeStyleUniforms,n)}_removeEdges(e){let t=e.userData,n=t.edges;if(!n)return;e.remove(n),n.geometry?.dispose();let r=n.material;Array.isArray(r)?r.forEach(e=>e?.dispose?.()):r?.dispose?.(),t.edges=null}getRayAt(e,n){if(!this.camera||!this.canvas)return null;let r=this.canvas,i=r.clientWidth||r.width,a=r.clientHeight||r.height;if(!i||!a)return null;let o=e/i*2-1,s=-(n/a)*2+1,c=new t.Vector3(o,s,-1).unproject(this.camera),l=new t.Vector3(o,s,1).unproject(this.camera).clone().sub(c).normalize();return new t.Ray(c,l)}_intersectMeshAtRay(e,n,r){let i=new t.Raycaster;i.ray.copy(n);let a=i.intersectObject(e,!1);if(!a.length)return null;if(r!=null){let e=a.find(e=>e.instanceId===r);return e?e.point:a[0].point}return a[0].point}_buildPickResult(e,n,r,i){let a=n.mesh.userData,o=null,s=e.batchId,c=e.instanceIndex,l=a.geoRef,u=[];if(c!=null){let e=this._instanceFeature(n.mesh,l,c);if(!e)return null;o=e.smid,s=e.batchId}else{l=a.geoByBatchId?.get(e.batchId)??a.geoRef;let t=U(l,e.batchId);o=t.smid,u=t.segments}if(this._isFeatureHidden(o,s))return null;let d=null,f=0;if(c!=null)d=this._instanceBox(n.mesh,c),f=n.mesh.geometry.index?Math.round(n.mesh.geometry.index.count/3):0;else if(o!=null&&this._smidMeshes.has(o)){let e=this._smidMeshes.get(o),t=1/0,n=1/0,r=1/0,i=-1/0,a=-1/0,s=-1/0,c=0;for(let l of e){let e=l.userData,u=e.geoRef?.pickInfo,d=u?.[o]??u?.[String(o)],p=d?H(d):-1,m=d?.segments??(p>=0?U(e.geoRef,p).segments:[]),h=St(l.geometry,m);h&&(h.minX<t&&(t=h.minX),h.minY<n&&(n=h.minY),h.minZ<r&&(r=h.minZ),h.maxX>i&&(i=h.maxX),h.maxY>a&&(a=h.maxY),h.maxZ>s&&(s=h.maxZ),c+=h.count,f+=h.triangles)}c>0&&(d={minX:t,minY:n,minZ:r,maxX:i,maxY:a,maxZ:s,count:c,triangles:f})}if(!d&&(d=St(n.mesh.geometry,u),!d&&n.mesh.geometry)){n.mesh.geometry.boundingBox||n.mesh.geometry.computeBoundingBox();let e=n.mesh.geometry.boundingBox;e&&(d={minX:e.min.x,maxX:e.max.x,minY:e.min.y,maxY:e.max.y,minZ:e.min.z,maxZ:e.max.z,count:0,triangles:0})}let p=n.mesh.geometry,m=f>0?f:p.index?Math.round(p.index.count/3):0,h=Ct({smid:o,box:d,triangles:m,floorHeight:this.style.floorHeight}),g=null;if(d&&this.sceneAnchor){let e=new t.Vector3((d.minX+d.maxX)/2,(d.minY+d.maxY)/2,(d.minZ+d.maxZ)/2);e.applyMatrix4(n.mesh.matrixWorld);let r=this.sceneAnchor.meterInMercator;g=this._lngLatFromWorld(e.x*r+this.sceneAnchor.x,-e.y*r+this.sceneAnchor.y)}let _=r??null;!_&&i&&(_=this._intersectMeshAtRay(n.mesh,i,c));let v=null,y=null,b=null;if(_&&this.sceneAnchor){let e=o==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(o),n=e.translation,r=e.elevation,i=_.clone();if(e.rotation){let n=fo(e.rotation);if(n){let r=new t.Matrix3().set(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],n[8]),a=e.pivot?new t.Vector3(e.pivot[0],e.pivot[1],e.pivot[2]):new t.Vector3(0,0,0);i.sub(a).applyMatrix3(r).add(a)}}n?i.add(new t.Vector3(n[0],n[1],n[2])):r&&(i.z+=r),v=[i.x,i.y,i.z];let a=this.sceneAnchor.meterInMercator;y=this._lngLatFromWorld(i.x*a+this.sceneAnchor.x,-i.y*a+this.sceneAnchor.y),b=i.z+(this.sceneAnchor.altitude??0)}else g&&d&&this.sceneAnchor&&(y=g,b=(d.minZ+d.maxZ)/2+(this.sceneAnchor.altitude??0));return{datasetId:n.datasetId,datasetName:this.datasets.get(n.datasetId)?.name??n.datasetId,objectId:e.objectId,batchId:s,instanceIndex:c,skeletonName:n.skeletonName,centerLngLat:g,point:v,lngLat:y,altitude:b,...h,mesh:n.mesh}}pick(e,t){if(!this.picker||!this.scene||!this.camera||!this.sceneAnchor)return null;let n=this.picker.pick(this.scene,this.camera,e,t);if(!n)return null;let r=this._pickables.get(n.objectId);if(!r)return null;let i=this.getRayAt(e,t);return this._buildPickResult(n,r,void 0,i??void 0)}pickPosition(e,n){if(!this.camera||!this.sceneAnchor)return null;let r=this.pick(e,n);if(r?.point&&r?.lngLat&&r.altitude!=null)return{lngLat:r.lngLat,altitude:r.altitude,point:r.point};let i=this.getRayAt(e,n);if(!i)return null;let a=new t.Plane(new t.Vector3(0,0,1),0),o=new t.Vector3,s=i.intersectPlane(a,o);if(s){let e=this.sceneAnchor.meterInMercator;return{lngLat:this._lngLatFromWorld(s.x*e+this.sceneAnchor.x,-s.y*e+this.sceneAnchor.y),altitude:s.z+(this.sceneAnchor.altitude??0),point:[s.x,s.y,s.z]}}return null}drillPick(e,n,r=10){if(!this.sceneAnchor||!this.camera)return[];let i=this.getRayAt(e,n);if(!i)return[];let a=new t.Raycaster;a.ray.copy(i);let o=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e;for(;t;){if(!t.visible)return!1;t=t.parent}return!0}),s=a.intersectObjects(o,!1);if(!s.length)return[];let c=[],l=new Set,u=new Set;for(let e of s){if(c.length>=r)break;let t=e.object,n=t.userData;if(n.pickId==null)continue;let i=this._pickables.get(n.pickId);if(!i)continue;let a=null,o=-1,s=e.instanceId;if(s!=null){let e=this._instanceFeature(t,n.geoRef,s);if(!e)continue;a=e.smid,o=e.batchId}else if(e.faceIndex!=null){let r=t.geometry.attributes.aBatchId;if(r){let i=t.geometry.index?t.geometry.index.getX(e.faceIndex*3):e.faceIndex*3;o=Math.round(r.getX(i)),a=U(n.geoByBatchId?.get(o)??n.geoRef,o).smid}}if(a!=null){if(l.has(a))continue;l.add(a)}else{let e=`${n.pickId}:${o}:${s??-1}`;if(u.has(e))continue;u.add(e)}if(this._isFeatureHidden(a,o))continue;let d={objectId:n.pickId,batchId:o,instanceIndex:s},f=this._buildPickResult(d,i,e.point);f&&c.push(f)}return c}getFeatureBounds(e){if(!this.sceneAnchor)return null;let n=1/0,r=-1/0,i=1/0,a=-1/0,o=!1;for(let s of this._pickables.values()){let c=s.mesh,l=c.userData,u=l.geoRef,d=u?.pickInfo;if(!d)continue;let f=null;if(c.isInstancedMesh){let t=l.instanceLookup;t||(t=xt(d),l.instanceLookup=t);for(let[n,r]of t)if(r.smid===e){f=this._instanceBox(c,n);break}}else{let t=d,n=t[e]??t[String(e)];if(n){let e=U(u,H(n));if(f=St(c.geometry,e.segments),!f&&c.geometry){c.geometry.boundingBox||c.geometry.computeBoundingBox();let e=c.geometry.boundingBox;e&&(f={minX:e.min.x,maxX:e.max.x,minY:e.min.y,maxY:e.max.y,minZ:e.min.z,maxZ:e.max.z,count:0,triangles:0})}}}if(f){o=!0;let s=[new t.Vector3(f.minX,f.minY,f.minZ),new t.Vector3(f.maxX,f.minY,f.minZ),new t.Vector3(f.minX,f.maxY,f.minZ),new t.Vector3(f.maxX,f.maxY,f.minZ),new t.Vector3(f.minX,f.minY,f.maxZ),new t.Vector3(f.maxX,f.minY,f.maxZ),new t.Vector3(f.minX,f.maxY,f.maxZ),new t.Vector3(f.maxX,f.maxY,f.maxZ)],l=e==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(e),u=l.translation,d=l.elevation,p=l.rotation?fo(l.rotation):null,m=null,h=null;p&&(m=new t.Matrix3().set(p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8]),h=l.pivot?new t.Vector3(l.pivot[0],l.pivot[1],l.pivot[2]):new t.Vector3(0,0,0));let g=e==null?null:this._gpuPathPoseAt(e),_=null;if(g&&g.yaw!==0){let e=Math.cos(g.yaw),n=Math.sin(g.yaw);_=new t.Matrix3().set(e,-n,0,n,e,0,0,0,1)}for(let e of s){if(m&&h&&e.sub(h).applyMatrix3(m).add(h),_){let n=h??new t.Vector3(0,0,0);e.sub(n).applyMatrix3(_).add(n)}u?e.add(new t.Vector3(u[0],u[1],u[2])):d&&(e.z+=d),g&&e.add(new t.Vector3(g.pos[0],g.pos[1],g.pos[2])),e.applyMatrix4(c.matrixWorld);let o=this.sceneAnchor.meterInMercator,[s,l]=this._lngLatFromWorld(e.x*o+this.sceneAnchor.x,-e.y*o+this.sceneAnchor.y);s<n&&(n=s),s>r&&(r=s),l<i&&(i=l),l>a&&(a=l)}}}return o?[[n,i],[r,a]]:null}_instanceFeature(e,t,n){let r=e.userData;return r.instanceLookup||(r.instanceLookup=xt(t?.pickInfo)),r.instanceLookup.get(n)??null}_instanceBox(e,n){let r=e;if(!r.isInstancedMesh)return null;let i=e.geometry;i.boundingBox||i.computeBoundingBox();let a=i.boundingBox;if(!a)return null;let o=new t.Matrix4;r.getMatrixAt(n,o);let s=a.clone().applyMatrix4(o);return{minX:s.min.x,minY:s.min.y,minZ:s.min.z,maxX:s.max.x,maxY:s.max.y,maxZ:s.max.z,count:i.getAttribute(`position`)?.count??0,triangles:i.index?Math.round(i.index.count/3):0}}select(e,{silent:t=!1}={}){if(this._selection){for(let e of this._selectedMeshes){if(xo(e)){this._applyPointCloudStyle(e,!1);continue}let t=$(e);t&&(t.userData.uSelBatch.value=-1,t.userData.uSelWhole.value=0)}this._selectedMeshes=[],this._clearSelectionDecoration(),this._selection=null}if(!e){this.uniforms.uSelMix.value=0,this.uniforms.uDim.value=0,this.outlineMaterial.uniforms.uSelBatch.value=-1,this.outlineMaterial.uniforms.uSelWhole.value=0,this.outlineMaterial.uniforms.uElevation.value=0,this._requestRepaint(),t||this.onPick(null);return}this._selection=e;let n=new Set;if(e.smid!=null){let t=this._smidMeshes.get(e.smid);if(t)for(let e of t)n.add(e)}n.add(e.mesh);for(let t of n){let n=$(t);if(!n)continue;let r=e.batchId;if(e.instanceIndex!=null&&t===e.mesh)r=e.batchId;else if(e.smid!=null){let n=t.userData.geoRef?.pickInfo,i=n?.[e.smid]??n?.[String(e.smid)],a=i?H(i):-1;r=a>=0?a:t===e.mesh?e.batchId:-1}n.userData.uSelBatch.value=r,n.userData.uSelWhole.value=+(r<0),this._selectedMeshes.push(t)}for(let e of this._selectedMeshes)xo(e)&&this._applyPointCloudStyle(e,!0);if(this.uniforms.uSelMix.value=1,this.uniforms.uDim.value=+!!this.style.dimOthers,this.style.outline){let t=[...n].filter(e=>!xo(e));t.length&&((this.style.outlineStyle??`edges`)===`edges`?this._addSelectionEdges(e,t):this._addSelectionHull(e,t))}this._requestRepaint()}_addSelectionEdges(e,n){this._syncSelectionStyle();for(let r of n){let n=r.userData,i=n.geoRef,a=[],o=-1;if(r===e.mesh&&e.instanceIndex!=null){a=[{vertexOffset:0,vertexCount:r.geometry.getAttribute(`position`)?.count??0}];let t=i?.pickInfo,n=t?.[e.smid??``]??t?.[String(e.smid)];o=n?H(n):-1}else if(e.smid!=null){let t=i?.pickInfo,n=t?.[e.smid]??t?.[String(e.smid)],r=n?H(n):-1;o=r,a=n?.segments??(r>=0?U(i,r).segments:[])}else r===e.mesh&&(a=U(n.geoByBatchId?.get(e.batchId)??i,e.batchId).segments,o=e.batchId);let s=so(r.geometry,a);if(s&&s.length>0){let n=o>=0?new Float32Array(s.length/6).fill(o):void 0,i=new t.Mesh(no(s,n),this._createSelectionEdgeMaterial(r));i.renderOrder=4,i.frustumCulled=!1,i.raycast=()=>{},i.userData.isSelectionEdge=!0,r===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(i,e),r.add(i),this._selectionEdgeMeshes.push(i)}}this._selectionEdgeMeshes.length===0?this._addSelectionHull(e,n):this._selectionEdges=this._selectionEdgeMeshes[0]??null}_applyInstanceTransform(e,n){let r=n.mesh;if(n.instanceIndex==null||!r.isInstancedMesh)return;let i=new t.Matrix4;r.getMatrixAt(n.instanceIndex,i),i.decompose(e.position,e.quaternion,e.scale)}_addSelectionHull(e,n){let r=e.instanceIndex!=null;this.outlineMaterial.uniforms.uSelBatch.value=r?-1:e.batchId,this.outlineMaterial.uniforms.uSelWhole.value=r||e.batchId<0?1:0,this.outlineMaterial.uniforms.uElevation.value=r?this._selectionElevation(e):this.style.selectElevation??0;for(let r of n){let n=$(r);n?.userData?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=n.userData.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=n.userData.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=n.userData.uBatchTexActive.value);let i=new t.Mesh(r.geometry,this.outlineMaterial);i.renderOrder=3,i.frustumCulled=!1,i.raycast=()=>{},r===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(i,e),r.add(i),this._outlineMeshes.push(i)}this._outlineMesh=this._outlineMeshes[0]??null}_syncSelectionStyle(){let e=this.style,t=this.selectionEdgeMaterial.uniforms;t.uColor.value.set(e.outlineColor??e.selectColor),t.uWidth.value=Math.max(.1,e.outlineWidthPx??3),t.uOpacity.value=So(e.opacity),t.uElevation&&(t.uElevation.value=e.selectElevation??0);for(let e of this._outlineMeshes){let t=e.parent,n=t?$(t)?.userData:null;n?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=n.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=n.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=n.uBatchTexActive.value)}}_selectionElevation(e){let t=this.style.selectElevation??0;if(e.smid!=null){let n=this._featureStyleManager.getFeatureEffectiveOffset(e.smid);n.elevation&&(t+=n.elevation)}return t}_clearSelectionDecoration(){for(let e of this._outlineMeshes)e.parent?.remove(e);this._outlineMeshes=[],this._outlineMesh=null;for(let e of this._selectionEdgeMeshes)e.parent?.remove(e),e.geometry.dispose();this._selectionEdgeMeshes=[],this._selectionEdges=null}_updateLineResolution(e){let t=e.width||1,n=e.height||1,r=e.clientWidth||t;this.lineShared.uResolution.value.set(t,n),this.lineShared.uDpr.value=Math.max(1,t/r)}get lodRangeScale(){return this._lodRangeScale}setLodRangeScale(e,t){if(!(e<=0)){if(t){let n=this.datasets.get(t);n?.tileset&&(n.tileset.lodRangeScale=e)}else{this._lodRangeScale=e;for(let t of this.datasets.values())t.tileset&&(t.tileset.lodRangeScale=e)}this._requestRepaint()}}renderFrame(e){if(!this.renderer||!this.scene||!this.camera||!this.sceneAnchor||!this.canvas)return!1;let n=this.renderer.getContext();if(n&&typeof n.isContextLost==`function`&&n.isContextLost())return!1;if(this._prewarming)return!0;let r=this.animator.tick();this.flushOverrides();let i=this.canvas,a=this.sceneAnchor.meterInMercator;this._enuMatrix.set(a,0,0,this.sceneAnchor.x,0,-a,0,this.sceneAnchor.y,0,0,a,this.sceneAnchor.z,0,0,0,1);let o=new t.Matrix4().fromArray(e.mvp);o.multiply(this._enuMatrix),this.camera.projectionMatrix.copy(o),this.camera.projectionMatrixInverse.copy(o).invert();let s=e.cameraEnu;this.camera.position.set(s[0],s[1],s[2]),this.camera.matrixWorld.setPosition(s[0],s[1],s[2]),this.camera.matrixWorldInverse.copy(this.camera.matrixWorld).invert(),this.groundManager.update(this.camera);let c=!1;for(let t of this.datasets.values()){if(!t.visible||!t.tileset)continue;let n=[s[0]-t.offset[0],s[1]-t.offset[1],s[2]-t.offset[2]];t.tileset.update(n,e.fovRad,e.canvasHeight)&&(c=!0)}this.style.mode===Z.DYNAMIC&&(this.uniforms.uTime.value+=.016*(this.style.speed??1)),this.gpuPathManager.updateUniforms(this.uniforms);let l=(this.uniforms.uPathTexActive?.value??0)>0;l&&!this._customPathTime&&this.uniforms.uPathTime&&(this.uniforms.uPathTime.value+=.016),this._updateLights(),this._updateLineResolution(i),this.renderer.setViewport(0,0,i.width,i.height),this.renderer.resetState(),(this.uniforms.uOpacity?.value??1)>Co&&this.renderer.render(this.scene,this.camera),this._frame++;let u=performance.now();u-this._fps.last>500&&(this._fps.value=Math.round(this._frame*1e3/(u-this._fps.last)),this._frame=0,this._fps.last=u);let d=r||this.style.mode===Z.DYNAMIC||l||this.stats.loading>0||c;return this._prewarmShadingEnabled&&!this._shadingPrewarmed&&this._pickables.size>0&&this.prewarmShading(),d}get fps(){return this._fps.value}get stats(){let e={tiles:0,loading:0,failed:0,meshes:0,vertices:0,triangles:0,datasets:this.datasets.size};for(let t of this.datasets.values()){let n=t.tileset?.stats;n&&(e.tiles+=n.tiles,e.loading+=n.loading,e.failed+=n.failed,e.meshes+=n.meshes,e.vertices+=n.vertices,e.triangles+=n.triangles)}return e}getBounds(){let e=1/0,t=1/0,n=-1/0,r=-1/0;for(let i of this.datasets.values()){let a=ta(i.tileset?.config?.geoBounds);a&&(e=Math.min(e,a.left),n=Math.max(n,a.right),t=Math.min(t,a.bottom),r=Math.max(r,a.top))}return isFinite(e)?[[e,t],[n,r]]:null}dispose(){this.unmount()}};v(Do,`_EDGE_SKIP_KEYWORDS`,[`terrain`,`ground`,`vegetation`,`green`,`road`,`dem`,`绿地`,`道路`,`地面`,`地形`,`植被`,`铺装`]),Ji();var Oo=1e-4;function ko(e,t){let n=e.elements;for(let e=0;e<16;e++){let r=Math.max(1,Math.abs(n[e]),Math.abs(t[e]));if(Math.abs(n[e]-t[e])>Oo*r)return!1}return!0}function Ao(e){let t=e.elements,n=1;for(let e=0;e<16;e++){let r=Math.abs(t[e]);r>n&&(n=r)}let r=1e-6*n;return Math.abs(t[3])<r&&Math.abs(t[7])<r&&Math.abs(t[11])<r&&Math.abs(t[15]-1)<r}function jo(e,t){return t>0&&Math.abs(e.elements[5]*Math.tan(t/2)-1)<.001}function Mo(e){if(!e||typeof e!=`object`)return null;let t=e;return t.defaultProjectionData?.projectionMatrix??t.projectionMatrix??null}function No(e){let t={nearZ:null,farZ:null};if(!e||typeof e!=`object`)return t;let n=e,r=n.defaultProjectionData,i=e=>{let t=n[e];if(typeof t==`number`&&Number.isFinite(t))return t;let i=r?.[e];return typeof i==`number`&&Number.isFinite(i)?i:null};return{nearZ:i(`nearZ`),farZ:i(`farZ`)}}function Po(e,t){if(e&&typeof e==`object`){let t=e.fov;if(typeof t==`number`&&Number.isFinite(t)&&t>0)return t}return typeof t==`number`&&Number.isFinite(t)&&t>0?t:null}function Fo(e,n){let r=e.projectionMatrix;if(!r||r.length<16)return null;let i=new t.Matrix4().fromArray(Array.from(r)),a=new t.Matrix4().fromArray(Array.from(e.mvp));if(i.determinant()===0||!jo(i,n.fov))return null;let o=i.clone().invert().multiply(a);if(!ko(i.clone().multiply(o),Array.from(e.mvp))||!Ao(o)||!jo(i,n.fov))return null;let{distance:s,fov:c,aspect:l}=n;if(!(s>0)||!(c>0)||!(l>0))return null;let u=s*Math.tan(c/2),d=u*l,f=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,p=e.farZ!=null&&e.farZ>f?e.farZ:s*4+1e3;p>f||(p=f+1e3);let m=new t.OrthographicCamera(-d,d,u,-u,f,p);return m.updateProjectionMatrix(),{matrix:m.projectionMatrix.clone().multiply(o),view:o}}function Io(e,n,r){let i=e.projectionMatrix;if(!i||i.length<16)return null;let a=new t.Matrix4().fromArray(Array.from(i)),o=new t.Matrix4().fromArray(Array.from(e.mvp));if(a.determinant()===0||!jo(a,n.fov))return null;let s=a.clone().invert().multiply(o);if(!ko(a.clone().multiply(s),Array.from(e.mvp))||!Ao(s))return null;let c=Math.max(0,Math.min(1,r));if(c<=0)return{matrix:o,view:s};let{distance:l,fov:u,aspect:d}=n;if(!(l>0)||!(u>0)||!(d>0))return null;let f=l*Math.tan(u/2),p=f*d,m=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,h=e.farZ!=null&&e.farZ>m?e.farZ:l*4+1e3;h>m||(h=m+1e3);let g=new t.OrthographicCamera(-p,p,f,-f,m,h);if(g.updateProjectionMatrix(),c>=1)return{matrix:g.projectionMatrix.clone().multiply(s),view:s};let _=new t.Matrix4,v=a.elements,y=g.projectionMatrix.elements,b=_.elements;for(let e=0;e<16;e++)b[e]=(1-c)*v[e]+c*y[e];return{matrix:_.multiply(s),view:s}}var Lo=u({Animator:()=>Za,AttributeQuery:()=>At,BinaryReader:()=>b,DEFAULT_FLOOR_HEIGHT:()=>wt,DEFAULT_STYLE:()=>ti,DatasetManager:()=>uo,EARTH_RADIUS:()=>jt,EASING_NAMES:()=>Aa,FeatureStyleManager:()=>vo,GPUPathManager:()=>Jr,GroundManager:()=>yo,Path:()=>Gr,Picker:()=>ya,PixelFormat:()=>G,S3MFormatError:()=>yt,S3MTileset:()=>ia,S3MViewer:()=>Do,S3M_VERSION:()=>Ue,SAMPLES_PER_PATH:()=>256,SELECT_MODE:()=>Q,SELECT_MODE_LABELS:()=>ei,STYLE:()=>Z,STYLE_LABELS:()=>$r,TextureCompress:()=>K,VertexTag:()=>B,VertexTagV3:()=>We,buildAttributes:()=>Ct,buildBlendedMVP:()=>Io,buildFeatureEdgeSegments:()=>so,buildOrthoMVP:()=>Fo,buildThickLineGeometry:()=>no,buildTileObjects:()=>Gi,createLineSharedUniforms:()=>Qa,createOutlineMaterial:()=>Qr,createSharedUniforms:()=>Xr,createStyledMaterial:()=>Zr,createTexture:()=>Br,createThickLineMaterial:()=>to,cubicBezier:()=>Va,default:()=>Do,dxtPixelFormatOf:()=>Cn,easing:()=>ja,extractEulerAngles:()=>po,extractFovRadians:()=>Po,extractNearFar:()=>No,extractProjectionMatrix:()=>Mo,isS3M1Buffer:()=>Me,lngLatFromMercator:()=>Nt,lngLatFromWorld:()=>Ft,measureSegments:()=>St,mercatorFromLngLat:()=>Mt,parseS3M1:()=>He,parseS3MB:()=>bt,resolveFeature:()=>U,resolveRotationMatrix:()=>fo,resolveTextureKind:()=>Sn,setMaxAnisotropy:()=>Pr,steps:()=>Ha,worldFromLngLat:()=>Pt});Tt(),mi(),Yr(),Wr(),En(),Kr(),Tt(),En(),Wr(),Kr(),Yr(),mi(),Ji();var Ro=globalThis;return Ro.THREE||(Ro.THREE=t),Ro.S3M=Lo,e.Animator=Za,e.AttributeQuery=At,e.BinaryReader=b,e.DEFAULT_FLOOR_HEIGHT=wt,e.DEFAULT_STYLE=ti,e.DatasetManager=uo,e.EARTH_RADIUS=jt,e.EASING_NAMES=Aa,e.FeatureStyleManager=vo,e.GPUPathManager=Jr,e.GroundManager=yo,e.Path=Gr,e.Picker=ya,e.PixelFormat=G,e.S3MFormatError=yt,e.S3MTileset=ia,e.S3MViewer=Do,e.default=Do,e.S3M_VERSION=Ue,e.SAMPLES_PER_PATH=qr,e.SELECT_MODE=Q,e.SELECT_MODE_LABELS=ei,e.STYLE=Z,e.STYLE_LABELS=$r,e.TextureCompress=K,e.VertexTag=B,e.VertexTagV3=We,e.buildAttributes=Ct,e.buildBlendedMVP=Io,e.buildFeatureEdgeSegments=so,e.buildOrthoMVP=Fo,e.buildThickLineGeometry=no,e.buildTileObjects=Gi,e.createLineSharedUniforms=Qa,e.createOutlineMaterial=Qr,e.createSharedUniforms=Xr,e.createStyledMaterial=Zr,e.createTexture=Br,e.createThickLineMaterial=to,e.cubicBezier=Va,e.dxtPixelFormatOf=Cn,e.easing=ja,e.extractEulerAngles=po,e.extractFovRadians=Po,e.extractNearFar=No,e.extractProjectionMatrix=Mo,e.isS3M1Buffer=Me,e.lngLatFromMercator=Nt,e.lngLatFromWorld=Ft,e.measureSegments=St,e.mercatorFromLngLat=Mt,e.parseS3M1=He,e.parseS3MB=bt,e.resolveFeature=U,e.resolveRotationMatrix=fo,e.resolveTextureKind=Sn,e.setMaxAnisotropy=Pr,e.steps=Ha,e.worldFromLngLat=Pt,e})({},THREE);