s3m-three 0.3.9 → 0.3.11

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.
Files changed (36) hide show
  1. package/dist/browser/s3m-three.iife.ext-three.js +174 -40
  2. package/dist/browser/s3m-three.iife.js +174 -40
  3. package/dist/core/types.d.ts +16 -0
  4. package/dist/core/types.d.ts.map +1 -1
  5. package/dist/index.d.ts +3 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/render/EdgeLines.d.ts +12 -0
  10. package/dist/render/EdgeLines.d.ts.map +1 -1
  11. package/dist/render/EdgeLines.js +60 -6
  12. package/dist/render/EdgeLines.js.map +1 -1
  13. package/dist/render/FeatureStyleManager.d.ts +33 -0
  14. package/dist/render/FeatureStyleManager.d.ts.map +1 -1
  15. package/dist/render/FeatureStyleManager.js +98 -11
  16. package/dist/render/FeatureStyleManager.js.map +1 -1
  17. package/dist/render/GPUPathManager.d.ts +95 -0
  18. package/dist/render/GPUPathManager.d.ts.map +1 -0
  19. package/dist/render/GPUPathManager.js +265 -0
  20. package/dist/render/GPUPathManager.js.map +1 -0
  21. package/dist/render/S3MViewer.d.ts +47 -0
  22. package/dist/render/S3MViewer.d.ts.map +1 -1
  23. package/dist/render/S3MViewer.js +104 -3
  24. package/dist/render/S3MViewer.js.map +1 -1
  25. package/dist/render/StyleMaterial.d.ts +12 -0
  26. package/dist/render/StyleMaterial.d.ts.map +1 -1
  27. package/dist/render/StyleMaterial.js +117 -14
  28. package/dist/render/StyleMaterial.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/core/types.ts +8 -0
  31. package/src/index.ts +3 -1
  32. package/src/render/EdgeLines.ts +64 -6
  33. package/src/render/FeatureStyleManager.ts +130 -11
  34. package/src/render/GPUPathManager.ts +306 -0
  35. package/src/render/S3MViewer.ts +119 -2
  36. package/src/render/StyleMaterial.ts +121 -14
@@ -11,6 +11,7 @@
11
11
  import * as THREE from 'three';
12
12
  import type { StyleUniforms } from '../core/types.js';
13
13
  import { DEFAULT_FLOOR_HEIGHT } from '../core/FeatureInfo.js';
14
+ import { GPUPathManager } from './GPUPathManager.js';
14
15
 
15
16
  /** 着色模式,数值与着色器里的 uMode 一一对应 */
