s3m-three 0.3.11 → 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.
@@ -3837,7 +3837,7 @@ void main() {
3837
3837
  vec4 sampledDiffuseColor = s3mAtlasUnit( vMapUv, vAtlasRect, uAtlasDim, map );
3838
3838
  diffuseColor *= sampledDiffuseColor;
3839
3839
  #endif
3840
- ${d?`\n${Zy}`:``}`):d&&(e.fragmentShader=e.fragmentShader.replace(`#include <map_fragment>`,`#include <map_fragment>\n${Zy}`))},n.customProgramCacheKey=()=>`s3m-styled${u?`-atlas`:``}${d?`-bake`:``}`,n.userData.uSelBatch=r,n.userData.uSelWhole=i,n.userData.uBatchTex=a,n.userData.uBatchTex2=o,n.userData.uBatchTexWidth=s,n.userData.uBatchTexActive=c,n.userData.uTileFade=l,n.userData.isStyled=!0,n}function Iy(e,t=.9){let n=new gc({uniforms:{uSelBatch:{value:-1},uSelWhole:{value:0},uWidth:{value:t},uElevation:{value:0},uBatchTex:{value:Uy},uBatchTex2:{value:Uy},uBatchMix:e.uBatchMix??{value:0},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uPathTex:e.uPathTex??{value:My.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:Qy,fragmentShader:$y,side:1,depthWrite:!1,transparent:!1,polygonOffset:!0,polygonOffsetFactor:1,polygonOffsetUnits:1});return n.userData.isOutline=!0,n}var Ly,Ry,zy,By,Vy,Hy,Uy,Wy,Gy,Ky,qy,Jy,Yy,Xy,Zy,Qy,$y,eb=n((()=>{rh(),Ny(),Ly={WHITE:0,TEXTURE:1,SOLID:2,HEIGHT:3,FLOORS:4,BATCH:5,DYNAMIC:6,TOP_SIDE:7,CUSTOM:8},Ry={[Ly.WHITE]:`白膜`,[Ly.TEXTURE]:`原色`,[Ly.SOLID]:`单色`,[Ly.HEIGHT]:`按高度`,[Ly.FLOORS]:`按楼层`,[Ly.BATCH]:`按单体`,[Ly.DYNAMIC]:`动态扫描`,[Ly.TOP_SIDE]:`顶/侧分色`,[Ly.CUSTOM]:`自定义`},zy={REPLACE:`replace`,OVERLAY:`overlay`,MULTIPLY:`multiply`,GLOW_ONLY:`glowOnly`},By={[zy.OVERLAY]:`叠加原图 (Overlay)`,[zy.REPLACE]:`纯色覆盖 (Replace)`,[zy.MULTIPLY]:`叠乘模式 (Multiply)`,[zy.GLOW_ONLY]:`仅描边发光 (Glow)`},Vy={mode:Ly.TEXTURE,colorA:`#dfe6ee`,colorB:`#1d4ed8`,colorC:`#fbbf24`,selectColor:`#22d3ee`,selectMode:zy.OVERLAY,selectOpacity:.65,selectEmissive:.35,selectElevation:0,floorHeight:i_,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},Hy=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]),Uy=new Cu(Hy,1,6,ci,ei),Uy.minFilter=Rr,Uy.magFilter=Rr,Uy.needsUpdate=!0,Wy=`
3840
+ ${d?`\n${Zy}`:``}`):d&&(e.fragmentShader=e.fragmentShader.replace(`#include <map_fragment>`,`#include <map_fragment>\n${Zy}`))},n.customProgramCacheKey=()=>`s3m-styled${u?`-atlas`:``}${d?`-bake`:``}`,n.userData.uSelBatch=r,n.userData.uSelWhole=i,n.userData.uSelElevation=t?.uSelElevation,n.userData.uBatchMix=t?.uBatchMix,n.userData.uPathTex=t?.uPathTex,n.userData.uPathCount=t?.uPathCount,n.userData.uPathTime=t?.uPathTime,n.userData.uPathTexActive=t?.uPathTexActive,n.userData.uBatchTex=a,n.userData.uBatchTex2=o,n.userData.uBatchTexWidth=s,n.userData.uBatchTexActive=c,n.userData.uTileFade=l,n.userData.isStyled=!0,n}function Iy(e,t=.9){let n=new gc({uniforms:{uSelBatch:{value:-1},uSelWhole:{value:0},uWidth:{value:t},uElevation:{value:0},uBatchTex:{value:Uy},uBatchTex2:{value:Uy},uBatchMix:e.uBatchMix??{value:0},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uPathTex:e.uPathTex??{value:My.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:Qy,fragmentShader:$y,side:1,depthWrite:!1,transparent:!1,polygonOffset:!0,polygonOffsetFactor:1,polygonOffsetUnits:1});return n.userData.isOutline=!0,n}var Ly,Ry,zy,By,Vy,Hy,Uy,Wy,Gy,Ky,qy,Jy,Yy,Xy,Zy,Qy,$y,eb=n((()=>{rh(),Ny(),Ly={WHITE:0,TEXTURE:1,SOLID:2,HEIGHT:3,FLOORS:4,BATCH:5,DYNAMIC:6,TOP_SIDE:7,CUSTOM:8},Ry={[Ly.WHITE]:`白膜`,[Ly.TEXTURE]:`原色`,[Ly.SOLID]:`单色`,[Ly.HEIGHT]:`按高度`,[Ly.FLOORS]:`按楼层`,[Ly.BATCH]:`按单体`,[Ly.DYNAMIC]:`动态扫描`,[Ly.TOP_SIDE]:`顶/侧分色`,[Ly.CUSTOM]:`自定义`},zy={REPLACE:`replace`,OVERLAY:`overlay`,MULTIPLY:`multiply`,GLOW_ONLY:`glowOnly`},By={[zy.OVERLAY]:`叠加原图 (Overlay)`,[zy.REPLACE]:`纯色覆盖 (Replace)`,[zy.MULTIPLY]:`叠乘模式 (Multiply)`,[zy.GLOW_ONLY]:`仅描边发光 (Glow)`},Vy={mode:Ly.TEXTURE,colorA:`#dfe6ee`,colorB:`#1d4ed8`,colorC:`#fbbf24`,selectColor:`#22d3ee`,selectMode:zy.OVERLAY,selectOpacity:.65,selectEmissive:.35,selectElevation:0,floorHeight:i_,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},Hy=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]),Uy=new Cu(Hy,1,6,ci,ei),Uy.minFilter=Rr,Uy.magFilter=Rr,Uy.needsUpdate=!0,Wy=`
3841
3841
  attribute float aBatchId;
3842
3842
  attribute vec3 aColor;
3843
3843
  #ifdef S3M_ATLAS
@@ -3975,9 +3975,12 @@ void main() {
3975
3975
  if ( autoHeading ) {
3976
3976
  float c = cos( pathYaw );
3977
3977
  float s = sin( pathYaw );
3978
+
3979
+ // GLSL 的 mat3 是列优先:下面两行是「第 0 列 = (c, s)」,等价于绕 Z 转 +yaw,
3980
+ // 把模型 +X 朝向对到切线方向(yaw = atan2(dy, dx))。写成 (c,-s; s,c) 会左右镜像。
3978
3981
  mat3 rotHeading = mat3(
3979
- c, -s, 0.0,
3980
- s, c, 0.0,
3982
+ c, s, 0.0,
3983
+ -s, c, 0.0,
3981
3984
  0.0, 0.0, 1.0
3982
3985
  );
3983
3986
  s3mRot = rotHeading * s3mRot;
@@ -4397,9 +4400,12 @@ void main() {
4397
4400
  if ( autoHeading ) {
4398
4401
  float c = cos( pathYaw );
4399
4402
  float s = sin( pathYaw );
4403
+
4404
+ // GLSL 的 mat3 是列优先:下面两行是「第 0 列 = (c, s)」,等价于绕 Z 转 +yaw,
4405
+ // 把模型 +X 朝向对到切线方向(yaw = atan2(dy, dx))。写成 (c,-s; s,c) 会左右镜像。
4400
4406
  mat3 rotHeading = mat3(
4401
- c, -s, 0.0,
4402
- s, c, 0.0,
4407
+ c, s, 0.0,
4408
+ -s, c, 0.0,
4403
4409
  0.0, 0.0, 1.0
4404
4410
  );
4405
4411
  s3mRot = rotHeading * s3mRot;
@@ -4456,13 +4462,26 @@ void main() {
4456
4462
  #endif
4457
4463
  uniform float uObjectId;
4458
4464
  uniform sampler2D uBatchTex;
4465
+ uniform sampler2D uBatchTex2;
4466
+ uniform float uBatchMix;
4459
4467
  uniform float uBatchTexWidth;
4460
4468
  uniform int uBatchTexActive;
4469
+ uniform sampler2D uPathTex;
4470
+ uniform float uPathCount;
4471
+ uniform float uPathTime;
4472
+ uniform int uPathTexActive;
4461
4473
  uniform float uSelBatch;
4462
4474
  uniform float uSelWhole;
4463
4475
  uniform float uSelElevation;
4464
4476
  varying float vBatch;
4465
4477
 
4478
+ /** 交叉淡化期间也要读「屏幕上正在显示的那份」,否则过渡中点到的是旧位置 */
4479
+ vec4 s3mPickSample( vec2 uv ) {
4480
+ vec4 a = texture2D( uBatchTex, uv );
4481
+ if ( uBatchMix <= 0.0001 ) return a;
4482
+ return mix( a, texture2D( uBatchTex2, uv ), uBatchMix );
4483
+ }
4484
+
4466
4485
  void main() {
4467
4486
  float s3mBatch;
4468
4487
  #ifdef USE_INSTANCING
@@ -4474,22 +4493,82 @@ void main() {
4474
4493
  vBatch = aBatchId;
4475
4494
  #endif
4476
4495
 
4477
- // 单体状态(平移 / 隐藏)必须和主着色器用同一份数据、同一套算法:
4478
- // 平移只发生在顶点着色器里,拾取这一趟如果还按原始坐标画,移位的楼就点不中。
4496
+ // 单体状态必须和主着色器用同一份数据、同一套算法:位移 / 旋转 / 隐藏 / GPU 路径
4497
+ // 全都只发生在顶点着色器里,拾取这一趟如果还按原始坐标画,动过的楼就点不中。
4498
+ // 状态纹理共 6 行,行序与 StyleMaterial 的 VERT_SETUP 严格一一对应。
4479
4499
  vec3 p = position;
4500
+ mat3 rot = mat3( 1.0 );
4501
+ vec3 pivot = vec3( 0.0 );
4502
+ vec3 offset = vec3( 0.0 );
4503
+ bool hidden = false;
4504
+
4480
4505
  if ( uBatchTexActive > 0 && s3mBatch >= 0.0 ) {
4481
- vec4 state = texture2D( uBatchTex, vec2( ( s3mBatch + 0.5 ) / uBatchTexWidth, 0.25 ) );
4506
+ float u = ( s3mBatch + 0.5 ) / uBatchTexWidth;
4507
+ // Row 0:rgb = 配色,a = 抬高 / < -0.5 表示隐藏
4508
+ vec4 state = s3mPickSample( vec2( u, 0.08333333 ) );
4482
4509
  if ( state.a < -0.5 ) {
4483
- p = vec3( 0.0 );
4510
+ hidden = true;
4484
4511
  } else {
4485
- vec4 offset = texture2D( uBatchTex, vec2( ( s3mBatch + 0.5 ) / uBatchTexWidth, 0.75 ) );
4486
- p += offset.xyz;
4487
- if ( offset.z == 0.0 && state.a > 0.0 ) {
4488
- p.z += state.a;
4512
+ // Row 1:平移(z 已包含抬高)
4513
+ vec4 r1 = s3mPickSample( vec2( u, 0.25 ) );
4514
+ offset = r1.xyz;
4515
+ if ( offset.z == 0.0 && state.a > 0.0 ) offset.z = state.a;
4516
+
4517
+ // Row 2/3/4:3x3 姿态矩阵(列优先)+ 轴心
4518
+ vec4 r2 = s3mPickSample( vec2( u, 0.41666667 ) );
4519
+ vec4 r3 = s3mPickSample( vec2( u, 0.58333333 ) );
4520
+ vec4 r4 = s3mPickSample( vec2( u, 0.75 ) );
4521
+ rot = mat3(
4522
+ vec3( r2.x, r3.x, r4.x ),
4523
+ vec3( r2.y, r3.y, r4.y ),
4524
+ vec3( r2.z, r3.z, r4.z )
4525
+ );
4526
+ pivot = vec3( r2.w, r3.w, r4.w );
4527
+
4528
+ // Row 5:GPU 路径动画,与主着色器逐行对齐(含 loop / pingpong / clamp 与自动朝向)
4529
+ if ( uPathTexActive > 0 && uPathCount > 0.0 ) {
4530
+ vec4 r5 = s3mPickSample( vec2( u, 0.91666667 ) );
4531
+ float pathId = r5.x;
4532
+ float speed = r5.y;
4533
+ float phase = r5.z;
4534
+ float mode = r5.w;
4535
+ if ( pathId >= 0.0 && mode > 0.5 ) {
4536
+ float t = phase + uPathTime * speed;
4537
+ bool autoHeading = true;
4538
+ if ( mode >= 4.0 ) {
4539
+ autoHeading = false;
4540
+ mode -= 3.0;
4541
+ }
4542
+ if ( mode < 1.5 ) {
4543
+ t = fract( t );
4544
+ } else if ( mode < 2.5 ) {
4545
+ t = clamp( t, 0.0, 1.0 );
4546
+ } else {
4547
+ t = mod( t, 2.0 );
4548
+ t = ( t > 1.0 ) ? ( 2.0 - t ) : t;
4549
+ }
4550
+ vec4 pathSample = texture2D(
4551
+ uPathTex,
4552
+ vec2( ( t * 255.0 + 0.5 ) / 256.0, ( pathId + 0.5 ) / uPathCount )
4553
+ );
4554
+ if ( autoHeading ) {
4555
+ float c = cos( pathSample.w );
4556
+ float s = sin( pathSample.w );
4557
+ // 列优先:(c, s) 是第 0 列 → 绕 Z 转 +yaw,与 StyleMaterial / EdgeLines 逐位一致
4558
+ rot = mat3( c, s, 0.0, -s, c, 0.0, 0.0, 0.0, 1.0 ) * rot;
4559
+ }
4560
+ offset += pathSample.xyz;
4561
+ }
4489
4562
  }
4490
4563
  }
4491
4564
  }
4492
4565
 
4566
+ if ( hidden ) {
4567
+ p = vec3( 0.0 );
4568
+ } else {
4569
+ p = rot * ( p - pivot ) + pivot + offset;
4570
+ }
4571
+
4493
4572
  // 选中单体自身的拔高(selectElevation)
4494
4573
  float sel = max( step( 0.0, uSelBatch ) * step( abs( s3mBatch - uSelBatch ), 0.5 ), uSelWhole );
4495
4574
  p.z += sel * uSelElevation;
@@ -4516,7 +4595,7 @@ void main() {
4516
4595
  floor( b / 256.0 ) / 255.0
4517
4596
  );
4518
4597
  }
4519
- `,tx=(()=>{let e=new Cu(new Float32Array([-1,-1,-1,0,0,0,0,0]),1,2,ci,ei);return e.minFilter=Rr,e.magFilter=Rr,e.needsUpdate=!0,e})();function nx(e){return new gc({uniforms:{uObjectId:{value:e},uBatchTex:{value:tx},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uSelBatch:{value:-1},uSelWhole:{value:0},uSelElevation:{value:0}},vertexShader:$b,fragmentShader:ex,side:2,depthTest:!0,depthWrite:!0,toneMapped:!1})}function rx(e){return e.isPoints===!0}var ix=class{constructor(e,t={}){X(this,`renderer`,void 0),X(this,`size`,void 0),X(this,`target`,null),X(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 oo(e,e,{minFilter:Rr,magFilter:Rr,format:ci,type:Jr,depthBuffer:!0,stencilBuffer:!1}),this.target.texture.colorSpace=pa),this.target}pick(e,t,n,r){let i=this.renderer,a=i.domElement,o=a.width,s=a.height;if(!o||!s)return null;let c=Math.floor(n/a.clientWidth*o),l=Math.floor(r/a.clientHeight*s);if(c<0||l<0||c>=o||l>=s)return null;let u=this._ensureTarget(this.size),d=s-1-l,f=Math.floor(this.size/2),p=Math.floor(this.size/2);u.viewport.set(f-c,p-d,o,s);let m=i.getRenderTarget(),h=i.getViewport(new io),g=i.toneMapping,_=i.outputColorSpace,v=i.autoClear,y=i.getClearColor(new W),b=i.getClearAlpha(),x=[],S=new Set;e.traverseVisible(e=>{let t=e;if(!t.isMesh&&!rx(t))return;let n=t.userData;if(n.pickId===void 0)return;n.pickMaterial||(n.pickMaterial=nx(n.pickId)),t.isInstancedMesh&&S.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=tx,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,x.push([t,r]),t.material=i});let C=[];e.traverseVisible(e=>{let t=e;(t.isMesh||rx(t))&&t.userData.pickId===void 0&&(C.push(t),t.visible=!1)});let w=null;try{i.resetState(),i.setRenderTarget(u),i.toneMapping=0,i.outputColorSpace=pa,i.autoClear=!0,i.setClearColor(0,0),i.clear(),i.render(e,t),i.readRenderTargetPixels(u,f,p,1,1,this.buf);let n=this.buf[0],r=this.buf[1],a=this.buf[2],o=this.buf[3],s=n+r*256-1,c=a+o*256-1;s>=0&&(w=S.has(s)?{objectId:s,batchId:-1,instanceIndex:Math.max(0,c)}:{objectId:s,batchId:c})}finally{for(let[e,t]of x)e.material=t;for(let e of C)e.visible=!0;i.setRenderTarget(m),i.setViewport(h),i.toneMapping=g,i.outputColorSpace=_,i.autoClear=v,i.setClearColor(y,b),i.resetState()}return w}dispose(){this.target?.dispose(),this.target=null}},ax=1.70158,ox=ax*1.525,sx=2.70158,cx=2*Math.PI/3,lx=2*Math.PI/4.5,ux=7.5625,dx=2.75;function fx(e){if(e<1/dx)return ux*e*e;if(e<2/dx){let t=e-1.5/dx;return ux*t*t+.75}if(e<2.5/dx){let t=e-2.25/dx;return ux*t*t+.9375}let t=e-2.625/dx;return ux*t*t+.984375}function px(e){return 1-fx(1-e)}var mx={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=>sx*e*e*e-ax*e*e,easeOutBack:e=>1+sx*(e-1)**3+ax*(e-1)**2,easeInOutBack:e=>e<.5?(2*e)**2*(7.189819*e-ox)/2:((2*e-2)**2*(3.5949095*(e*2-2)+ox)+2)/2,easeInElastic:e=>e===0?0:e===1?1:-(2**(10*e-10))*Math.sin((e*10-10.75)*cx),easeOutElastic:e=>e===0?0:e===1?1:2**(-10*e)*Math.sin((e*10-.75)*cx)+1,easeInOutElastic:e=>e===0?0:e===1?1:e<.5?-(2**(20*e-10)*Math.sin((20*e-11.125)*lx))/2:2**(-20*e+10)*Math.sin((20*e-11.125)*lx)/2+1,easeInBounce:px,easeOutBounce:fx,easeInOutBounce:e=>e<.5?(1-px(1-2*e))/2:(1+px(2*e-1))/2},hx=Object.keys(mx);function gx(e){if(typeof e==`function`)return e;let t=mx[e];if(!t)throw Error(`[s3m] 未知的缓动曲线: ${String(e)}`);return t}var _x=8,vx=.001,yx=1e-7,bx=12,xx=(e,t)=>1-3*t+3*e,Sx=(e,t)=>3*t-6*e,Cx=e=>3*e;function wx(e,t,n){return((xx(t,n)*e+Sx(t,n))*e+Cx(t))*e}function Tx(e,t,n){return 3*xx(t,n)*e*e+2*Sx(t,n)*e+Cx(t)}function Ex(e,t,n,r){if(e===t&&n===r)return e=>e;let i=t=>{let r=t;for(let i=0;i<_x;i++){let i=Tx(r,e,n);if(Math.abs(i)<vx)break;let a=wx(r,e,n)-t;if(Math.abs(a)<yx)return r;r-=a/i}let i=0,a=1;r=t;for(let o=0;o<bx;o++){let o=wx(r,e,n);if(Math.abs(o-t)<yx)return r;o<t?i=r:a=r,r=(i+a)/2}return r};return e=>e<=0?0:e>=1?1:wx(i(e),t,r)}function Dx(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)}}uh();var Ox=1e-4,kx=.15;function Ax(e){return e<0?0:e>1?1:e}function jx(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 Mx=class{constructor(e,t){X(this,`key`,void 0),X(this,`channel`,void 0),X(this,`dim`,void 0),X(this,`to`,new Float32Array(3)),X(this,`_cur`,new Float32Array(3)),X(this,`done`,!1),X(this,`onComplete`,void 0),this.key=e,this.channel=t,this.dim=t.dim}},Nx=class extends Mx{constructor(...e){super(...e),X(this,`_from`,new Float32Array(3)),X(this,`_start`,0),X(this,`_duration`,0),X(this,`_delay`,0),X(this,`_ease`,gx(`linear`)),X(this,`_retarget`,`proportional`),X(this,`_span`,0),X(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?gx(t.easing):gx(`linear`),this._retarget=t.retarget??`proportional`,this._span=jx(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:Ax(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>Ox){let e=jx(this._from,this.to,this.dim)/this._span;i=Math.min(r,Math.max(r*kx,r*e))}this._start=t,this._delay=Math.max(0,n.delay??0),this._duration=i,this._ease=n.easing?gx(n.easing):this._ease,this._span=jx(this._from,this.to,this.dim),this._progress=0,this.done=!1}},Px=class extends Mx{constructor(...e){super(...e),X(this,`_x0`,new Float32Array(3)),X(this,`_v0`,new Float32Array(3)),X(this,`_vel`,new Float32Array(3)),X(this,`_start`,0),X(this,`_k`,120),X(this,`_c`,14),X(this,`_eps`,.001),X(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}=Fx(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=Fx(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 Fx(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 Ix=class{constructor(e=()=>performance.now()){X(this,`_channels`,new Map),X(this,`_tracks`,new Map),X(this,`_buf`,new Float32Array(3)),X(this,`_finished`,[]),X(this,`_now`,void 0),X(this,`_budgetMs`,2.5),X(this,`_lastTick`,-1/0),X(this,`_skipped`,0),X(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 Px;if(c&&c!=null&&u!==l&&(this._tracks.delete(e),c=void 0),c||this.onActive?.(),!c){let t=l?new Px(e,r):new Nx(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}};rh(),eb(),Ny();function Lx(){return{uResolution:{value:new B(1,1)},uDpr:{value:1}}}var Rx=`
4598
+ `,tx=(()=>{let e=new Cu(new Float32Array([-1,-1,-1,0,0,0,0,0]),1,2,ci,ei);return e.minFilter=Rr,e.magFilter=Rr,e.needsUpdate=!0,e})(),nx=(()=>{let e=new Cu(new Float32Array([0,0,0,0]),1,1,ci,ei);return e.minFilter=Rr,e.magFilter=Rr,e.needsUpdate=!0,e})();function rx(e){return new gc({uniforms:{uObjectId:{value:e},uBatchTex:{value:tx},uBatchTex2:{value:tx},uBatchMix:{value:0},uBatchTexWidth:{value:1},uBatchTexActive:{value:0},uPathTex:{value:nx},uPathCount:{value:1},uPathTime:{value:0},uPathTexActive:{value:0},uSelBatch:{value:-1},uSelWhole:{value:0},uSelElevation:{value:0}},vertexShader:$b,fragmentShader:ex,side:2,depthTest:!0,depthWrite:!0,toneMapped:!1})}function ix(e){return e.isPoints===!0}var ax=class{constructor(e,t={}){X(this,`renderer`,void 0),X(this,`size`,void 0),X(this,`target`,null),X(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 oo(e,e,{minFilter:Rr,magFilter:Rr,format:ci,type:Jr,depthBuffer:!0,stencilBuffer:!1}),this.target.texture.colorSpace=pa),this.target}pick(e,t,n,r){let i=this.renderer,a=i.domElement,o=a.width,s=a.height;if(!o||!s)return null;let c=Math.floor(n/a.clientWidth*o),l=Math.floor(r/a.clientHeight*s);if(c<0||l<0||c>=o||l>=s)return null;let u=this._ensureTarget(this.size),d=s-1-l,f=Math.floor(this.size/2),p=Math.floor(this.size/2);u.viewport.set(f-c,p-d,o,s);let m=i.getRenderTarget(),h=i.getViewport(new io),g=i.toneMapping,_=i.outputColorSpace,v=i.autoClear,y=i.getClearColor(new W),b=i.getClearAlpha(),x=[],S=new Set;e.traverseVisible(e=>{let t=e;if(!t.isMesh&&!ix(t))return;let n=t.userData;if(n.pickId===void 0)return;n.pickMaterial||(n.pickMaterial=rx(n.pickId)),t.isInstancedMesh&&S.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=tx,i.uniforms.uBatchTex2.value=tx,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??nx,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,x.push([t,r]),t.material=i});let C=[];e.traverseVisible(e=>{let t=e;(t.isMesh||ix(t))&&t.userData.pickId===void 0&&(C.push(t),t.visible=!1)});let w=null;try{i.resetState(),i.setRenderTarget(u),i.toneMapping=0,i.outputColorSpace=pa,i.autoClear=!0,i.setClearColor(0,0),i.clear(),i.render(e,t),i.readRenderTargetPixels(u,f,p,1,1,this.buf);let n=this.buf[0],r=this.buf[1],a=this.buf[2],o=this.buf[3],s=n+r*256-1,c=a+o*256-1;s>=0&&(w=S.has(s)?{objectId:s,batchId:-1,instanceIndex:Math.max(0,c)}:{objectId:s,batchId:c})}finally{for(let[e,t]of x)e.material=t;for(let e of C)e.visible=!0;i.setRenderTarget(m),i.setViewport(h),i.toneMapping=g,i.outputColorSpace=_,i.autoClear=v,i.setClearColor(y,b),i.resetState()}return w}dispose(){this.target?.dispose(),this.target=null}},ox=1.70158,sx=ox*1.525,cx=2.70158,lx=2*Math.PI/3,ux=2*Math.PI/4.5,dx=7.5625,fx=2.75;function px(e){if(e<1/fx)return dx*e*e;if(e<2/fx){let t=e-1.5/fx;return dx*t*t+.75}if(e<2.5/fx){let t=e-2.25/fx;return dx*t*t+.9375}let t=e-2.625/fx;return dx*t*t+.984375}function mx(e){return 1-px(1-e)}var hx={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=>cx*e*e*e-ox*e*e,easeOutBack:e=>1+cx*(e-1)**3+ox*(e-1)**2,easeInOutBack:e=>e<.5?(2*e)**2*(7.189819*e-sx)/2:((2*e-2)**2*(3.5949095*(e*2-2)+sx)+2)/2,easeInElastic:e=>e===0?0:e===1?1:-(2**(10*e-10))*Math.sin((e*10-10.75)*lx),easeOutElastic:e=>e===0?0:e===1?1:2**(-10*e)*Math.sin((e*10-.75)*lx)+1,easeInOutElastic:e=>e===0?0:e===1?1:e<.5?-(2**(20*e-10)*Math.sin((20*e-11.125)*ux))/2:2**(-20*e+10)*Math.sin((20*e-11.125)*ux)/2+1,easeInBounce:mx,easeOutBounce:px,easeInOutBounce:e=>e<.5?(1-mx(1-2*e))/2:(1+mx(2*e-1))/2},gx=Object.keys(hx);function _x(e){if(typeof e==`function`)return e;let t=hx[e];if(!t)throw Error(`[s3m] 未知的缓动曲线: ${String(e)}`);return t}var vx=8,yx=.001,bx=1e-7,xx=12,Sx=(e,t)=>1-3*t+3*e,Cx=(e,t)=>3*t-6*e,wx=e=>3*e;function Tx(e,t,n){return((Sx(t,n)*e+Cx(t,n))*e+wx(t))*e}function Ex(e,t,n){return 3*Sx(t,n)*e*e+2*Cx(t,n)*e+wx(t)}function Dx(e,t,n,r){if(e===t&&n===r)return e=>e;let i=t=>{let r=t;for(let i=0;i<vx;i++){let i=Ex(r,e,n);if(Math.abs(i)<yx)break;let a=Tx(r,e,n)-t;if(Math.abs(a)<bx)return r;r-=a/i}let i=0,a=1;r=t;for(let o=0;o<xx;o++){let o=Tx(r,e,n);if(Math.abs(o-t)<bx)return r;o<t?i=r:a=r,r=(i+a)/2}return r};return e=>e<=0?0:e>=1?1:Tx(i(e),t,r)}function Ox(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)}}uh();var kx=1e-4,Ax=.15;function jx(e){return e<0?0:e>1?1:e}function Mx(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 Nx=class{constructor(e,t){X(this,`key`,void 0),X(this,`channel`,void 0),X(this,`dim`,void 0),X(this,`to`,new Float32Array(3)),X(this,`_cur`,new Float32Array(3)),X(this,`done`,!1),X(this,`onComplete`,void 0),this.key=e,this.channel=t,this.dim=t.dim}},Px=class extends Nx{constructor(...e){super(...e),X(this,`_from`,new Float32Array(3)),X(this,`_start`,0),X(this,`_duration`,0),X(this,`_delay`,0),X(this,`_ease`,_x(`linear`)),X(this,`_retarget`,`proportional`),X(this,`_span`,0),X(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?_x(t.easing):_x(`linear`),this._retarget=t.retarget??`proportional`,this._span=Mx(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:jx(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>kx){let e=Mx(this._from,this.to,this.dim)/this._span;i=Math.min(r,Math.max(r*Ax,r*e))}this._start=t,this._delay=Math.max(0,n.delay??0),this._duration=i,this._ease=n.easing?_x(n.easing):this._ease,this._span=Mx(this._from,this.to,this.dim),this._progress=0,this.done=!1}},Fx=class extends Nx{constructor(...e){super(...e),X(this,`_x0`,new Float32Array(3)),X(this,`_v0`,new Float32Array(3)),X(this,`_vel`,new Float32Array(3)),X(this,`_start`,0),X(this,`_k`,120),X(this,`_c`,14),X(this,`_eps`,.001),X(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}=Ix(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=Ix(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 Ix(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 Lx=class{constructor(e=()=>performance.now()){X(this,`_channels`,new Map),X(this,`_tracks`,new Map),X(this,`_buf`,new Float32Array(3)),X(this,`_finished`,[]),X(this,`_now`,void 0),X(this,`_budgetMs`,2.5),X(this,`_lastTick`,-1/0),X(this,`_skipped`,0),X(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 Fx;if(c&&c!=null&&u!==l&&(this._tracks.delete(e),c=void 0),c||this.onActive?.(),!c){let t=l?new Fx(e,r):new Px(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}};rh(),eb(),Ny();function Rx(){return{uResolution:{value:new B(1,1)},uDpr:{value:1}}}var zx=`
4520
4599
  attribute vec3 aOther;
4521
4600
  attribute float aSide;
4522
4601
  attribute float aBatchId;
@@ -4605,9 +4684,12 @@ void main() {
4605
4684
  if ( autoHeading ) {
4606
4685
  float c = cos( pathYaw );
4607
4686
  float s = sin( pathYaw );
4687
+
4688
+ // GLSL 的 mat3 是列优先:下面两行是「第 0 列 = (c, s)」,等价于绕 Z 转 +yaw,
4689
+ // 把模型 +X 朝向对到切线方向(yaw = atan2(dy, dx))。写成 (c,-s; s,c) 会左右镜像。
4608
4690
  mat3 rotHeading = mat3(
4609
- c, -s, 0.0,
4610
- s, c, 0.0,
4691
+ c, s, 0.0,
4692
+ -s, c, 0.0,
4611
4693
  0.0, 0.0, 1.0
4612
4694
  );
4613
4695
  s3mRot = rotHeading * s3mRot;
@@ -4647,7 +4729,7 @@ void main() {
4647
4729
 
4648
4730
  gl_Position = vec4( ndc * clipA.w, clipA.z, clipA.w );
4649
4731
  }
4650
- `,zx=`
4732
+ `,Bx=`
4651
4733
  uniform vec3 uColor;
4652
4734
  uniform float uOpacity;
4653
4735
 
@@ -4655,9 +4737,9 @@ void main() {
4655
4737
  if ( uOpacity <= 0.003 ) discard;
4656
4738
  gl_FragColor = vec4( uColor, uOpacity );
4657
4739
  }
4658
- `;function Bx(e,t={},n,r){let i=n??{uColor:{value:new W(t.color??`#ffffff`)},uOpacity:{value:t.opacity??1},uWidth:{value:t.width??1.5},uElevation:{value:t.elevation??0}};t.color!==void 0&&n&&i.uColor.value.set(t.color),t.opacity!==void 0&&n&&(i.uOpacity.value=t.opacity),t.width!==void 0&&n&&(i.uWidth.value=t.width);let a={uBatchTex:r?.uBatchTex??{value:Uy},uBatchTex2:r?.uBatchTex2??{value:Uy},uBatchMix:r?.uBatchMix??{value:0},uBatchTexWidth:r?.uBatchTexWidth??{value:1},uBatchTexActive:r?.uBatchTexActive??{value:0},uPathTex:r?.uPathTex??{value:My.DUMMY_PATH_TEX},uPathCount:r?.uPathCount??{value:1},uPathTexActive:r?.uPathTexActive??{value:0},uPathTime:r?.uPathTime??{value:0}},o=new gc({uniforms:{uResolution:e.uResolution,uDpr:e.uDpr,uColor:i.uColor,uOpacity:i.uOpacity,uWidth:i.uWidth,uElevation:i.uElevation??{value:t.elevation??0},uTranslation:{value:new H(0,0,0)},uBatchTex:a.uBatchTex,uBatchTex2:a.uBatchTex2,uBatchMix:a.uBatchMix,uBatchTexWidth:a.uBatchTexWidth,uBatchTexActive:a.uBatchTexActive,uPathTex:a.uPathTex,uPathCount:a.uPathCount,uPathTexActive:a.uPathTexActive,uPathTime:a.uPathTime},vertexShader:Rx,fragmentShader:zx,transparent:!0,depthWrite:!1,side:2,polygonOffset:!0,polygonOffsetFactor:-2,polygonOffsetUnits:-2});return o.userData.isThickLine=!0,o}function Vx(e,t){let n=Math.floor(e.length/6),r=n*4,i=new Float32Array(r*3),a=new Float32Array(r*3),o=new Float32Array(r),s=new Float32Array(r),c=r>65535?new Uint32Array(n*6):new Uint16Array(n*6);for(let r=0;r<n;r++){let n=r*6,i=e[n],a=e[n+1],o=e[n+2],u=e[n+3],d=e[n+4],f=e[n+5],p=t?Number(t[r]??-1):-1,m=r*4;l(m,i,a,o,u,d,f,-1),l(m+1,i,a,o,u,d,f,1),l(m+2,u,d,f,i,a,o,1),l(m+3,u,d,f,i,a,o,-1);for(let e=0;e<4;e++)s[m+e]=p;let h=r*6;c[h]=m,c[h+1]=m+1,c[h+2]=m+2,c[h+3]=m,c[h+4]=m+2,c[h+5]=m+3}function l(e,t,n,r,s,c,l,u){let d=e*3;i[d]=t,i[d+1]=n,i[d+2]=r,a[d]=s,a[d+1]=c,a[d+2]=l,o[e]=u}let u=new q;return u.setAttribute(`position`,new G(i,3)),u.setAttribute(`aOther`,new G(a,3)),u.setAttribute(`aSide`,new G(o,1)),u.setAttribute(`aBatchId`,new G(s,1)),u.setIndex(new G(c,1)),u.computeBoundingSphere(),u}function Hx(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=Ux(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 Ux(e,t,n,r){return`${Math.round(e*r)},${Math.round(t*r)},${Math.round(n*r)}`}var Wx=6e4,Gx=100;function Kx(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]*Gx)},${Math.round(o[n]*Gx)},${Math.round(s[n]*Gx)}`,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>=Wx*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}rh();function qx(e,t,n,r){return`${Math.round(e*r)},${Math.round(t*r)},${Math.round(n*r)}`}function Jx(e,t){let n=e.getAttribute(`position`);if(!n||n.count===0)return e;let r=1/Math.max(t,1e-9),i=new Map,a=[],o=new Int32Array(n.count);for(let e=0;e<n.count;e++){let t=n.getX(e),s=n.getY(e),c=n.getZ(e),l=qx(t,s,c,r),u=i.get(l);u===void 0&&(u=a.length/3,a.push(t,s,c),i.set(l,u)),o[e]=u}let s=e.getIndex(),c=s?s.count:n.count,l=new Uint32Array(c);for(let e=0;e<c;e++)l[e]=o[s?s.getX(e):e];let u=new q;return u.setAttribute(`position`,new K(a,3)),u.setIndex(new G(l,1)),u}rh(),uh();var Yx=class{constructor(){X(this,`datasets`,new Map),X(this,`sceneAnchor`,null),X(this,`totalMaxTiles`,0)}get(e){return this.datasets.get(e)}values(){return this.datasets.values()}registerDataset(e){let t=this.datasets.get(e.id);if(t)return t;let n=new Ml;n.name=`s3m-dataset:${e.id}`,n.visible=e.visible!==!1;let r={id:e.id,name:e.name??e.id,options:e,root:n,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,r),this.rebalanceBudgets(),r}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,t,n,r,i,a,o,s,c){let l=this.datasets.get(e.id);if(l)return l;let u=new Ml;u.name=`s3m-dataset:${e.id}`,u.visible=e.visible!==!1,t.add(u);let d={id:e.id,name:e.name??e.id,options:e,root:u,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,d);let f=new Wb({configUrl:e.configUrl,maxTiles:e.maxTiles??o,maxConcurrent:s,lodRangeScale:e.lodRangeScale??i,buildTile:a??null,useWorker:e.useWorker,uniforms:r,onTile:e=>{c.onTile(e,d)},onTileRemoved:e=>{c.onTileRemoved(e,d)},onProgress:()=>{c.onStats(),c.triggerRepaint()},onError:e=>{d.error=e,c.onError(e),c.onStats()}});d.tileset=f,this.rebalanceBudgets();try{await f.init()}catch(e){return d.error=e,c.onError(e),d}return d.anchor=f.anchor,d.baseAlignOffset=this.computeAlignOffset(f,e.align),d.userOffset=e.heightOffset??0,d.heightOffset=d.baseAlignOffset+d.userOffset,this.layoutDataset(d,n),c.onReady(d),c.triggerRepaint(),d}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=m_(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0));let n=this.sceneAnchor.meterInMercator,r=m_(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=Vb(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}};rh(),a_(),uh();function Xx(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 t=new Xo(e[0],e[1],e[2]),n=new U().makeRotationFromEuler(t).elements;return[n[0],n[4],n[8],n[1],n[5],n[9],n[2],n[6],n[10]]}if(e.length===4){let t=new fo(e[0],e[1],e[2],e[3]),n=new U().makeRotationFromQuaternion(t).elements;return[n[0],n[4],n[8],n[1],n[5],n[9],n[2],n[6],n[10]]}}if(e instanceof Xo){let t=new U().makeRotationFromEuler(e).elements;return[t[0],t[4],t[8],t[1],t[5],t[9],t[2],t[6],t[10]]}if(e instanceof fo){let t=new U().makeRotationFromQuaternion(e).elements;return[t[0],t[4],t[8],t[1],t[5],t[9],t[2],t[6],t[10]]}if(e instanceof V){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 U){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 Zx(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 t=new fo(e[0],e[1],e[2],e[3]),n=new Xo().setFromQuaternion(t);return[n.x,n.y,n.z]}}if(e instanceof Xo)return[e.x,e.y,e.z];if(e instanceof fo){let t=new Xo().setFromQuaternion(e);return[t.x,t.y,t.z]}if(e instanceof V){let t=new U().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),n=new Xo().setFromRotationMatrix(t);return[n.x,n.y,n.z]}if(e instanceof U){let t=new Xo().setFromRotationMatrix(e);return[t.x,t.y,t.z]}return[0,0,0]}function Qx(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function $x(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 eS(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 tS(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 nS=class{constructor(e,t,n,r,i,a=()=>!1){X(this,`_getLayerFloorHeight`,void 0),X(this,`_triggerRepaint`,void 0),X(this,`_onStyleChanged`,void 0),X(this,`_getAllMeshes`,void 0),X(this,`_applyOverrideHook`,void 0),X(this,`_isLayerTransparent`,void 0),X(this,`featureStyles`,new Map),X(this,`thematicColors`,new Map),X(this,`thematicElevation`,new Map),X(this,`thematicField`,null),X(this,`elevationField`,null),X(this,`filter`,null),X(this,`fieldFilter`,null),X(this,`_meshBatchTextures`,new WeakMap),X(this,`_markedMeshes`,new Set),X(this,`_dirtyAll`,!1),X(this,`_flushScheduled`,!1),X(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,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n;if(!r.length)return this.clearThematicColors(),{field:e.field,type:`discrete`,matched:0,missing:0,legend:[]};let i=await t.queryBySmids(r),a=[],o=[];for(let t of r){let n=i.get(t),r=n?n[e.field]:void 0;if(r==null||r===``)continue;let s=Number(r);Number.isFinite(s)?a.push({smid:t,val:s}):o.push({smid:t,val:String(r)})}let s=a.length>=o.length&&a.length>0,c=new Map,l=[],u=e.defaultColor??`#64748b`,d=e.nullColor??`#334155`;if(s){let t=a.map(e=>e.val),n=Math.min(...t),r=Math.max(...t)-n||1,i=(e.ramp??[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`]).map(e=>new W(e)),o=Math.max(2,e.stops??5);for(let e=0;e<o;e++){let t=e/o,a=(e+1)/o,s=$x(i,(t+a)/2),c=n+t*r,u=n+a*r;l.push({color:`#${s.getHexString()}`,label:`${tS(c)} ~ ${tS(u)}`,count:0,min:c,max:u})}for(let{smid:e,val:t}of a){let i=Math.min(1,Math.max(0,(t-n)/r)),a=Math.min(o-1,Math.floor(i*o)),s=l[a].color;c.set(e,s),l[a].count++}}else{let t=new Map;for(let{val:e}of o)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];l.push({color:o,label:t,count:a})}let a=new Map(l.map(e=>[e.label,e.color]));for(let{smid:e,val:t}of o)c.set(e,a.get(t)??u)}let f=0;for(let e of r)c.has(e)||(c.set(e,d),f++);return f>0&&l.push({color:d,label:`无数据 / 缺失`,count:f}),this.setThematicColors(c,e.field),{field:e.field,type:s?`continuous`:`discrete`,matched:r.length-f,missing:f,legend:l}}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?eS(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=Qg(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,t,n,r,i){let a=t;for(let t=0;t<a;t++){e[t*4+0]=-1,e[t*4+1]=-1,e[t*4+2]=-1,e[t*4+3]=0;let n=(a+t)*4;e[n+0]=0,e[n+1]=0,e[n+2]=0,e[n+3]=0;let r=(a*2+t)*4;e[r+0]=1,e[r+1]=0,e[r+2]=0,e[r+3]=0;let i=(a*3+t)*4;e[i+0]=0,e[i+1]=1,e[i+2]=0,e[i+3]=0;let o=(a*4+t)*4;e[o+0]=0,e[o+1]=0,e[o+2]=1,e[o+3]=0;let s=(a*5+t)*4;e[s+0]=-1,e[s+1]=0,e[s+2]=0,e[s+3]=0}let o=!1,s=new Set,c=new Map,l=new Map,u=new Map,d=new Map,f=new Map,p=new Map,m=new Map,h=new Map,g=this.filter,_=r.userData;for(let[e,t]of Object.entries(n)){let n=Number(e),o=Qg(t);if(o<0||o>=a)continue;h.set(o,(h.get(o)??0)+1);let v=!1;if(g&&(g.include&&g.include.length>0&&!g.include.includes(n)&&(v=!0),g.exclude&&g.exclude.length>0&&g.exclude.includes(n)&&(v=!0),g.predicate)){let{segments:e}=e_(_.geoRef,o),t=n_({smid:n,box:t_(r.geometry,e),triangles:0,floorHeight:this._getLayerFloorHeight()});g.predicate({...t,smid:n})||(v=!0)}if(v){s.add(o);continue}if(this.fieldFilter){let e=this.fieldFilter.matched.has(n);if(this.fieldFilter.mode===`keep`?!e:e){s.add(o);continue}}let y=i.get(n);if(y?.hidden){s.add(o);continue}let b=y?.opacity;if(b!=null){if(b<=0){s.add(o);continue}b<1&&!m.has(o)&&m.set(o,b)}let x=y?.color??this.thematicColors.get(n);x&&!c.has(o)&&c.set(o,x);let S=y?.elevation??this.thematicElevation.get(n);if(S!=null&&!l.has(o)&&l.set(o,S),y?.translation&&!u.has(o)&&u.set(o,y.translation),y?.rotation!=null&&!d.has(o)){let e=Xx(y.rotation);e&&d.set(o,e)}y?.pivot&&!f.has(o)&&f.set(o,y.pivot),y?.gpuPath&&!p.has(o)&&p.set(o,y.gpuPath)}for(let t of s)e[t*4+3]=-1,o=!0;let v=new W;for(let[t,n]of c)s.has(t)||(v.set(n),e[t*4+0]=v.r,e[t*4+1]=v.g,e[t*4+2]=v.b,o=!0);for(let[t,n]of l){if(s.has(t))continue;e[t*4+3]=n;let r=(a+t)*4;e[r+2]=n,o=!0}for(let[t,n]of u){if(s.has(t))continue;let r=(a+t)*4;e[r+0]=n[0],e[r+1]=n[1],e[r+2]=n[2]+(l.get(t)??0),o=!0}let y=!1;for(let[t,n]of m)s.has(t)||(e[(a+t)*4+3]=n,o=!0,y=!0);for(let[t,n]of d){if(s.has(t))continue;let r=f.get(t)??[0,0,0],i=(a*2+t)*4;e[i+0]=n[0],e[i+1]=n[1],e[i+2]=n[2],e[i+3]=r[0];let c=(a*3+t)*4;e[c+0]=n[3],e[c+1]=n[4],e[c+2]=n[5],e[c+3]=r[1];let l=(a*4+t)*4;e[l+0]=n[6],e[l+1]=n[7],e[l+2]=n[8],e[l+3]=r[2],o=!0}for(let[t,n]of f)d.has(t)||s.has(t)||(e[(a*2+t)*4+3]=n[0],e[(a*3+t)*4+3]=n[1],e[(a*4+t)*4+3]=n[2],o=!0);for(let[t,n]of p){if(s.has(t))continue;let r=(a*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,o=!0}let b=0;for(let[e,t]of h)t<2||(s.has(e)||c.has(e)||l.has(e)||d.has(e)||p.has(e))&&b++;return{hasActive:o,hasFade:y,conflicts:b}}applyOverridesToMesh(e){let t=Qx(e);if(!t)return;let n=e.userData.geoRef?.pickInfo,r=this.featureStyles.size>0||this.thematicColors.size>0||this.thematicElevation.size>0,i=this.filter,a=this.fieldFilter!=null||i!=null&&((i.include?.length??0)>0||(i.exclude?.length??0)>0||i.predicate!=null);if(!r&&!a||!n||Object.keys(n).length===0){t.userData.uBatchTexActive&&(t.userData.uBatchTexActive.value=0),t.transparent&&!this._isLayerTransparent()&&(t.transparent=!1);return}let o=0;for(let e of Object.values(n)){let t=Qg(e);t>o&&(o=t)}let s=Math.max(o+1,1),c=this._meshBatchTextures.get(e);if(!c||c.width<s){let n=new Float32Array(s*6*4),r=new Cu(n,s,6,ci,ei);r.minFilter=Rr,r.magFilter=Rr,c={texture:r,data:n,width:s},this._meshBatchTextures.set(e,c),t.userData.uBatchTex.value=r,t.userData.uBatchTexWidth.value=s}let{data:l,texture:u}=c,{hasActive:d,hasFade:f,conflicts:p}=this._bakeStylesIntoBuffer(l,c.width,n,e,this.featureStyles);f&&!t.transparent?t.transparent=!0:!f&&t.transparent&&!this._isLayerTransparent()&&(t.transparent=!1),p>0&&!this._batchConflictWarned&&(this._batchConflictWarned=!0,console.warn(`[s3m] 有 ${p} 个单体状态写不进独立的 batch(多个 SMID 共用同一个 batchId,\n S3M 的单体化粒度只到 batch,无法单独隐藏/改色其中一部分)。
4740
+ `;function Vx(e,t={},n,r){let i=n??{uColor:{value:new W(t.color??`#ffffff`)},uOpacity:{value:t.opacity??1},uWidth:{value:t.width??1.5},uElevation:{value:t.elevation??0}};t.color!==void 0&&n&&i.uColor.value.set(t.color),t.opacity!==void 0&&n&&(i.uOpacity.value=t.opacity),t.width!==void 0&&n&&(i.uWidth.value=t.width);let a={uBatchTex:r?.uBatchTex??{value:Uy},uBatchTex2:r?.uBatchTex2??{value:Uy},uBatchMix:r?.uBatchMix??{value:0},uBatchTexWidth:r?.uBatchTexWidth??{value:1},uBatchTexActive:r?.uBatchTexActive??{value:0},uPathTex:r?.uPathTex??{value:My.DUMMY_PATH_TEX},uPathCount:r?.uPathCount??{value:1},uPathTexActive:r?.uPathTexActive??{value:0},uPathTime:r?.uPathTime??{value:0}},o=new gc({uniforms:{uResolution:e.uResolution,uDpr:e.uDpr,uColor:i.uColor,uOpacity:i.uOpacity,uWidth:i.uWidth,uElevation:i.uElevation??{value:t.elevation??0},uTranslation:{value:new H(0,0,0)},uBatchTex:a.uBatchTex,uBatchTex2:a.uBatchTex2,uBatchMix:a.uBatchMix,uBatchTexWidth:a.uBatchTexWidth,uBatchTexActive:a.uBatchTexActive,uPathTex:a.uPathTex,uPathCount:a.uPathCount,uPathTexActive:a.uPathTexActive,uPathTime:a.uPathTime},vertexShader:zx,fragmentShader:Bx,transparent:!0,depthWrite:!1,side:2,polygonOffset:!0,polygonOffsetFactor:-2,polygonOffsetUnits:-2});return o.userData.isThickLine=!0,o}function Hx(e,t){let n=Math.floor(e.length/6),r=n*4,i=new Float32Array(r*3),a=new Float32Array(r*3),o=new Float32Array(r),s=new Float32Array(r),c=r>65535?new Uint32Array(n*6):new Uint16Array(n*6);for(let r=0;r<n;r++){let n=r*6,i=e[n],a=e[n+1],o=e[n+2],u=e[n+3],d=e[n+4],f=e[n+5],p=t?Number(t[r]??-1):-1,m=r*4;l(m,i,a,o,u,d,f,-1),l(m+1,i,a,o,u,d,f,1),l(m+2,u,d,f,i,a,o,1),l(m+3,u,d,f,i,a,o,-1);for(let e=0;e<4;e++)s[m+e]=p;let h=r*6;c[h]=m,c[h+1]=m+1,c[h+2]=m+2,c[h+3]=m,c[h+4]=m+2,c[h+5]=m+3}function l(e,t,n,r,s,c,l,u){let d=e*3;i[d]=t,i[d+1]=n,i[d+2]=r,a[d]=s,a[d+1]=c,a[d+2]=l,o[e]=u}let u=new q;return u.setAttribute(`position`,new G(i,3)),u.setAttribute(`aOther`,new G(a,3)),u.setAttribute(`aSide`,new G(o,1)),u.setAttribute(`aBatchId`,new G(s,1)),u.setIndex(new G(c,1)),u.computeBoundingSphere(),u}function Ux(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=Wx(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 Wx(e,t,n,r){return`${Math.round(e*r)},${Math.round(t*r)},${Math.round(n*r)}`}var Gx=6e4,Kx=100;function qx(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]*Kx)},${Math.round(o[n]*Kx)},${Math.round(s[n]*Kx)}`,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>=Gx*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}rh();function Jx(e,t,n,r){return`${Math.round(e*r)},${Math.round(t*r)},${Math.round(n*r)}`}function Yx(e,t){let n=e.getAttribute(`position`);if(!n||n.count===0)return e;let r=1/Math.max(t,1e-9),i=new Map,a=[],o=new Int32Array(n.count);for(let e=0;e<n.count;e++){let t=n.getX(e),s=n.getY(e),c=n.getZ(e),l=Jx(t,s,c,r),u=i.get(l);u===void 0&&(u=a.length/3,a.push(t,s,c),i.set(l,u)),o[e]=u}let s=e.getIndex(),c=s?s.count:n.count,l=new Uint32Array(c);for(let e=0;e<c;e++)l[e]=o[s?s.getX(e):e];let u=new q;return u.setAttribute(`position`,new K(a,3)),u.setIndex(new G(l,1)),u}rh(),uh();var Xx=class{constructor(){X(this,`datasets`,new Map),X(this,`sceneAnchor`,null),X(this,`totalMaxTiles`,0)}get(e){return this.datasets.get(e)}values(){return this.datasets.values()}registerDataset(e){let t=this.datasets.get(e.id);if(t)return t;let n=new Ml;n.name=`s3m-dataset:${e.id}`,n.visible=e.visible!==!1;let r={id:e.id,name:e.name??e.id,options:e,root:n,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,r),this.rebalanceBudgets(),r}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,t,n,r,i,a,o,s,c){let l=this.datasets.get(e.id);if(l)return l;let u=new Ml;u.name=`s3m-dataset:${e.id}`,u.visible=e.visible!==!1,t.add(u);let d={id:e.id,name:e.name??e.id,options:e,root:u,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,d);let f=new Wb({configUrl:e.configUrl,maxTiles:e.maxTiles??o,maxConcurrent:s,lodRangeScale:e.lodRangeScale??i,buildTile:a??null,useWorker:e.useWorker,uniforms:r,onTile:e=>{c.onTile(e,d)},onTileRemoved:e=>{c.onTileRemoved(e,d)},onProgress:()=>{c.onStats(),c.triggerRepaint()},onError:e=>{d.error=e,c.onError(e),c.onStats()}});d.tileset=f,this.rebalanceBudgets();try{await f.init()}catch(e){return d.error=e,c.onError(e),d}return d.anchor=f.anchor,d.baseAlignOffset=this.computeAlignOffset(f,e.align),d.userOffset=e.heightOffset??0,d.heightOffset=d.baseAlignOffset+d.userOffset,this.layoutDataset(d,n),c.onReady(d),c.triggerRepaint(),d}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=m_(t,e.anchor.lon,e.anchor.lat,e.anchor.height??0));let n=this.sceneAnchor.meterInMercator,r=m_(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=Vb(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}};rh(),a_(),uh();function Zx(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 t=new Xo(e[0],e[1],e[2]),n=new U().makeRotationFromEuler(t).elements;return[n[0],n[4],n[8],n[1],n[5],n[9],n[2],n[6],n[10]]}if(e.length===4){let t=new fo(e[0],e[1],e[2],e[3]),n=new U().makeRotationFromQuaternion(t).elements;return[n[0],n[4],n[8],n[1],n[5],n[9],n[2],n[6],n[10]]}}if(e instanceof Xo){let t=new U().makeRotationFromEuler(e).elements;return[t[0],t[4],t[8],t[1],t[5],t[9],t[2],t[6],t[10]]}if(e instanceof fo){let t=new U().makeRotationFromQuaternion(e).elements;return[t[0],t[4],t[8],t[1],t[5],t[9],t[2],t[6],t[10]]}if(e instanceof V){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 U){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 Qx(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 t=new fo(e[0],e[1],e[2],e[3]),n=new Xo().setFromQuaternion(t);return[n.x,n.y,n.z]}}if(e instanceof Xo)return[e.x,e.y,e.z];if(e instanceof fo){let t=new Xo().setFromQuaternion(e);return[t.x,t.y,t.z]}if(e instanceof V){let t=new U().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),n=new Xo().setFromRotationMatrix(t);return[n.x,n.y,n.z]}if(e instanceof U){let t=new Xo().setFromRotationMatrix(e);return[t.x,t.y,t.z]}return[0,0,0]}function $x(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function eS(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 tS(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 nS(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 rS=class{constructor(e,t,n,r,i,a=()=>!1){X(this,`_getLayerFloorHeight`,void 0),X(this,`_triggerRepaint`,void 0),X(this,`_onStyleChanged`,void 0),X(this,`_getAllMeshes`,void 0),X(this,`_applyOverrideHook`,void 0),X(this,`_isLayerTransparent`,void 0),X(this,`featureStyles`,new Map),X(this,`thematicColors`,new Map),X(this,`thematicElevation`,new Map),X(this,`thematicField`,null),X(this,`elevationField`,null),X(this,`filter`,null),X(this,`fieldFilter`,null),X(this,`_meshBatchTextures`,new WeakMap),X(this,`_markedMeshes`,new Set),X(this,`_dirtyAll`,!1),X(this,`_flushScheduled`,!1),X(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,t,n){if(!t)throw Error(`[s3m] 未配置业务属性数据源,先调用 setAttributeSource() 或构造时传 attributes`);let r=e.smids?.length?[...new Set(e.smids)]:n;if(!r.length)return this.clearThematicColors(),{field:e.field,type:`discrete`,matched:0,missing:0,legend:[]};let i=await t.queryBySmids(r),a=[],o=[];for(let t of r){let n=i.get(t),r=n?n[e.field]:void 0;if(r==null||r===``)continue;let s=Number(r);Number.isFinite(s)?a.push({smid:t,val:s}):o.push({smid:t,val:String(r)})}let s=a.length>=o.length&&a.length>0,c=new Map,l=[],u=e.defaultColor??`#64748b`,d=e.nullColor??`#334155`;if(s){let t=a.map(e=>e.val),n=Math.min(...t),r=Math.max(...t)-n||1,i=(e.ramp??[`#3b82f6`,`#10b981`,`#f59e0b`,`#ef4444`]).map(e=>new W(e)),o=Math.max(2,e.stops??5);for(let e=0;e<o;e++){let t=e/o,a=(e+1)/o,s=eS(i,(t+a)/2),c=n+t*r,u=n+a*r;l.push({color:`#${s.getHexString()}`,label:`${nS(c)} ~ ${nS(u)}`,count:0,min:c,max:u})}for(let{smid:e,val:t}of a){let i=Math.min(1,Math.max(0,(t-n)/r)),a=Math.min(o-1,Math.floor(i*o)),s=l[a].color;c.set(e,s),l[a].count++}}else{let t=new Map;for(let{val:e}of o)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];l.push({color:o,label:t,count:a})}let a=new Map(l.map(e=>[e.label,e.color]));for(let{smid:e,val:t}of o)c.set(e,a.get(t)??u)}let f=0;for(let e of r)c.has(e)||(c.set(e,d),f++);return f>0&&l.push({color:d,label:`无数据 / 缺失`,count:f}),this.setThematicColors(c,e.field),{field:e.field,type:s?`continuous`:`discrete`,matched:r.length-f,missing:f,legend:l}}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?tS(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=Qg(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,t,n,r,i){let a=t;for(let t=0;t<a;t++){e[t*4+0]=-1,e[t*4+1]=-1,e[t*4+2]=-1,e[t*4+3]=0;let n=(a+t)*4;e[n+0]=0,e[n+1]=0,e[n+2]=0,e[n+3]=0;let r=(a*2+t)*4;e[r+0]=1,e[r+1]=0,e[r+2]=0,e[r+3]=0;let i=(a*3+t)*4;e[i+0]=0,e[i+1]=1,e[i+2]=0,e[i+3]=0;let o=(a*4+t)*4;e[o+0]=0,e[o+1]=0,e[o+2]=1,e[o+3]=0;let s=(a*5+t)*4;e[s+0]=-1,e[s+1]=0,e[s+2]=0,e[s+3]=0}let o=!1,s=new Set,c=new Map,l=new Map,u=new Map,d=new Map,f=new Map,p=new Map,m=new Map,h=new Map,g=this.filter,_=r.userData;for(let[e,t]of Object.entries(n)){let n=Number(e),o=Qg(t);if(o<0||o>=a)continue;h.set(o,(h.get(o)??0)+1);let v=!1;if(g&&(g.include&&g.include.length>0&&!g.include.includes(n)&&(v=!0),g.exclude&&g.exclude.length>0&&g.exclude.includes(n)&&(v=!0),g.predicate)){let{segments:e}=e_(_.geoRef,o),t=n_({smid:n,box:t_(r.geometry,e),triangles:0,floorHeight:this._getLayerFloorHeight()});g.predicate({...t,smid:n})||(v=!0)}if(v){s.add(o);continue}if(this.fieldFilter){let e=this.fieldFilter.matched.has(n);if(this.fieldFilter.mode===`keep`?!e:e){s.add(o);continue}}let y=i.get(n);if(y?.hidden){s.add(o);continue}let b=y?.opacity;if(b!=null){if(b<=0){s.add(o);continue}b<1&&!m.has(o)&&m.set(o,b)}let x=y?.color??this.thematicColors.get(n);x&&!c.has(o)&&c.set(o,x);let S=y?.elevation??this.thematicElevation.get(n);if(S!=null&&!l.has(o)&&l.set(o,S),y?.translation&&!u.has(o)&&u.set(o,y.translation),y?.rotation!=null&&!d.has(o)){let e=Zx(y.rotation);e&&d.set(o,e)}y?.pivot&&!f.has(o)&&f.set(o,y.pivot),y?.gpuPath&&!p.has(o)&&p.set(o,y.gpuPath)}for(let t of s)e[t*4+3]=-1,o=!0;let v=new W;for(let[t,n]of c)s.has(t)||(v.set(n),e[t*4+0]=v.r,e[t*4+1]=v.g,e[t*4+2]=v.b,o=!0);for(let[t,n]of l){if(s.has(t))continue;e[t*4+3]=n;let r=(a+t)*4;e[r+2]=n,o=!0}for(let[t,n]of u){if(s.has(t))continue;let r=(a+t)*4;e[r+0]=n[0],e[r+1]=n[1],e[r+2]=n[2]+(l.get(t)??0),o=!0}let y=!1;for(let[t,n]of m)s.has(t)||(e[(a+t)*4+3]=n,o=!0,y=!0);for(let[t,n]of d){if(s.has(t))continue;let r=f.get(t)??[0,0,0],i=(a*2+t)*4;e[i+0]=n[0],e[i+1]=n[1],e[i+2]=n[2],e[i+3]=r[0];let c=(a*3+t)*4;e[c+0]=n[3],e[c+1]=n[4],e[c+2]=n[5],e[c+3]=r[1];let l=(a*4+t)*4;e[l+0]=n[6],e[l+1]=n[7],e[l+2]=n[8],e[l+3]=r[2],o=!0}for(let[t,n]of f)d.has(t)||s.has(t)||(e[(a*2+t)*4+3]=n[0],e[(a*3+t)*4+3]=n[1],e[(a*4+t)*4+3]=n[2],o=!0);for(let[t,n]of p){if(s.has(t))continue;let r=(a*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,o=!0}let b=0;for(let[e,t]of h)t<2||(s.has(e)||c.has(e)||l.has(e)||d.has(e)||p.has(e))&&b++;return{hasActive:o,hasFade:y,conflicts:b}}applyOverridesToMesh(e){let t=$x(e);if(!t)return;let n=e.userData.geoRef?.pickInfo,r=this.featureStyles.size>0||this.thematicColors.size>0||this.thematicElevation.size>0,i=this.filter,a=this.fieldFilter!=null||i!=null&&((i.include?.length??0)>0||(i.exclude?.length??0)>0||i.predicate!=null);if(!r&&!a||!n||Object.keys(n).length===0){t.userData.uBatchTexActive&&(t.userData.uBatchTexActive.value=0),t.transparent&&!this._isLayerTransparent()&&(t.transparent=!1);return}let o=0;for(let e of Object.values(n)){let t=Qg(e);t>o&&(o=t)}let s=Math.max(o+1,1),c=this._meshBatchTextures.get(e);if(!c||c.width<s){let n=new Float32Array(s*6*4),r=new Cu(n,s,6,ci,ei);r.minFilter=Rr,r.magFilter=Rr,c={texture:r,data:n,width:s},this._meshBatchTextures.set(e,c),t.userData.uBatchTex.value=r,t.userData.uBatchTexWidth.value=s}let{data:l,texture:u}=c,{hasActive:d,hasFade:f,conflicts:p}=this._bakeStylesIntoBuffer(l,c.width,n,e,this.featureStyles);f&&!t.transparent?t.transparent=!0:!f&&t.transparent&&!this._isLayerTransparent()&&(t.transparent=!1),p>0&&!this._batchConflictWarned&&(this._batchConflictWarned=!0,console.warn(`[s3m] 有 ${p} 个单体状态写不进独立的 batch(多个 SMID 共用同一个 batchId,\n S3M 的单体化粒度只到 batch,无法单独隐藏/改色其中一部分)。
4659
4741
  当前规则:任一 SMID 需要隐藏则整批隐藏,颜色 / 抬高取首个。
4660
- 用 layer.auditBatches() 可以列出具体是哪些 SMID 共用了 batchId。`)),u.needsUpdate=!0,t.userData.uBatchTexActive&&(t.userData.uBatchTexActive.value=+!!d)}prepareCrossFade(e,t){for(let n of t){let t=Qx(n);if(!t)continue;let r=n.userData.geoRef?.pickInfo;if(!r||Object.keys(r).length===0)continue;let i=0;for(let e of Object.values(r)){let t=Qg(e);t>i&&(i=t)}let a=Math.max(i+1,1),o=this._meshBatchTextures.get(n);if(!o||o.width<a){let e=new Float32Array(a*6*4),r=new Cu(e,a,6,ci,ei);r.minFilter=Rr,r.magFilter=Rr,o={texture:r,data:e,width:a},this._meshBatchTextures.set(n,o),t.userData.uBatchTex.value=r,t.userData.uBatchTexWidth.value=a}if(!o.texture2||!o.data2||o.data2.length<o.width*6*4){let e=new Float32Array(o.width*6*4),t=new Cu(e,o.width,6,ci,ei);t.minFilter=Rr,t.magFilter=Rr,o.data2=e,o.texture2=t}this._bakeStylesIntoBuffer(o.data,o.width,r,n,this.featureStyles),o.texture.needsUpdate=!0;let s=this._bakeStylesIntoBuffer(o.data2,o.width,r,n,e);o.texture2.needsUpdate=!0,t.userData.uBatchTex2.value=o.texture2,t.userData.uBatchTexActive.value=1,s.hasFade&&!t.transparent&&(t.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=Qx(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=Qx(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)}};rh(),uh();var rS=class{constructor(e={}){X(this,`mode`,void 0),X(this,`opacity`,void 0),X(this,`color`,void 0),X(this,`gridColor`,void 0),X(this,`gridSize`,void 0),X(this,`excavationBounds`,null),X(this,`size`,void 0),X(this,`groundHeight`,0),X(this,`occlude`,void 0),X(this,`trackHeight`,void 0),X(this,`group`,void 0),X(this,`_mesh`,null),X(this,`_material`,null),X(this,`_depthMesh`,null),X(this,`_depthMaterial`,null),X(this,`_geom`,null),X(this,`_occludeExplicit`,void 0),this.mode=e.mode??`none`,this.opacity=e.opacity??.62,this.color=new W(e.color??`#0f172a`),this.gridColor=new W(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 Ml,this.group.name=`s3m-ground-surface`,this._initMesh(),this._applyMode()}_initMesh(){let e=new Pc(this.size,this.size,1,1);this._geom=e;let t=new gc({transparent:!0,depthTest:!0,depthWrite:!1,side:2,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 B(-9999,-9999)},uExcavationMax:{value:new B(9999,9999)}},vertexShader:`
4742
+ 用 layer.auditBatches() 可以列出具体是哪些 SMID 共用了 batchId。`)),u.needsUpdate=!0,t.userData.uBatchTexActive&&(t.userData.uBatchTexActive.value=+!!d)}prepareCrossFade(e,t){for(let n of t){let t=$x(n);if(!t)continue;let r=n.userData.geoRef?.pickInfo;if(!r||Object.keys(r).length===0)continue;let i=0;for(let e of Object.values(r)){let t=Qg(e);t>i&&(i=t)}let a=Math.max(i+1,1),o=this._meshBatchTextures.get(n);if(!o||o.width<a){let e=new Float32Array(a*6*4),r=new Cu(e,a,6,ci,ei);r.minFilter=Rr,r.magFilter=Rr,o={texture:r,data:e,width:a},this._meshBatchTextures.set(n,o),t.userData.uBatchTex.value=r,t.userData.uBatchTexWidth.value=a}if(!o.texture2||!o.data2||o.data2.length<o.width*6*4){let e=new Float32Array(o.width*6*4),t=new Cu(e,o.width,6,ci,ei);t.minFilter=Rr,t.magFilter=Rr,o.data2=e,o.texture2=t}this._bakeStylesIntoBuffer(o.data,o.width,r,n,this.featureStyles),o.texture.needsUpdate=!0;let s=this._bakeStylesIntoBuffer(o.data2,o.width,r,n,e);o.texture2.needsUpdate=!0,t.userData.uBatchTex2.value=o.texture2,t.userData.uBatchTexActive.value=1,s.hasFade&&!t.transparent&&(t.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=$x(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=$x(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)}};rh(),uh();var iS=class{constructor(e={}){X(this,`mode`,void 0),X(this,`opacity`,void 0),X(this,`color`,void 0),X(this,`gridColor`,void 0),X(this,`gridSize`,void 0),X(this,`excavationBounds`,null),X(this,`size`,void 0),X(this,`groundHeight`,0),X(this,`occlude`,void 0),X(this,`trackHeight`,void 0),X(this,`group`,void 0),X(this,`_mesh`,null),X(this,`_material`,null),X(this,`_depthMesh`,null),X(this,`_depthMaterial`,null),X(this,`_geom`,null),X(this,`_occludeExplicit`,void 0),this.mode=e.mode??`none`,this.opacity=e.opacity??.62,this.color=new W(e.color??`#0f172a`),this.gridColor=new W(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 Ml,this.group.name=`s3m-ground-surface`,this._initMesh(),this._applyMode()}_initMesh(){let e=new Pc(this.size,this.size,1,1);this._geom=e;let t=new gc({transparent:!0,depthTest:!0,depthWrite:!1,side:2,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 B(-9999,-9999)},uExcavationMax:{value:new B(9999,9999)}},vertexShader:`
4661
4743
  varying vec2 vEnuPos;
4662
4744
  void main() {
4663
4745
  vec4 worldPos = modelMatrix * vec4(position, 1.0);
@@ -4735,4 +4817,4 @@ void main() {
4735
4817
  }
4736
4818
  gl_FragColor = vec4(1.0);
4737
4819
  }
4738
- `}),i=new dc(e,r);i.position.set(0,0,-.02),i.renderOrder=-1e3,i.name=`s3m-ground-depth`,i.visible=!1,this.group.add(i),this._depthMesh=i,this._depthMaterial=r,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()}};rh(),Oy(),eb(),Ay(),Ny(),a_(),uh();var iS=65534;function aS(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function oS(e){return e.isPoints===!0}var sS=[`opacity`,`floorHeight`,`selectOpacity`,`selectEmissive`,`selectElevation`,`dimFactor`,`texMix`,`roofThreshold`,`ambientGain`,`edgeWidth`,`edgeOpacity`,`outlineWidth`],cS=[`colorA`,`colorB`,`colorC`,`selectColor`,`edgeColor`],lS=[`translation`,`elevation`,`opacity`,`color`,`rotation`],uS=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={}){X(this,`options`,void 0),X(this,`pickable`,void 0),X(this,`onStats`,void 0),X(this,`onReady`,void 0),X(this,`onPick`,void 0),X(this,`onError`,void 0),X(this,`geo`,null),X(this,`canvas`,null),X(this,`renderer`,null),X(this,`scene`,null),X(this,`camera`,null),X(this,`picker`,null),X(this,`uniforms`,void 0),X(this,`style`,void 0),X(this,`_styleTarget`,void 0),X(this,`outlineMaterial`,void 0),X(this,`lineShared`,void 0),X(this,`edgeMaterial`,void 0),X(this,`selectionEdgeMaterial`,void 0),X(this,`_edgeStyleUniforms`,void 0),X(this,`_selEdgeStyleUniforms`,void 0),X(this,`groundManager`,void 0),X(this,`_datasetManager`,new Yx),X(this,`_featureStyleManager`,void 0),X(this,`gpuPathManager`,new My),X(this,`_customPathTime`,!1),X(this,`_pickables`,new Map),X(this,`_pickSeq`,0),X(this,`_freePickIds`,[]),X(this,`_smidMeshes`,new Map),X(this,`_meshHeight`,new Map),X(this,`_heightMin`,1/0),X(this,`_heightMax`,-1/0),X(this,`_boxScratch`,new ho),X(this,`_selection`,null),X(this,`_selectedMeshes`,[]),X(this,`_outlineMesh`,null),X(this,`_outlineMeshes`,[]),X(this,`_selectionEdges`,null),X(this,`_selectionEdgeMeshes`,[]),X(this,`_edgesEnabled`,!1),X(this,`_tileFadeSeq`,0),X(this,`_modeGen`,0),X(this,`_pathSpecs`,new Map),X(this,`_pathScratch`,new Float32Array(3)),X(this,`_creaseLines`,null),X(this,`_nativeEdgeLines`,new Set),X(this,`_pointClouds`,new Set),X(this,`_opacityTransparent`,!1),X(this,`animator`,new Ix),X(this,`attributeQuery`,null),X(this,`_enuMatrix`,new U),X(this,`_colorScratch`,new W),X(this,`_needsRepaint`,!0),X(this,`_frame`,0),X(this,`_fps`,{value:0,last:0}),X(this,`_ambientLight`,void 0),X(this,`_hemiLight`,void 0),X(this,`_keyLight`,void 0),X(this,`_fillLight`,void 0),X(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}),X(this,`_datasetQueue`,void 0),X(this,`_onRequestRepaint`,()=>{}),X(this,`_getBearing`,void 0),X(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 rS(e.ground),this.scene||(this.scene=new Wl,this.scene.add(this.groundManager.group),this._addLights()),this._featureStyleManager=new nS(()=>this.style.floorHeight,()=>this._requestRepaint(),()=>{this._selection&&this._syncSelectionStyle()},()=>this.getAllMeshes(),e=>this._applyOverridesToMesh(e),()=>this._opacityTransparent),this.uniforms=Py(),by(b_),this.style={...Vy,...e.style??{}},this._styleTarget={...this.style},this._opacityTransparent=(this.style.opacity??1)<.999,this._applyStyleUniforms(),this._registerAnimChannels(),this.animator.onActive=()=>this._requestRepaint(),this.outlineMaterial=Iy(this.uniforms),this.lineShared=Lx(),this._edgeStyleUniforms={uColor:{value:new W(this.style.edgeColor)},uWidth:{value:Math.max(.1,this.style.edgeWidth??1.5)},uOpacity:{value:.6}},this.edgeMaterial=Bx(this.lineShared,{},this._edgeStyleUniforms),this._selEdgeStyleUniforms={uColor:{value:new W(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=Bx(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 u_(e.attributes))}_createRenderer(e,t){let n=new Vl({canvas:e,context:t,antialias:!0});return n.autoClear=!1,n.setPixelRatio(1),n.toneMapping=this.options.toneMapping===void 0?0:this.options.toneMapping,n.toneMappingExposure=this.options.toneMappingExposure??1,n}_syncTextureCapabilities(e){let t=!!e.getExtension(`WEBGL_compressed_texture_s3tc`),n=!!e.getExtension(`WEBGL_compressed_texture_s3tc_srgb`);yy(t&&n)}mount(e,t){this.canvas=e,this.renderer=this._createRenderer(e,t),vy(this.renderer.capabilities.getMaxAnisotropy()),this._syncTextureCapabilities(t),this.scene=new Wl,this.scene.add(this.groundManager.group),this._addLights(),this.camera=new _c,this.camera.matrixAutoUpdate=!1,this.picker=new ix(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),vy(this.renderer.capabilities.getMaxAnisotropy()),this._syncTextureCapabilities(e),this.picker?.dispose(),this.picker=new ix(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 mp(this._lightOptions.ambientColor,this._lightOptions.ambientIntensity),this._hemiLight=new ep(this._lightOptions.hemisphereColor,this._lightOptions.hemisphereGroundColor,this._lightOptions.hemisphereIntensity),this._keyLight=new pp(this._lightOptions.keyLightColor,this._lightOptions.keyLightIntensity),this._fillLight=new pp(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??0,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 h_(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=Zx(t),o=this._ensureFeatureChannel(e,`rotation`);this.animator.to(o,a,r)}rotateFeatureBy(e,t,n,r){let i=Zx(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 ky?t:new ky(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=Zx(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=Zx(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 lS)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 u_(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=aS(t);r&&r.dispose(),Qb(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=oS(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=aS(a);if(e){e.transparent=Math.min(1,Math.max(.05,this.style.opacity??1))<.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,t){if(!t.point)return!1;let n=e.geometry;if(!n||(n.boundingBox||n.computeBoundingBox(),!n.boundingBox))return!1;let r=new H(t.point[0],t.point[1],t.point[2]);e.updateWorldMatrix(!0,!1);let i=e.matrixWorld.clone().invert(),a=r.applyMatrix4(i);return n.boundingBox.clone().expandByScalar(.5).containsPoint(a)}_replaySelectionOnto(e){let t=this._selection;if(!t)return;let n=aS(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?Qg(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),oS(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),oS(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),aS(t)?.dispose?.()}Qb(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>iS){for(let e=0;e<=iS;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:Ry[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 cS.includes(e)?3:1}_registerAnimChannels(){for(let e of sS)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 cS)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??zy.OVERLAY;e.uSelMode&&(e.uSelMode.value=n===zy.REPLACE?0:n===zy.MULTIPLY?2:n===zy.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=Math.min(1,Math.max(.05,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=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(oS(n.mesh))continue;let r=aS(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)){Zb(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=aS(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&&!oS(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 t=await fetch(e);if(!t.ok)throw Error(`[s3m] 棱线缓存加载失败: ${t.status} ${e}`);let n=await t.arrayBuffer(),r=new Float32Array(n);if(r.length<6)return;let i=new q;i.setAttribute(`position`,new G(r,3));let a=this.style,o=new Qu({color:new W(a.edgeColor),transparent:!0,opacity:Math.min(1,Math.max(0,a.edgeOpacity??.6))*Math.min(1,Math.max(.05,a.opacity??1)),depthWrite:!1}),s=new ld(i,o);s.renderOrder=2,s.frustumCulled=!1,s.raycast=()=>{},this.clearCreases(),this._creaseLines=s,this.scene?.add(s),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 t=e.userData;if(t.edges||t.nativeEdges||!e.geometry||this._shouldSkipAutoEdges(t,``))return;let n=e.geometry.getAttribute(`position`);if((e.geometry.index?.count??(n?n.count:0))>12e4)return;let r=Jx(e.geometry,.005),i=this.style.edgeThreshold??55,a=new Qd(r,i);r.dispose();let o=a.getAttribute(`position`),s=o?o.array:null;if(a.dispose(),!s||s.length<6)return;let c=.005,l=Hx(e.geometry,c),u;if(l){let e=s.length/6;u=new Float32Array(e);for(let t=0;t<e;t++){let e=t*6;u[t]=l.get(Ux(s[e],s[e+1],s[e+2],1/c))??-1}}let d=new dc(Vx(s,u),this._createEdgeMaterial(e));d.renderOrder=2,d.frustumCulled=!1,d.raycast=()=>{},d.userData.isThickEdge=!0,t.edges=d,e.add(d)}_createEdgeMaterial(e){let t=aS(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 Bx(this.lineShared,{},this._edgeStyleUniforms,n)}_createSelectionEdgeMaterial(e){let t=aS(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 Bx(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,t){if(!this.camera||!this.canvas)return null;let n=this.canvas,r=n.clientWidth||n.width,i=n.clientHeight||n.height;if(!r||!i)return null;let a=e/r*2-1,o=-(t/i)*2+1,s=new H(a,o,-1).unproject(this.camera),c=new H(a,o,1).unproject(this.camera).clone().sub(s).normalize();return new Bo(s,c)}_intersectMeshAtRay(e,t,n){let r=new gm;r.ray.copy(t);let i=r.intersectObject(e,!1);if(!i.length)return null;if(n!=null){let e=i.find(e=>e.instanceId===n);return e?e.point:i[0].point}return i[0].point}_buildPickResult(e,t,n,r){let i=t.mesh.userData,a=null,o=e.batchId,s=e.instanceIndex,c=i.geoRef,l=[];if(s!=null){let e=this._instanceFeature(t.mesh,c,s);if(!e)return null;a=e.smid,o=e.batchId}else{c=i.geoByBatchId?.get(e.batchId)??i.geoRef;let t=e_(c,e.batchId);a=t.smid,l=t.segments}if(this._isFeatureHidden(a,o))return null;let u=null,d=0;if(s!=null)u=this._instanceBox(t.mesh,s),d=t.mesh.geometry.index?Math.round(t.mesh.geometry.index.count/3):0;else if(a!=null&&this._smidMeshes.has(a)){let e=this._smidMeshes.get(a),t=1/0,n=1/0,r=1/0,i=-1/0,o=-1/0,s=-1/0,c=0;for(let l of e){let e=l.userData,u=e.geoRef?.pickInfo,f=u?.[a]??u?.[String(a)],p=f?Qg(f):-1,m=f?.segments??(p>=0?e_(e.geoRef,p).segments:[]),h=t_(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>o&&(o=h.maxY),h.maxZ>s&&(s=h.maxZ),c+=h.count,d+=h.triangles)}c>0&&(u={minX:t,minY:n,minZ:r,maxX:i,maxY:o,maxZ:s,count:c,triangles:d})}if(!u&&(u=t_(t.mesh.geometry,l),!u&&t.mesh.geometry)){t.mesh.geometry.boundingBox||t.mesh.geometry.computeBoundingBox();let e=t.mesh.geometry.boundingBox;e&&(u={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 f=t.mesh.geometry,p=d>0?d:f.index?Math.round(f.index.count/3):0,m=n_({smid:a,box:u,triangles:p,floorHeight:this.style.floorHeight}),h=null;if(u&&this.sceneAnchor){let e=new H((u.minX+u.maxX)/2,(u.minY+u.maxY)/2,(u.minZ+u.maxZ)/2);e.applyMatrix4(t.mesh.matrixWorld);let n=this.sceneAnchor.meterInMercator;h=this._lngLatFromWorld(e.x*n+this.sceneAnchor.x,-e.y*n+this.sceneAnchor.y)}let g=n??null;!g&&r&&(g=this._intersectMeshAtRay(t.mesh,r,s));let _=null,v=null,y=null;if(g&&this.sceneAnchor){let e=a==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(a),t=e.translation,n=e.elevation,r=g.clone();if(e.rotation){let t=Xx(e.rotation);if(t){let n=new V().set(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]),i=e.pivot?new H(e.pivot[0],e.pivot[1],e.pivot[2]):new H(0,0,0);r.sub(i).applyMatrix3(n).add(i)}}t?r.add(new H(t[0],t[1],t[2])):n&&(r.z+=n),_=[r.x,r.y,r.z];let i=this.sceneAnchor.meterInMercator;v=this._lngLatFromWorld(r.x*i+this.sceneAnchor.x,-r.y*i+this.sceneAnchor.y),y=r.z+(this.sceneAnchor.altitude??0)}else h&&u&&this.sceneAnchor&&(v=h,y=(u.minZ+u.maxZ)/2+(this.sceneAnchor.altitude??0));return{datasetId:t.datasetId,datasetName:this.datasets.get(t.datasetId)?.name??t.datasetId,objectId:e.objectId,batchId:o,instanceIndex:s,skeletonName:t.skeletonName,centerLngLat:h,point:_,lngLat:v,altitude:y,...m,mesh:t.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,t){if(!this.camera||!this.sceneAnchor)return null;let n=this.pick(e,t);if(n?.point&&n?.lngLat&&n.altitude!=null)return{lngLat:n.lngLat,altitude:n.altitude,point:n.point};let r=this.getRayAt(e,t);if(!r)return null;let i=new Ac(new H(0,0,1),0),a=new H,o=r.intersectPlane(i,a);if(o){let e=this.sceneAnchor.meterInMercator;return{lngLat:this._lngLatFromWorld(o.x*e+this.sceneAnchor.x,-o.y*e+this.sceneAnchor.y),altitude:o.z+(this.sceneAnchor.altitude??0),point:[o.x,o.y,o.z]}}return null}drillPick(e,t,n=10){if(!this.sceneAnchor||!this.camera)return[];let r=this.getRayAt(e,t);if(!r)return[];let i=new gm;i.ray.copy(r);let a=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e;for(;t;){if(!t.visible)return!1;t=t.parent}return!0}),o=i.intersectObjects(a,!1);if(!o.length)return[];let s=[],c=new Set,l=new Set;for(let e of o){if(s.length>=n)break;let t=e.object,r=t.userData;if(r.pickId==null)continue;let i=this._pickables.get(r.pickId);if(!i)continue;let a=null,o=-1,u=e.instanceId;if(u!=null){let e=this._instanceFeature(t,r.geoRef,u);if(!e)continue;a=e.smid,o=e.batchId}else if(e.faceIndex!=null){let n=t.geometry.attributes.aBatchId;if(n){let i=t.geometry.index?t.geometry.index.getX(e.faceIndex*3):e.faceIndex*3;o=Math.round(n.getX(i)),a=e_(r.geoByBatchId?.get(o)??r.geoRef,o).smid}}if(a!=null){if(c.has(a))continue;c.add(a)}else{let e=`${r.pickId}:${o}:${u??-1}`;if(l.has(e))continue;l.add(e)}if(this._isFeatureHidden(a,o))continue;let d={objectId:r.pickId,batchId:o,instanceIndex:u},f=this._buildPickResult(d,i,e.point);f&&s.push(f)}return s}getFeatureBounds(e){if(!this.sceneAnchor)return null;let t=1/0,n=-1/0,r=1/0,i=-1/0,a=!1;for(let o of this._pickables.values()){let s=o.mesh,c=s.userData,l=c.geoRef,u=l?.pickInfo;if(!u)continue;let d=null;if(s.isInstancedMesh){let t=c.instanceLookup;t||(t=$g(u),c.instanceLookup=t);for(let[n,r]of t)if(r.smid===e){d=this._instanceBox(s,n);break}}else{let t=u,n=t[e]??t[String(e)];if(n){let e=e_(l,Qg(n));if(d=t_(s.geometry,e.segments),!d&&s.geometry){s.geometry.boundingBox||s.geometry.computeBoundingBox();let e=s.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})}}}if(d){a=!0;let o=[new H(d.minX,d.minY,d.minZ),new H(d.maxX,d.minY,d.minZ),new H(d.minX,d.maxY,d.minZ),new H(d.maxX,d.maxY,d.minZ),new H(d.minX,d.minY,d.maxZ),new H(d.maxX,d.minY,d.maxZ),new H(d.minX,d.maxY,d.maxZ),new H(d.maxX,d.maxY,d.maxZ)],c=e==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(e),l=c.translation,u=c.elevation,f=c.rotation?Xx(c.rotation):null,p=null,m=null;f&&(p=new V().set(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8]),m=c.pivot?new H(c.pivot[0],c.pivot[1],c.pivot[2]):new H(0,0,0));for(let e of o){p&&m&&e.sub(m).applyMatrix3(p).add(m),l?e.add(new H(l[0],l[1],l[2])):u&&(e.z+=u),e.applyMatrix4(s.matrixWorld);let a=this.sceneAnchor.meterInMercator,[o,c]=this._lngLatFromWorld(e.x*a+this.sceneAnchor.x,-e.y*a+this.sceneAnchor.y);o<t&&(t=o),o>n&&(n=o),c<r&&(r=c),c>i&&(i=c)}}}return a?[[t,r],[n,i]]:null}_instanceFeature(e,t,n){let r=e.userData;return r.instanceLookup||(r.instanceLookup=$g(t?.pickInfo)),r.instanceLookup.get(n)??null}_instanceBox(e,t){let n=e;if(!n.isInstancedMesh)return null;let r=e.geometry;r.boundingBox||r.computeBoundingBox();let i=r.boundingBox;if(!i)return null;let a=new U;n.getMatrixAt(t,a);let o=i.clone().applyMatrix4(a);return{minX:o.min.x,minY:o.min.y,minZ:o.min.z,maxX:o.max.x,maxY:o.max.y,maxZ:o.max.z,count:r.getAttribute(`position`)?.count??0,triangles:r.index?Math.round(r.index.count/3):0}}select(e,{silent:t=!1}={}){if(this._selection){for(let e of this._selectedMeshes){if(oS(e)){this._applyPointCloudStyle(e,!1);continue}let t=aS(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=aS(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?Qg(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)oS(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=>!oS(e));t.length&&((this.style.outlineStyle??`edges`)===`edges`?this._addSelectionEdges(e,t):this._addSelectionHull(e,t))}this._requestRepaint()}_addSelectionEdges(e,t){this._syncSelectionStyle();for(let n of t){let t=n.userData,r=t.geoRef,i=[],a=-1;if(n===e.mesh&&e.instanceIndex!=null){i=[{vertexOffset:0,vertexCount:n.geometry.getAttribute(`position`)?.count??0}];let t=r?.pickInfo,o=t?.[e.smid??``]??t?.[String(e.smid)];a=o?Qg(o):-1}else if(e.smid!=null){let t=r?.pickInfo,n=t?.[e.smid]??t?.[String(e.smid)],o=n?Qg(n):-1;a=o,i=n?.segments??(o>=0?e_(r,o).segments:[])}else n===e.mesh&&(i=e_(t.geoByBatchId?.get(e.batchId)??r,e.batchId).segments,a=e.batchId);let o=Kx(n.geometry,i);if(o&&o.length>0){let t=a>=0?new Float32Array(o.length/6).fill(a):void 0,r=new dc(Vx(o,t),this._createSelectionEdgeMaterial(n));r.renderOrder=4,r.frustumCulled=!1,r.raycast=()=>{},r.userData.isSelectionEdge=!0,n===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(r,e),n.add(r),this._selectionEdgeMeshes.push(r)}}this._selectionEdgeMeshes.length===0?this._addSelectionHull(e,t):this._selectionEdges=this._selectionEdgeMeshes[0]??null}_applyInstanceTransform(e,t){let n=t.mesh;if(t.instanceIndex==null||!n.isInstancedMesh)return;let r=new U;n.getMatrixAt(t.instanceIndex,r),r.decompose(e.position,e.quaternion,e.scale)}_addSelectionHull(e,t){let n=e.instanceIndex!=null;this.outlineMaterial.uniforms.uSelBatch.value=n?-1:e.batchId,this.outlineMaterial.uniforms.uSelWhole.value=n||e.batchId<0?1:0,this.outlineMaterial.uniforms.uElevation.value=n?this._selectionElevation(e):this.style.selectElevation??0;for(let n of t){let t=aS(n);t?.userData?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=t.userData.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=t.userData.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=t.userData.uBatchTexActive.value);let r=new dc(n.geometry,this.outlineMaterial);r.renderOrder=3,r.frustumCulled=!1,r.raycast=()=>{},n===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(r,e),n.add(r),this._outlineMeshes.push(r)}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?aS(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 t=this.renderer.getContext();if(t&&typeof t.isContextLost==`function`&&t.isContextLost())return!1;let n=this.animator.tick();this.flushOverrides();let r=this.canvas,i=this.sceneAnchor.meterInMercator;this._enuMatrix.set(i,0,0,this.sceneAnchor.x,0,-i,0,this.sceneAnchor.y,0,0,i,this.sceneAnchor.z,0,0,0,1);let a=new U().fromArray(e.mvp);a.multiply(this._enuMatrix),this.camera.projectionMatrix.copy(a),this.camera.projectionMatrixInverse.copy(a).invert();let o=e.cameraEnu;this.camera.position.set(o[0],o[1],o[2]),this.camera.matrixWorld.setPosition(o[0],o[1],o[2]),this.camera.matrixWorldInverse.copy(this.camera.matrixWorld).invert(),this.groundManager.update(this.camera);let s=!1;for(let t of this.datasets.values()){if(!t.visible||!t.tileset)continue;let n=[o[0]-t.offset[0],o[1]-t.offset[1],o[2]-t.offset[2]];t.tileset.update(n,e.fovRad,e.canvasHeight)&&(s=!0)}this.style.mode===Ly.DYNAMIC&&(this.uniforms.uTime.value+=.016*(this.style.speed??1)),this.gpuPathManager.updateUniforms(this.uniforms);let c=(this.uniforms.uPathTexActive?.value??0)>0;c&&!this._customPathTime&&this.uniforms.uPathTime&&(this.uniforms.uPathTime.value+=.016),this._updateLights(),this._updateLineResolution(r),this.renderer.setViewport(0,0,r.width,r.height),this.renderer.resetState(),this.renderer.render(this.scene,this.camera),this._frame++;let l=performance.now();return l-this._fps.last>500&&(this._fps.value=Math.round(this._frame*1e3/(l-this._fps.last)),this._frame=0,this._fps.last=l),n||this.style.mode===Ly.DYNAMIC||c||this.stats.loading>0||s}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=Vb(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()}};X(uS,`_EDGE_SKIP_KEYWORDS`,[`terrain`,`ground`,`vegetation`,`green`,`road`,`dem`,`绿地`,`道路`,`地面`,`地形`,`植被`,`铺装`]),Pb(),rh();var dS=1e-4;function fS(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])>dS*r)return!1}return!0}function pS(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 mS(e,t){return t>0&&Math.abs(e.elements[5]*Math.tan(t/2)-1)<.001}function hS(e){if(!e||typeof e!=`object`)return null;let t=e;return t.defaultProjectionData?.projectionMatrix??t.projectionMatrix??null}function gS(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 _S(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 vS(e,t){let n=e.projectionMatrix;if(!n||n.length<16)return null;let r=new U().fromArray(Array.from(n)),i=new U().fromArray(Array.from(e.mvp));if(r.determinant()===0||!mS(r,t.fov))return null;let a=r.clone().invert().multiply(i);if(!fS(r.clone().multiply(a),Array.from(e.mvp))||!pS(a)||!mS(r,t.fov))return null;let{distance:o,fov:s,aspect:c}=t;if(!(o>0)||!(s>0)||!(c>0))return null;let l=o*Math.tan(s/2),u=l*c,d=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,f=e.farZ!=null&&e.farZ>d?e.farZ:o*4+1e3;f>d||(f=d+1e3);let p=new zc(-u,u,l,-l,d,f);return p.updateProjectionMatrix(),{matrix:p.projectionMatrix.clone().multiply(a),view:a}}function yS(e,t,n){let r=e.projectionMatrix;if(!r||r.length<16)return null;let i=new U().fromArray(Array.from(r)),a=new U().fromArray(Array.from(e.mvp));if(i.determinant()===0||!mS(i,t.fov))return null;let o=i.clone().invert().multiply(a);if(!fS(i.clone().multiply(o),Array.from(e.mvp))||!pS(o))return null;let s=Math.max(0,Math.min(1,n));if(s<=0)return{matrix:a,view:o};let{distance:c,fov:l,aspect:u}=t;if(!(c>0)||!(l>0)||!(u>0))return null;let d=c*Math.tan(l/2),f=d*u,p=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,m=e.farZ!=null&&e.farZ>p?e.farZ:c*4+1e3;m>p||(m=p+1e3);let h=new zc(-f,f,d,-d,p,m);if(h.updateProjectionMatrix(),s>=1)return{matrix:h.projectionMatrix.clone().multiply(o),view:o};let g=new U,_=i.elements,v=h.projectionMatrix.elements,y=g.elements;for(let e=0;e<16;e++)y[e]=(1-s)*_[e]+s*v[e];return{matrix:g.multiply(o),view:o}}var bS=i({Animator:()=>Ix,AttributeQuery:()=>u_,BinaryReader:()=>dh,DEFAULT_FLOOR_HEIGHT:()=>i_,DEFAULT_STYLE:()=>Vy,DatasetManager:()=>Yx,EARTH_RADIUS:()=>d_,EASING_NAMES:()=>hx,FeatureStyleManager:()=>nS,GPUPathManager:()=>My,GroundManager:()=>rS,Path:()=>ky,Picker:()=>ix,PixelFormat:()=>rv,S3MFormatError:()=>Xg,S3MTileset:()=>Wb,S3MViewer:()=>uS,S3M_VERSION:()=>vg,SAMPLES_PER_PATH:()=>256,SELECT_MODE:()=>zy,SELECT_MODE_LABELS:()=>By,STYLE:()=>Ly,STYLE_LABELS:()=>Ry,TextureCompress:()=>iv,VertexTag:()=>yg,VertexTagV3:()=>bg,buildAttributes:()=>n_,buildBlendedMVP:()=>yS,buildFeatureEdgeSegments:()=>Kx,buildOrthoMVP:()=>vS,buildThickLineGeometry:()=>Vx,buildTileObjects:()=>jb,createLineSharedUniforms:()=>Lx,createOutlineMaterial:()=>Iy,createSharedUniforms:()=>Py,createStyledMaterial:()=>Fy,createTexture:()=>wy,createThickLineMaterial:()=>Bx,cubicBezier:()=>Ex,default:()=>uS,dxtPixelFormatOf:()=>nv,easing:()=>gx,extractEulerAngles:()=>Zx,extractFovRadians:()=>_S,extractNearFar:()=>gS,extractProjectionMatrix:()=>hS,isS3M1Buffer:()=>ag,lngLatFromMercator:()=>p_,lngLatFromWorld:()=>h_,measureSegments:()=>t_,mercatorFromLngLat:()=>f_,parseS3M1:()=>_g,parseS3MB:()=>Zg,resolveFeature:()=>e_,resolveRotationMatrix:()=>Xx,resolveTextureKind:()=>tv,setMaxAnisotropy:()=>vy,steps:()=>Dx,worldFromLngLat:()=>m_});a_(),eb(),Ny(),Oy(),sv(),Ay(),rh(),a_(),sv(),Oy(),Ay(),Ny(),eb(),Pb();var xS=globalThis;return xS.THREE||(xS.THREE=a),xS.S3M=bS,e.Animator=Ix,e.AttributeQuery=u_,e.BinaryReader=dh,e.DEFAULT_FLOOR_HEIGHT=i_,e.DEFAULT_STYLE=Vy,e.DatasetManager=Yx,e.EARTH_RADIUS=d_,e.EASING_NAMES=hx,e.FeatureStyleManager=nS,e.GPUPathManager=My,e.GroundManager=rS,e.Path=ky,e.Picker=ix,e.PixelFormat=rv,e.S3MFormatError=Xg,e.S3MTileset=Wb,e.S3MViewer=uS,e.default=uS,e.S3M_VERSION=vg,e.SAMPLES_PER_PATH=jy,e.SELECT_MODE=zy,e.SELECT_MODE_LABELS=By,e.STYLE=Ly,e.STYLE_LABELS=Ry,e.TextureCompress=iv,e.VertexTag=yg,e.VertexTagV3=bg,e.buildAttributes=n_,e.buildBlendedMVP=yS,e.buildFeatureEdgeSegments=Kx,e.buildOrthoMVP=vS,e.buildThickLineGeometry=Vx,e.buildTileObjects=jb,e.createLineSharedUniforms=Lx,e.createOutlineMaterial=Iy,e.createSharedUniforms=Py,e.createStyledMaterial=Fy,e.createTexture=wy,e.createThickLineMaterial=Bx,e.cubicBezier=Ex,e.dxtPixelFormatOf=nv,e.easing=gx,e.extractEulerAngles=Zx,e.extractFovRadians=_S,e.extractNearFar=gS,e.extractProjectionMatrix=hS,e.isS3M1Buffer=ag,e.lngLatFromMercator=p_,e.lngLatFromWorld=h_,e.measureSegments=t_,e.mercatorFromLngLat=f_,e.parseS3M1=_g,e.parseS3MB=Zg,e.resolveFeature=e_,e.resolveRotationMatrix=Xx,e.resolveTextureKind=tv,e.setMaxAnisotropy=vy,e.steps=Dx,e.worldFromLngLat=m_,e})({});
4820
+ `}),i=new dc(e,r);i.position.set(0,0,-.02),i.renderOrder=-1e3,i.name=`s3m-ground-depth`,i.visible=!1,this.group.add(i),this._depthMesh=i,this._depthMaterial=r,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()}};rh(),Oy(),eb(),Ay(),Ny(),a_(),uh();var aS=65534;function oS(e){let t=Array.isArray(e.material)?e.material[0]:e.material;return t?.userData?.isStyled?t:null}function sS(e){return e.isPoints===!0}function cS(e){let t=e??1;return t<0?0:t>1?1:t}var lS=.001,uS=[`opacity`,`floorHeight`,`selectOpacity`,`selectEmissive`,`selectElevation`,`dimFactor`,`texMix`,`roofThreshold`,`ambientGain`,`edgeWidth`,`edgeOpacity`,`outlineWidth`],dS=[`colorA`,`colorB`,`colorC`,`selectColor`,`edgeColor`],fS=[`translation`,`elevation`,`opacity`,`color`,`rotation`],pS=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={}){X(this,`options`,void 0),X(this,`pickable`,void 0),X(this,`onStats`,void 0),X(this,`onReady`,void 0),X(this,`onPick`,void 0),X(this,`onError`,void 0),X(this,`geo`,null),X(this,`canvas`,null),X(this,`renderer`,null),X(this,`scene`,null),X(this,`camera`,null),X(this,`picker`,null),X(this,`uniforms`,void 0),X(this,`style`,void 0),X(this,`_styleTarget`,void 0),X(this,`outlineMaterial`,void 0),X(this,`lineShared`,void 0),X(this,`edgeMaterial`,void 0),X(this,`selectionEdgeMaterial`,void 0),X(this,`_edgeStyleUniforms`,void 0),X(this,`_selEdgeStyleUniforms`,void 0),X(this,`groundManager`,void 0),X(this,`_datasetManager`,new Xx),X(this,`_featureStyleManager`,void 0),X(this,`gpuPathManager`,new My),X(this,`_customPathTime`,!1),X(this,`_pickables`,new Map),X(this,`_pickSeq`,0),X(this,`_freePickIds`,[]),X(this,`_smidMeshes`,new Map),X(this,`_meshHeight`,new Map),X(this,`_heightMin`,1/0),X(this,`_heightMax`,-1/0),X(this,`_boxScratch`,new ho),X(this,`_selection`,null),X(this,`_selectedMeshes`,[]),X(this,`_outlineMesh`,null),X(this,`_outlineMeshes`,[]),X(this,`_selectionEdges`,null),X(this,`_selectionEdgeMeshes`,[]),X(this,`_edgesEnabled`,!1),X(this,`_tileFadeSeq`,0),X(this,`_modeGen`,0),X(this,`_shadingPrewarmed`,!1),X(this,`_prewarmShadingEnabled`,!0),X(this,`_prewarming`,!1),X(this,`_pathSpecs`,new Map),X(this,`_pathScratch`,new Float32Array(3)),X(this,`_pathScratch2`,new Float32Array(3)),X(this,`_creaseLines`,null),X(this,`_nativeEdgeLines`,new Set),X(this,`_pointClouds`,new Set),X(this,`_opacityTransparent`,!1),X(this,`animator`,new Lx),X(this,`attributeQuery`,null),X(this,`_enuMatrix`,new U),X(this,`_colorScratch`,new W),X(this,`_needsRepaint`,!0),X(this,`_frame`,0),X(this,`_fps`,{value:0,last:0}),X(this,`_ambientLight`,void 0),X(this,`_hemiLight`,void 0),X(this,`_keyLight`,void 0),X(this,`_fillLight`,void 0),X(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}),X(this,`_datasetQueue`,void 0),X(this,`_onRequestRepaint`,()=>{}),X(this,`_getBearing`,void 0),X(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 iS(e.ground),this.scene||(this.scene=new Wl,this.scene.add(this.groundManager.group),this._addLights()),this._featureStyleManager=new rS(()=>this.style.floorHeight,()=>this._requestRepaint(),()=>{this._selection&&this._syncSelectionStyle()},()=>this.getAllMeshes(),e=>this._applyOverridesToMesh(e),()=>this._opacityTransparent),this.uniforms=Py(),by(b_),this.style={...Vy,...e.style??{}},this._styleTarget={...this.style},this._opacityTransparent=(this.style.opacity??1)<.999,this._applyStyleUniforms(),this._registerAnimChannels(),this.animator.onActive=()=>this._requestRepaint(),this.outlineMaterial=Iy(this.uniforms),this.lineShared=Rx(),this._edgeStyleUniforms={uColor:{value:new W(this.style.edgeColor)},uWidth:{value:Math.max(.1,this.style.edgeWidth??1.5)},uOpacity:{value:.6}},this.edgeMaterial=Vx(this.lineShared,{},this._edgeStyleUniforms),this._selEdgeStyleUniforms={uColor:{value:new W(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=Vx(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 u_(e.attributes))}_createRenderer(e,t){let n=new Vl({canvas:e,context:t,antialias:!0});return n.autoClear=!1,n.setPixelRatio(1),n.toneMapping=this.options.toneMapping===void 0?0:this.options.toneMapping,n.toneMappingExposure=this.options.toneMappingExposure??1,n}_syncTextureCapabilities(e){let t=!!e.getExtension(`WEBGL_compressed_texture_s3tc`),n=!!e.getExtension(`WEBGL_compressed_texture_s3tc_srgb`);yy(t&&n)}mount(e,t){this.canvas=e,this.renderer=this._createRenderer(e,t),vy(this.renderer.capabilities.getMaxAnisotropy()),this._syncTextureCapabilities(t),this.scene=new Wl,this.scene.add(this.groundManager.group),this._addLights(),this.camera=new _c,this.camera.matrixAutoUpdate=!1,this.picker=new ax(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),vy(this.renderer.capabilities.getMaxAnisotropy()),this._syncTextureCapabilities(e),this.picker?.dispose(),this.picker=new ax(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 mp(this._lightOptions.ambientColor,this._lightOptions.ambientIntensity),this._hemiLight=new ep(this._lightOptions.hemisphereColor,this._lightOptions.hemisphereGroundColor,this._lightOptions.hemisphereIntensity),this._keyLight=new pp(this._lightOptions.keyLightColor,this._lightOptions.keyLightIntensity),this._fillLight=new pp(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??0,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 h_(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=Qx(t),o=this._ensureFeatureChannel(e,`rotation`);this.animator.to(o,a,r)}rotateFeatureBy(e,t,n,r){let i=Qx(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 ky?t:new ky(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=Qx(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=Qx(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 fS)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 u_(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=oS(t);r&&r.dispose(),Qb(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=sS(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=oS(a);if(e){e.transparent=cS(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,t){if(!t.point)return!1;let n=e.geometry;if(!n||(n.boundingBox||n.computeBoundingBox(),!n.boundingBox))return!1;let r=new H(t.point[0],t.point[1],t.point[2]);e.updateWorldMatrix(!0,!1);let i=e.matrixWorld.clone().invert(),a=r.applyMatrix4(i);return n.boundingBox.clone().expandByScalar(.5).containsPoint(a)}_replaySelectionOnto(e){let t=this._selection;if(!t)return;let n=oS(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?Qg(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),sS(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),sS(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),oS(t)?.dispose?.()}Qb(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>aS){for(let e=0;e<=aS;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:Ry[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 dS.includes(e)?3:1}_registerAnimChannels(){for(let e of uS)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 dS)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??zy.OVERLAY;e.uSelMode&&(e.uSelMode.value=n===zy.REPLACE?0:n===zy.MULTIPLY?2:n===zy.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=cS(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=cS(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(sS(n.mesh))continue;let r=oS(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)){Zb(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=oS(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=oS(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&&!sS(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 t=await fetch(e);if(!t.ok)throw Error(`[s3m] 棱线缓存加载失败: ${t.status} ${e}`);let n=await t.arrayBuffer(),r=new Float32Array(n);if(r.length<6)return;let i=new q;i.setAttribute(`position`,new G(r,3));let a=this.style,o=new Qu({color:new W(a.edgeColor),transparent:!0,opacity:Math.min(1,Math.max(0,a.edgeOpacity??.6))*cS(a.opacity),depthWrite:!1}),s=new ld(i,o);s.renderOrder=2,s.frustumCulled=!1,s.raycast=()=>{},this.clearCreases(),this._creaseLines=s,this.scene?.add(s),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))*cS(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)*cS(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 t=e.userData;if(t.edges||t.nativeEdges||!e.geometry||this._shouldSkipAutoEdges(t,``))return;let n=e.geometry.getAttribute(`position`);if((e.geometry.index?.count??(n?n.count:0))>12e4)return;let r=Yx(e.geometry,.005),i=this.style.edgeThreshold??55,a=new Qd(r,i);r.dispose();let o=a.getAttribute(`position`),s=o?o.array:null;if(a.dispose(),!s||s.length<6)return;let c=.005,l=Ux(e.geometry,c),u;if(l){let e=s.length/6;u=new Float32Array(e);for(let t=0;t<e;t++){let e=t*6;u[t]=l.get(Wx(s[e],s[e+1],s[e+2],1/c))??-1}}let d=new dc(Hx(s,u),this._createEdgeMaterial(e));d.renderOrder=2,d.frustumCulled=!1,d.raycast=()=>{},d.userData.isThickEdge=!0,t.edges=d,e.add(d)}_createEdgeMaterial(e){let t=oS(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 Vx(this.lineShared,{},this._edgeStyleUniforms,n)}_createSelectionEdgeMaterial(e){let t=oS(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 Vx(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,t){if(!this.camera||!this.canvas)return null;let n=this.canvas,r=n.clientWidth||n.width,i=n.clientHeight||n.height;if(!r||!i)return null;let a=e/r*2-1,o=-(t/i)*2+1,s=new H(a,o,-1).unproject(this.camera),c=new H(a,o,1).unproject(this.camera).clone().sub(s).normalize();return new Bo(s,c)}_intersectMeshAtRay(e,t,n){let r=new gm;r.ray.copy(t);let i=r.intersectObject(e,!1);if(!i.length)return null;if(n!=null){let e=i.find(e=>e.instanceId===n);return e?e.point:i[0].point}return i[0].point}_buildPickResult(e,t,n,r){let i=t.mesh.userData,a=null,o=e.batchId,s=e.instanceIndex,c=i.geoRef,l=[];if(s!=null){let e=this._instanceFeature(t.mesh,c,s);if(!e)return null;a=e.smid,o=e.batchId}else{c=i.geoByBatchId?.get(e.batchId)??i.geoRef;let t=e_(c,e.batchId);a=t.smid,l=t.segments}if(this._isFeatureHidden(a,o))return null;let u=null,d=0;if(s!=null)u=this._instanceBox(t.mesh,s),d=t.mesh.geometry.index?Math.round(t.mesh.geometry.index.count/3):0;else if(a!=null&&this._smidMeshes.has(a)){let e=this._smidMeshes.get(a),t=1/0,n=1/0,r=1/0,i=-1/0,o=-1/0,s=-1/0,c=0;for(let l of e){let e=l.userData,u=e.geoRef?.pickInfo,f=u?.[a]??u?.[String(a)],p=f?Qg(f):-1,m=f?.segments??(p>=0?e_(e.geoRef,p).segments:[]),h=t_(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>o&&(o=h.maxY),h.maxZ>s&&(s=h.maxZ),c+=h.count,d+=h.triangles)}c>0&&(u={minX:t,minY:n,minZ:r,maxX:i,maxY:o,maxZ:s,count:c,triangles:d})}if(!u&&(u=t_(t.mesh.geometry,l),!u&&t.mesh.geometry)){t.mesh.geometry.boundingBox||t.mesh.geometry.computeBoundingBox();let e=t.mesh.geometry.boundingBox;e&&(u={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 f=t.mesh.geometry,p=d>0?d:f.index?Math.round(f.index.count/3):0,m=n_({smid:a,box:u,triangles:p,floorHeight:this.style.floorHeight}),h=null;if(u&&this.sceneAnchor){let e=new H((u.minX+u.maxX)/2,(u.minY+u.maxY)/2,(u.minZ+u.maxZ)/2);e.applyMatrix4(t.mesh.matrixWorld);let n=this.sceneAnchor.meterInMercator;h=this._lngLatFromWorld(e.x*n+this.sceneAnchor.x,-e.y*n+this.sceneAnchor.y)}let g=n??null;!g&&r&&(g=this._intersectMeshAtRay(t.mesh,r,s));let _=null,v=null,y=null;if(g&&this.sceneAnchor){let e=a==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(a),t=e.translation,n=e.elevation,r=g.clone();if(e.rotation){let t=Zx(e.rotation);if(t){let n=new V().set(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8]),i=e.pivot?new H(e.pivot[0],e.pivot[1],e.pivot[2]):new H(0,0,0);r.sub(i).applyMatrix3(n).add(i)}}t?r.add(new H(t[0],t[1],t[2])):n&&(r.z+=n),_=[r.x,r.y,r.z];let i=this.sceneAnchor.meterInMercator;v=this._lngLatFromWorld(r.x*i+this.sceneAnchor.x,-r.y*i+this.sceneAnchor.y),y=r.z+(this.sceneAnchor.altitude??0)}else h&&u&&this.sceneAnchor&&(v=h,y=(u.minZ+u.maxZ)/2+(this.sceneAnchor.altitude??0));return{datasetId:t.datasetId,datasetName:this.datasets.get(t.datasetId)?.name??t.datasetId,objectId:e.objectId,batchId:o,instanceIndex:s,skeletonName:t.skeletonName,centerLngLat:h,point:_,lngLat:v,altitude:y,...m,mesh:t.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,t){if(!this.camera||!this.sceneAnchor)return null;let n=this.pick(e,t);if(n?.point&&n?.lngLat&&n.altitude!=null)return{lngLat:n.lngLat,altitude:n.altitude,point:n.point};let r=this.getRayAt(e,t);if(!r)return null;let i=new Ac(new H(0,0,1),0),a=new H,o=r.intersectPlane(i,a);if(o){let e=this.sceneAnchor.meterInMercator;return{lngLat:this._lngLatFromWorld(o.x*e+this.sceneAnchor.x,-o.y*e+this.sceneAnchor.y),altitude:o.z+(this.sceneAnchor.altitude??0),point:[o.x,o.y,o.z]}}return null}drillPick(e,t,n=10){if(!this.sceneAnchor||!this.camera)return[];let r=this.getRayAt(e,t);if(!r)return[];let i=new gm;i.ray.copy(r);let a=[...this._pickables.values()].map(e=>e.mesh).filter(e=>{let t=e;for(;t;){if(!t.visible)return!1;t=t.parent}return!0}),o=i.intersectObjects(a,!1);if(!o.length)return[];let s=[],c=new Set,l=new Set;for(let e of o){if(s.length>=n)break;let t=e.object,r=t.userData;if(r.pickId==null)continue;let i=this._pickables.get(r.pickId);if(!i)continue;let a=null,o=-1,u=e.instanceId;if(u!=null){let e=this._instanceFeature(t,r.geoRef,u);if(!e)continue;a=e.smid,o=e.batchId}else if(e.faceIndex!=null){let n=t.geometry.attributes.aBatchId;if(n){let i=t.geometry.index?t.geometry.index.getX(e.faceIndex*3):e.faceIndex*3;o=Math.round(n.getX(i)),a=e_(r.geoByBatchId?.get(o)??r.geoRef,o).smid}}if(a!=null){if(c.has(a))continue;c.add(a)}else{let e=`${r.pickId}:${o}:${u??-1}`;if(l.has(e))continue;l.add(e)}if(this._isFeatureHidden(a,o))continue;let d={objectId:r.pickId,batchId:o,instanceIndex:u},f=this._buildPickResult(d,i,e.point);f&&s.push(f)}return s}getFeatureBounds(e){if(!this.sceneAnchor)return null;let t=1/0,n=-1/0,r=1/0,i=-1/0,a=!1;for(let o of this._pickables.values()){let s=o.mesh,c=s.userData,l=c.geoRef,u=l?.pickInfo;if(!u)continue;let d=null;if(s.isInstancedMesh){let t=c.instanceLookup;t||(t=$g(u),c.instanceLookup=t);for(let[n,r]of t)if(r.smid===e){d=this._instanceBox(s,n);break}}else{let t=u,n=t[e]??t[String(e)];if(n){let e=e_(l,Qg(n));if(d=t_(s.geometry,e.segments),!d&&s.geometry){s.geometry.boundingBox||s.geometry.computeBoundingBox();let e=s.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})}}}if(d){a=!0;let o=[new H(d.minX,d.minY,d.minZ),new H(d.maxX,d.minY,d.minZ),new H(d.minX,d.maxY,d.minZ),new H(d.maxX,d.maxY,d.minZ),new H(d.minX,d.minY,d.maxZ),new H(d.maxX,d.minY,d.maxZ),new H(d.minX,d.maxY,d.maxZ),new H(d.maxX,d.maxY,d.maxZ)],c=e==null?{}:this._featureStyleManager.getFeatureEffectiveOffset(e),l=c.translation,u=c.elevation,f=c.rotation?Zx(c.rotation):null,p=null,m=null;f&&(p=new V().set(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8]),m=c.pivot?new H(c.pivot[0],c.pivot[1],c.pivot[2]):new H(0,0,0));let h=e==null?null:this._gpuPathPoseAt(e),g=null;if(h&&h.yaw!==0){let e=Math.cos(h.yaw),t=Math.sin(h.yaw);g=new V().set(e,-t,0,t,e,0,0,0,1)}for(let e of o){if(p&&m&&e.sub(m).applyMatrix3(p).add(m),g){let t=m??new H(0,0,0);e.sub(t).applyMatrix3(g).add(t)}l?e.add(new H(l[0],l[1],l[2])):u&&(e.z+=u),h&&e.add(new H(h.pos[0],h.pos[1],h.pos[2])),e.applyMatrix4(s.matrixWorld);let a=this.sceneAnchor.meterInMercator,[o,c]=this._lngLatFromWorld(e.x*a+this.sceneAnchor.x,-e.y*a+this.sceneAnchor.y);o<t&&(t=o),o>n&&(n=o),c<r&&(r=c),c>i&&(i=c)}}}return a?[[t,r],[n,i]]:null}_instanceFeature(e,t,n){let r=e.userData;return r.instanceLookup||(r.instanceLookup=$g(t?.pickInfo)),r.instanceLookup.get(n)??null}_instanceBox(e,t){let n=e;if(!n.isInstancedMesh)return null;let r=e.geometry;r.boundingBox||r.computeBoundingBox();let i=r.boundingBox;if(!i)return null;let a=new U;n.getMatrixAt(t,a);let o=i.clone().applyMatrix4(a);return{minX:o.min.x,minY:o.min.y,minZ:o.min.z,maxX:o.max.x,maxY:o.max.y,maxZ:o.max.z,count:r.getAttribute(`position`)?.count??0,triangles:r.index?Math.round(r.index.count/3):0}}select(e,{silent:t=!1}={}){if(this._selection){for(let e of this._selectedMeshes){if(sS(e)){this._applyPointCloudStyle(e,!1);continue}let t=oS(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=oS(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?Qg(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)sS(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=>!sS(e));t.length&&((this.style.outlineStyle??`edges`)===`edges`?this._addSelectionEdges(e,t):this._addSelectionHull(e,t))}this._requestRepaint()}_addSelectionEdges(e,t){this._syncSelectionStyle();for(let n of t){let t=n.userData,r=t.geoRef,i=[],a=-1;if(n===e.mesh&&e.instanceIndex!=null){i=[{vertexOffset:0,vertexCount:n.geometry.getAttribute(`position`)?.count??0}];let t=r?.pickInfo,o=t?.[e.smid??``]??t?.[String(e.smid)];a=o?Qg(o):-1}else if(e.smid!=null){let t=r?.pickInfo,n=t?.[e.smid]??t?.[String(e.smid)],o=n?Qg(n):-1;a=o,i=n?.segments??(o>=0?e_(r,o).segments:[])}else n===e.mesh&&(i=e_(t.geoByBatchId?.get(e.batchId)??r,e.batchId).segments,a=e.batchId);let o=qx(n.geometry,i);if(o&&o.length>0){let t=a>=0?new Float32Array(o.length/6).fill(a):void 0,r=new dc(Hx(o,t),this._createSelectionEdgeMaterial(n));r.renderOrder=4,r.frustumCulled=!1,r.raycast=()=>{},r.userData.isSelectionEdge=!0,n===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(r,e),n.add(r),this._selectionEdgeMeshes.push(r)}}this._selectionEdgeMeshes.length===0?this._addSelectionHull(e,t):this._selectionEdges=this._selectionEdgeMeshes[0]??null}_applyInstanceTransform(e,t){let n=t.mesh;if(t.instanceIndex==null||!n.isInstancedMesh)return;let r=new U;n.getMatrixAt(t.instanceIndex,r),r.decompose(e.position,e.quaternion,e.scale)}_addSelectionHull(e,t){let n=e.instanceIndex!=null;this.outlineMaterial.uniforms.uSelBatch.value=n?-1:e.batchId,this.outlineMaterial.uniforms.uSelWhole.value=n||e.batchId<0?1:0,this.outlineMaterial.uniforms.uElevation.value=n?this._selectionElevation(e):this.style.selectElevation??0;for(let n of t){let t=oS(n);t?.userData?.uBatchTex&&(this.outlineMaterial.uniforms.uBatchTex.value=t.userData.uBatchTex.value,this.outlineMaterial.uniforms.uBatchTexWidth.value=t.userData.uBatchTexWidth.value,this.outlineMaterial.uniforms.uBatchTexActive.value=t.userData.uBatchTexActive.value);let r=new dc(n.geometry,this.outlineMaterial);r.renderOrder=3,r.frustumCulled=!1,r.raycast=()=>{},n===e.mesh&&e.instanceIndex!=null&&this._applyInstanceTransform(r,e),n.add(r),this._outlineMeshes.push(r)}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=cS(e.opacity),t.uElevation&&(t.uElevation.value=e.selectElevation??0);for(let e of this._outlineMeshes){let t=e.parent,n=t?oS(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 t=this.renderer.getContext();if(t&&typeof t.isContextLost==`function`&&t.isContextLost())return!1;if(this._prewarming)return!0;let n=this.animator.tick();this.flushOverrides();let r=this.canvas,i=this.sceneAnchor.meterInMercator;this._enuMatrix.set(i,0,0,this.sceneAnchor.x,0,-i,0,this.sceneAnchor.y,0,0,i,this.sceneAnchor.z,0,0,0,1);let a=new U().fromArray(e.mvp);a.multiply(this._enuMatrix),this.camera.projectionMatrix.copy(a),this.camera.projectionMatrixInverse.copy(a).invert();let o=e.cameraEnu;this.camera.position.set(o[0],o[1],o[2]),this.camera.matrixWorld.setPosition(o[0],o[1],o[2]),this.camera.matrixWorldInverse.copy(this.camera.matrixWorld).invert(),this.groundManager.update(this.camera);let s=!1;for(let t of this.datasets.values()){if(!t.visible||!t.tileset)continue;let n=[o[0]-t.offset[0],o[1]-t.offset[1],o[2]-t.offset[2]];t.tileset.update(n,e.fovRad,e.canvasHeight)&&(s=!0)}this.style.mode===Ly.DYNAMIC&&(this.uniforms.uTime.value+=.016*(this.style.speed??1)),this.gpuPathManager.updateUniforms(this.uniforms);let c=(this.uniforms.uPathTexActive?.value??0)>0;c&&!this._customPathTime&&this.uniforms.uPathTime&&(this.uniforms.uPathTime.value+=.016),this._updateLights(),this._updateLineResolution(r),this.renderer.setViewport(0,0,r.width,r.height),this.renderer.resetState(),(this.uniforms.uOpacity?.value??1)>lS&&this.renderer.render(this.scene,this.camera),this._frame++;let l=performance.now();l-this._fps.last>500&&(this._fps.value=Math.round(this._frame*1e3/(l-this._fps.last)),this._frame=0,this._fps.last=l);let u=n||this.style.mode===Ly.DYNAMIC||c||this.stats.loading>0||s;return this._prewarmShadingEnabled&&!this._shadingPrewarmed&&this._pickables.size>0&&this.prewarmShading(),u}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=Vb(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()}};X(pS,`_EDGE_SKIP_KEYWORDS`,[`terrain`,`ground`,`vegetation`,`green`,`road`,`dem`,`绿地`,`道路`,`地面`,`地形`,`植被`,`铺装`]),Pb(),rh();var mS=1e-4;function hS(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])>mS*r)return!1}return!0}function gS(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 _S(e,t){return t>0&&Math.abs(e.elements[5]*Math.tan(t/2)-1)<.001}function vS(e){if(!e||typeof e!=`object`)return null;let t=e;return t.defaultProjectionData?.projectionMatrix??t.projectionMatrix??null}function yS(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 bS(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 xS(e,t){let n=e.projectionMatrix;if(!n||n.length<16)return null;let r=new U().fromArray(Array.from(n)),i=new U().fromArray(Array.from(e.mvp));if(r.determinant()===0||!_S(r,t.fov))return null;let a=r.clone().invert().multiply(i);if(!hS(r.clone().multiply(a),Array.from(e.mvp))||!gS(a)||!_S(r,t.fov))return null;let{distance:o,fov:s,aspect:c}=t;if(!(o>0)||!(s>0)||!(c>0))return null;let l=o*Math.tan(s/2),u=l*c,d=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,f=e.farZ!=null&&e.farZ>d?e.farZ:o*4+1e3;f>d||(f=d+1e3);let p=new zc(-u,u,l,-l,d,f);return p.updateProjectionMatrix(),{matrix:p.projectionMatrix.clone().multiply(a),view:a}}function SS(e,t,n){let r=e.projectionMatrix;if(!r||r.length<16)return null;let i=new U().fromArray(Array.from(r)),a=new U().fromArray(Array.from(e.mvp));if(i.determinant()===0||!_S(i,t.fov))return null;let o=i.clone().invert().multiply(a);if(!hS(i.clone().multiply(o),Array.from(e.mvp))||!gS(o))return null;let s=Math.max(0,Math.min(1,n));if(s<=0)return{matrix:a,view:o};let{distance:c,fov:l,aspect:u}=t;if(!(c>0)||!(l>0)||!(u>0))return null;let d=c*Math.tan(l/2),f=d*u,p=e.nearZ!=null&&e.nearZ>0?e.nearZ:1,m=e.farZ!=null&&e.farZ>p?e.farZ:c*4+1e3;m>p||(m=p+1e3);let h=new zc(-f,f,d,-d,p,m);if(h.updateProjectionMatrix(),s>=1)return{matrix:h.projectionMatrix.clone().multiply(o),view:o};let g=new U,_=i.elements,v=h.projectionMatrix.elements,y=g.elements;for(let e=0;e<16;e++)y[e]=(1-s)*_[e]+s*v[e];return{matrix:g.multiply(o),view:o}}var CS=i({Animator:()=>Lx,AttributeQuery:()=>u_,BinaryReader:()=>dh,DEFAULT_FLOOR_HEIGHT:()=>i_,DEFAULT_STYLE:()=>Vy,DatasetManager:()=>Xx,EARTH_RADIUS:()=>d_,EASING_NAMES:()=>gx,FeatureStyleManager:()=>rS,GPUPathManager:()=>My,GroundManager:()=>iS,Path:()=>ky,Picker:()=>ax,PixelFormat:()=>rv,S3MFormatError:()=>Xg,S3MTileset:()=>Wb,S3MViewer:()=>pS,S3M_VERSION:()=>vg,SAMPLES_PER_PATH:()=>256,SELECT_MODE:()=>zy,SELECT_MODE_LABELS:()=>By,STYLE:()=>Ly,STYLE_LABELS:()=>Ry,TextureCompress:()=>iv,VertexTag:()=>yg,VertexTagV3:()=>bg,buildAttributes:()=>n_,buildBlendedMVP:()=>SS,buildFeatureEdgeSegments:()=>qx,buildOrthoMVP:()=>xS,buildThickLineGeometry:()=>Hx,buildTileObjects:()=>jb,createLineSharedUniforms:()=>Rx,createOutlineMaterial:()=>Iy,createSharedUniforms:()=>Py,createStyledMaterial:()=>Fy,createTexture:()=>wy,createThickLineMaterial:()=>Vx,cubicBezier:()=>Dx,default:()=>pS,dxtPixelFormatOf:()=>nv,easing:()=>_x,extractEulerAngles:()=>Qx,extractFovRadians:()=>bS,extractNearFar:()=>yS,extractProjectionMatrix:()=>vS,isS3M1Buffer:()=>ag,lngLatFromMercator:()=>p_,lngLatFromWorld:()=>h_,measureSegments:()=>t_,mercatorFromLngLat:()=>f_,parseS3M1:()=>_g,parseS3MB:()=>Zg,resolveFeature:()=>e_,resolveRotationMatrix:()=>Zx,resolveTextureKind:()=>tv,setMaxAnisotropy:()=>vy,steps:()=>Ox,worldFromLngLat:()=>m_});a_(),eb(),Ny(),Oy(),sv(),Ay(),rh(),a_(),sv(),Oy(),Ay(),Ny(),eb(),Pb();var wS=globalThis;return wS.THREE||(wS.THREE=a),wS.S3M=CS,e.Animator=Lx,e.AttributeQuery=u_,e.BinaryReader=dh,e.DEFAULT_FLOOR_HEIGHT=i_,e.DEFAULT_STYLE=Vy,e.DatasetManager=Xx,e.EARTH_RADIUS=d_,e.EASING_NAMES=gx,e.FeatureStyleManager=rS,e.GPUPathManager=My,e.GroundManager=iS,e.Path=ky,e.Picker=ax,e.PixelFormat=rv,e.S3MFormatError=Xg,e.S3MTileset=Wb,e.S3MViewer=pS,e.default=pS,e.S3M_VERSION=vg,e.SAMPLES_PER_PATH=jy,e.SELECT_MODE=zy,e.SELECT_MODE_LABELS=By,e.STYLE=Ly,e.STYLE_LABELS=Ry,e.TextureCompress=iv,e.VertexTag=yg,e.VertexTagV3=bg,e.buildAttributes=n_,e.buildBlendedMVP=SS,e.buildFeatureEdgeSegments=qx,e.buildOrthoMVP=xS,e.buildThickLineGeometry=Hx,e.buildTileObjects=jb,e.createLineSharedUniforms=Rx,e.createOutlineMaterial=Iy,e.createSharedUniforms=Py,e.createStyledMaterial=Fy,e.createTexture=wy,e.createThickLineMaterial=Vx,e.cubicBezier=Dx,e.dxtPixelFormatOf=nv,e.easing=_x,e.extractEulerAngles=Qx,e.extractFovRadians=bS,e.extractNearFar=yS,e.extractProjectionMatrix=vS,e.isS3M1Buffer=ag,e.lngLatFromMercator=p_,e.lngLatFromWorld=h_,e.measureSegments=t_,e.mercatorFromLngLat=f_,e.parseS3M1=_g,e.parseS3MB=Zg,e.resolveFeature=e_,e.resolveRotationMatrix=Zx,e.resolveTextureKind=tv,e.setMaxAnisotropy=vy,e.steps=Ox,e.worldFromLngLat=m_,e})({});