16
17
  export const STYLE = {
@@ -188,8 +189,9 @@ const DUMMY_DATA = new Float32Array([
188
189
  1, 0, 0, 0, // Row 2: rot row 0, pivot.x
189
190
  0, 1, 0, 0, // Row 3: rot row 1, pivot.y
190
191
  0, 0, 1, 0, // Row 4: rot row 2, pivot.z
192
+ -1, 0, 0, 0, // Row 5: pathId (-1=none), speed, phase, modeFlag
191
193
  ]);
192
- export const DUMMY_BATCH_TEX = new THREE.DataTexture(DUMMY_DATA, 1, 5, THREE.RGBAFormat, THREE.FloatType);
194
+ export const DUMMY_BATCH_TEX = new THREE.DataTexture(DUMMY_DATA, 1, 6, THREE.RGBAFormat, THREE.FloatType);
193
195
  DUMMY_BATCH_TEX.minFilter = THREE.NearestFilter;
194
196
  DUMMY_BATCH_TEX.magFilter = THREE.NearestFilter;
195
197
  DUMMY_BATCH_TEX.needsUpdate = true;
@@ -235,6 +237,14 @@ export function createSharedUniforms(): StyleUniforms {
235
237
  uAmbientGain: { value: 0 },
236
238
  /** 双纹理交叉淡化插值系数(0 = 纯 uBatchTex, 1 = 纯 uBatchTex2) */
237
239
  uBatchMix: { value: 0 },
240
+ /** GPU 路径数据采样纹理 */
241
+ uPathTex: { value: GPUPathManager.DUMMY_PATH_TEX },
242
+ /** GPU 路径纹理中包含的路径条数(高度) */
243
+ uPathCount: { value: 1 },
244
+ /** 是否激活 GPU 路径动画(0 = 未激活,1 = 激活) */
245
+ uPathTexActive: { value: 0 },
246
+ /** GPU 路径时间戳(秒) */
247
+ uPathTime: { value: 0 },
238
248
  /**
239
249
  * 图层整体透明度:在片元里乘进 diffuseColor.a。
240
250
  *
@@ -277,6 +287,10 @@ const VERT_PARS = /* glsl */ `
277
287
  uniform float uBatchMix;
278
288
  uniform float uBatchTexWidth;
279
289
  uniform int uBatchTexActive;
290
+ uniform sampler2D uPathTex;
291
+ uniform float uPathCount;
292
+ uniform float uPathTime;
293
+ uniform int uPathTexActive;
280
294
  varying float vBatchId;
281
295
  varying vec3 vVertColor;
282
296
  varying float vWorldZ;
@@ -341,22 +355,63 @@ const VERT_SETUP = /* glsl */ `
341
355
  float s3mBatchSetup = s3mBatchRaw();
342
356
  if ( uBatchTexActive > 0 && s3mBatchSetup >= 0.0 ) {
343
357
  float s3mU = ( s3mBatchSetup + 0.5 ) / uBatchTexWidth;
344
- vec4 bState = s3mSampleBatchRow0( uBatchTex, uBatchTex2, vec2( s3mU, 0.1 ), uBatchMix );
358
+ vec4 bState = s3mSampleBatchRow0( uBatchTex, uBatchTex2, vec2( s3mU, 0.08333333 ), uBatchMix );
345
359
  if ( bState.a >= -0.5 ) {
346
- vec4 bOffset = s3mSampleBatchRow1( uBatchTex, uBatchTex2, vec2( s3mU, 0.3 ), uBatchMix );
360
+ vec4 bOffset = s3mSampleBatchRow1( uBatchTex, uBatchTex2, vec2( s3mU, 0.25 ), uBatchMix );
347
361
  s3mCustomOffset = bOffset.xyz;
348
362
  if ( s3mCustomOffset.z == 0.0 && bState.a > 0.0 ) {
349
363
  s3mCustomOffset.z = bState.a;
350
364
  }
351
- vec4 r2 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.5 ), uBatchMix );
352
- vec4 r3 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.7 ), uBatchMix );
353
- vec4 r4 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.9 ), uBatchMix );
365
+ vec4 r2 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.41666667 ), uBatchMix );
366
+ vec4 r3 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.58333333 ), uBatchMix );
367
+ vec4 r4 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.75 ), uBatchMix );
354
368
  s3mRot = mat3(
355
369
  vec3( r2.x, r3.x, r4.x ),
356
370
  vec3( r2.y, r3.y, r4.y ),
357
371
  vec3( r2.z, r3.z, r4.z )
358
372
  );
359
373
  s3mPivot = vec3( r2.w, r3.w, r4.w );
374
+
375
+ // Row 5: GPU 路径动画计算
376
+ if ( uPathTexActive > 0 ) {
377
+ vec4 r5 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.91666667 ), uBatchMix );
378
+ float pathId = r5.x;
379
+ float speed = r5.y;
380
+ float phase = r5.z;
381
+ float mode = r5.w;
382
+ if ( pathId >= 0.0 && mode > 0.5 && uPathCount > 0.0 ) {
383
+ float t = phase + uPathTime * speed;
384
+ bool autoHeading = true;
385
+ if ( mode >= 4.0 ) {
386
+ autoHeading = false;
387
+ mode -= 3.0;
388
+ }
389
+ if ( mode < 1.5 ) {
390
+ t = fract( t );
391
+ } else if ( mode < 2.5 ) {
392
+ t = clamp( t, 0.0, 1.0 );
393
+ } else {
394
+ t = mod( t, 2.0 );
395
+ t = ( t > 1.0 ) ? ( 2.0 - t ) : t;
396
+ }
397
+ float pathU = ( t * 255.0 + 0.5 ) / 256.0;
398
+ float pathV = ( pathId + 0.5 ) / uPathCount;
399
+ vec4 pathSample = texture2D( uPathTex, vec2( pathU, pathV ) );
400
+ vec3 pathPos = pathSample.xyz;
401
+ float pathYaw = pathSample.w;
402
+ if ( autoHeading ) {
403
+ float c = cos( pathYaw );
404
+ float s = sin( pathYaw );
405
+ mat3 rotHeading = mat3(
406
+ c, -s, 0.0,
407
+ s, c, 0.0,
408
+ 0.0, 0.0, 1.0
409
+ );
410
+ s3mRot = rotHeading * s3mRot;
411
+ }
412
+ s3mCustomOffset += pathPos;
413
+ }
414
+ }
360
415
  }
361
416
  }
362
417
  objectNormal = normalize( s3mRot * objectNormal );
@@ -366,7 +421,7 @@ const VERT_ELEVATION = /* glsl */ `
366
421
  float s3mBatchElev = s3mBatchRaw();
367
422
  if ( uBatchTexActive > 0 && s3mBatchElev >= 0.0 ) {
368
423
  float s3mU = ( s3mBatchElev + 0.5 ) / uBatchTexWidth;
369
- vec4 bState = s3mSampleBatchRow0( uBatchTex, uBatchTex2, vec2( s3mU, 0.1 ), uBatchMix );
424
+ vec4 bState = s3mSampleBatchRow0( uBatchTex, uBatchTex2, vec2( s3mU, 0.08333333 ), uBatchMix );
370
425
  if ( bState.a < -0.5 ) {
371
426
  transformed = vec3( 0.0 );
372
427
  }
@@ -637,7 +692,7 @@ const FRAG_COLOR = /* glsl */ `
637
692
  if ( uBatchTexActive > 0 && s3mBid >= 0.0 ) {
638
693
  // 用取整后的 id 采样:否则逐像素的插值误差会让纹素在边界上来回跳,同样出彩色噪点
639
694
  float s3mU = ( s3mBid + 0.5 ) / uBatchTexWidth;
640
- vec4 bState = s3mSampleBatchRow0( uBatchTex, uBatchTex2, vec2( s3mU, 0.1 ), uBatchMix );
695
+ vec4 bState = s3mSampleBatchRow0( uBatchTex, uBatchTex2, vec2( s3mU, 0.08333333 ), uBatchMix );
641
696
  if ( bState.a < -0.5 ) {
642
697
  discard; // 属于被过滤隐藏的单体
643
698
  }
@@ -648,7 +703,7 @@ const FRAG_COLOR = /* glsl */ `
648
703
  }
649
704
  // 单体独立透明度(状态纹理第 2 行 alpha,0 = 无覆盖)。
650
705
  // 与全局 uOpacity(diffuseColor.a 初值)和图集贴图自带 alpha 逐级叠乘
651
- vec4 bOffset = s3mSampleBatchRow1( uBatchTex, uBatchTex2, vec2( s3mU, 0.3 ), uBatchMix );
706
+ vec4 bOffset = s3mSampleBatchRow1( uBatchTex, uBatchTex2, vec2( s3mU, 0.25 ), uBatchMix );
652
707
  if ( bOffset.a > 0.0 ) {
653
708
  diffuseColor.a *= bOffset.a;
654
709
  }
@@ -836,6 +891,10 @@ const OUTLINE_VERT = /* glsl */ `
836
891
  uniform float uBatchMix;
837
892
  uniform float uBatchTexWidth;
838
893
  uniform int uBatchTexActive;
894
+ uniform sampler2D uPathTex;
895
+ uniform float uPathCount;
896
+ uniform float uPathTime;
897
+ uniform int uPathTexActive;
839
898
  varying float vSel;
840
899
 
841
900
  vec4 s3mSampleBatch( sampler2D texA, sampler2D texB, vec2 uv, float mixVal ) {
@@ -852,24 +911,64 @@ const OUTLINE_VERT = /* glsl */ `
852
911
  vec3 s3mPivot = vec3( 0.0 );
853
912
  if ( uBatchTexActive > 0 && aBatchId >= 0.0 ) {
854
913
  float s3mU = ( aBatchId + 0.5 ) / uBatchTexWidth;
855
- vec4 bState = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.1 ), uBatchMix );
914
+ vec4 bState = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.08333333 ), uBatchMix );
856
915
  if ( bState.a < -0.5 ) {
857
916
  vSel = 0.0; // 过滤隐藏的单体不显示描边
858
917
  } else {
859
- vec4 bOffset = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.3 ), uBatchMix );
918
+ vec4 bOffset = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.25 ), uBatchMix );
860
919
  s3mCustomOffset = bOffset.xyz;
861
920
  if ( s3mCustomOffset.z == 0.0 && bState.a > 0.0 ) {
862
921
  s3mCustomOffset.z = bState.a;
863
922
  }
864
- vec4 r2 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.5 ), uBatchMix );
865
- vec4 r3 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.7 ), uBatchMix );
866
- vec4 r4 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.9 ), uBatchMix );
923
+ vec4 r2 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.41666667 ), uBatchMix );
924
+ vec4 r3 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.58333333 ), uBatchMix );
925
+ vec4 r4 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.75 ), uBatchMix );
867
926
  s3mRot = mat3(
868
927
  vec3( r2.x, r3.x, r4.x ),
869
928
  vec3( r2.y, r3.y, r4.y ),
870
929
  vec3( r2.z, r3.z, r4.z )
871
930
  );
872
931
  s3mPivot = vec3( r2.w, r3.w, r4.w );
932
+
933
+ if ( uPathTexActive > 0 ) {
934
+ vec4 r5 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.91666667 ), uBatchMix );
935
+ float pathId = r5.x;
936
+ float speed = r5.y;
937
+ float phase = r5.z;
938
+ float mode = r5.w;
939
+ if ( pathId >= 0.0 && mode > 0.5 && uPathCount > 0.0 ) {
940
+ float t = phase + uPathTime * speed;
941
+ bool autoHeading = true;
942
+ if ( mode >= 4.0 ) {
943
+ autoHeading = false;
944
+ mode -= 3.0;
945
+ }
946
+ if ( mode < 1.5 ) {
947
+ t = fract( t );
948
+ } else if ( mode < 2.5 ) {
949
+ t = clamp( t, 0.0, 1.0 );
950
+ } else {
951
+ t = mod( t, 2.0 );
952
+ t = ( t > 1.0 ) ? ( 2.0 - t ) : t;
953
+ }
954
+ float pathU = ( t * 255.0 + 0.5 ) / 256.0;
955
+ float pathV = ( pathId + 0.5 ) / uPathCount;
956
+ vec4 pathSample = texture2D( uPathTex, vec2( pathU, pathV ) );
957
+ vec3 pathPos = pathSample.xyz;
958
+ float pathYaw = pathSample.w;
959
+ if ( autoHeading ) {
960
+ float c = cos( pathYaw );
961
+ float s = sin( pathYaw );
962
+ mat3 rotHeading = mat3(
963
+ c, -s, 0.0,
964
+ s, c, 0.0,
965
+ 0.0, 0.0, 1.0
966
+ );
967
+ s3mRot = rotHeading * s3mRot;
968
+ }
969
+ s3mCustomOffset += pathPos;
970
+ }
971
+ }
873
972
  }
874
973
  }
875
974
  vec3 p = position + ( s3mRot * normal ) * uWidth * vSel;
@@ -899,6 +998,10 @@ export interface OutlineMaterial extends THREE.ShaderMaterial {
899
998
  uBatchMix: { value: number };
900
999
  uBatchTexWidth: { value: number };
901
1000
  uBatchTexActive: { value: number };
1001
+ uPathTex: { value: unknown };
1002
+ uPathCount: { value: number };
1003
+ uPathTexActive: { value: number };
1004
+ uPathTime: { value: number };
902
1005
  uColor: { value: THREE.Color };
903
1006
  };
904
1007
  }
@@ -916,6 +1019,10 @@ export function createOutlineMaterial(shared: StyleUniforms, initialWidth = 0.9)
916
1019
  uBatchMix: shared.uBatchMix ?? { value: 0 },
917
1020
  uBatchTexWidth: { value: 1.0 },
918
1021
  uBatchTexActive: { value: 0 },
1022
+ uPathTex: shared.uPathTex ?? { value: GPUPathManager.DUMMY_PATH_TEX },
1023
+ uPathCount: shared.uPathCount ?? { value: 1 },
1024
+ uPathTexActive: shared.uPathTexActive ?? { value: 0 },
1025
+ uPathTime: shared.uPathTime ?? { value: 0 },
919
1026
  uColor: { value: shared.uSelColor.value.clone() },
920
1027
  },
921
1028
  vertexShader: OUTLINE_VERT,