s3m-three 0.3.8 → 0.3.10

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 (41) hide show
  1. package/dist/browser/s3m-three.iife.ext-three.js +322 -47
  2. package/dist/browser/s3m-three.iife.js +322 -47
  3. package/dist/core/types.d.ts +20 -0
  4. package/dist/core/types.d.ts.map +1 -1
  5. package/dist/index.d.ts +5 -1
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +3 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/render/EdgeLines.d.ts +18 -0
  10. package/dist/render/EdgeLines.d.ts.map +1 -1
  11. package/dist/render/EdgeLines.js +95 -13
  12. package/dist/render/EdgeLines.js.map +1 -1
  13. package/dist/render/FeatureStyleManager.d.ts +78 -0
  14. package/dist/render/FeatureStyleManager.d.ts.map +1 -1
  15. package/dist/render/FeatureStyleManager.js +407 -59
  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/OrthoProjection.d.ts +6 -0
  22. package/dist/render/OrthoProjection.d.ts.map +1 -1
  23. package/dist/render/OrthoProjection.js +48 -0
  24. package/dist/render/OrthoProjection.js.map +1 -1
  25. package/dist/render/S3MViewer.d.ts +66 -0
  26. package/dist/render/S3MViewer.d.ts.map +1 -1
  27. package/dist/render/S3MViewer.js +218 -6
  28. package/dist/render/S3MViewer.js.map +1 -1
  29. package/dist/render/StyleMaterial.d.ts +21 -0
  30. package/dist/render/StyleMaterial.d.ts.map +1 -1
  31. package/dist/render/StyleMaterial.js +256 -21
  32. package/dist/render/StyleMaterial.js.map +1 -1
  33. package/package.json +1 -1
  34. package/src/core/types.ts +10 -0
  35. package/src/index.ts +8 -0
  36. package/src/render/EdgeLines.ts +101 -13
  37. package/src/render/FeatureStyleManager.ts +524 -64
  38. package/src/render/GPUPathManager.ts +306 -0
  39. package/src/render/OrthoProjection.ts +52 -0
  40. package/src/render/S3MViewer.ts +272 -5
  41. package/src/render/StyleMaterial.ts +264 -21
@@ -14,6 +14,7 @@
14
14
  */
15
15
  import * as THREE from 'three';
16
16
  import { DUMMY_BATCH_TEX } from './StyleMaterial.js';
17
+ import { GPUPathManager } from './GPUPathManager.js';
17
18
 
18
19
  /** 所有等宽线材质共享的分辨率 uniform(每帧更新一次即可) */
19
20
  export interface LineSharedUniforms {
@@ -38,8 +39,14 @@ export interface ThickLineStyleUniforms {
38
39
  /** 等宽线的「单体状态」uniform:直接复用主材质 userData 里那几个对象,自动跟随 */
39
40
  export interface ThickLineBatchUniforms {
40
41
  uBatchTex: { value: THREE.Texture };
42
+ uBatchTex2?: { value: THREE.Texture };
43
+ uBatchMix?: { value: number };
41
44
  uBatchTexWidth: { value: number };
42
45
  uBatchTexActive: { value: number };
46
+ uPathTex?: { value: unknown };
47
+ uPathCount?: { value: number };
48
+ uPathTime?: { value: number };
49
+ uPathTexActive?: { value: number };
43
50
  }
44
51
 
45
52
  export interface ThickLineMaterial extends THREE.ShaderMaterial {
@@ -69,30 +76,99 @@ const VERT = /* glsl */ `
69
76
  uniform float uElevation;
70
77
  uniform vec3 uTranslation;
71
78
  uniform sampler2D uBatchTex;
79
+ uniform sampler2D uBatchTex2;
80
+ uniform float uBatchMix;
72
81
  uniform float uBatchTexWidth;
73
82
  uniform int uBatchTexActive;
83
+ uniform sampler2D uPathTex;
84
+ uniform float uPathCount;
85
+ uniform float uPathTime;
86
+ uniform int uPathTexActive;
87
+
88
+ vec4 s3mSampleBatch( sampler2D texA, sampler2D texB, vec2 uv, float mixVal ) {
89
+ vec4 vA = texture2D( texA, uv );
90
+ if ( mixVal <= 0.0001 ) return vA;
91
+ vec4 vB = texture2D( texB, uv );
92
+ return mix( vA, vB, mixVal );
93
+ }
74
94
 
75
95
  void main() {
76
- // 单体平移 / 拔高 / 隐藏:与主着色器同一份状态纹理、同一套口径。
77
- // 不采样的话,单体一动棱线就留在原地——这正是「棱线跟随」要解决的。
96
+ // 单体平移 / 旋转 / 拔高 / 隐藏:与主着色器同一份 6 行状态纹理、同一套变换口径。
97
+ // 不采样的话,单体一动或一转棱线就留在原地——这正是「棱线跟随」要解决的。
78
98
  vec3 s3mA = position;
79
99
  vec3 s3mB = aOther;
100
+ vec3 s3mCustomOffset = vec3( 0.0 );
101
+ mat3 s3mRot = mat3( 1.0 );
102
+ vec3 s3mPivot = vec3( 0.0 );
103
+
80
104
  if ( uBatchTexActive > 0 && aBatchId >= 0.0 ) {
81
- vec4 bState = texture2D( uBatchTex, vec2( ( aBatchId + 0.5 ) / uBatchTexWidth, 0.25 ) );
105
+ float s3mU = ( aBatchId + 0.5 ) / uBatchTexWidth;
106
+ vec4 bState = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.08333333 ), uBatchMix );
82
107
  if ( bState.a < -0.5 ) {
83
108
  // 该单体被隐藏:顶点着色器不能 discard,扔到裁剪空间外
84
109
  gl_Position = vec4( 2.0, 2.0, 2.0, 1.0 );
85
110
  return;
86
111
  }
87
- vec4 bOffset = texture2D( uBatchTex, vec2( ( aBatchId + 0.5 ) / uBatchTexWidth, 0.75 ) );
88
- vec3 s3mOffset = bOffset.xyz;
89
- if ( s3mOffset.z == 0.0 && bState.a > 0.0 ) {
90
- s3mOffset.z = bState.a;
112
+ vec4 bOffset = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.25 ), uBatchMix );
113
+ s3mCustomOffset = bOffset.xyz;
114
+ if ( s3mCustomOffset.z == 0.0 && bState.a > 0.0 ) {
115
+ s3mCustomOffset.z = bState.a;
116
+ }
117
+ vec4 r2 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.41666667 ), uBatchMix );
118
+ vec4 r3 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.58333333 ), uBatchMix );
119
+ vec4 r4 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.75 ), uBatchMix );
120
+ s3mRot = mat3(
121
+ vec3( r2.x, r3.x, r4.x ),
122
+ vec3( r2.y, r3.y, r4.y ),
123
+ vec3( r2.z, r3.z, r4.z )
124
+ );
125
+ s3mPivot = vec3( r2.w, r3.w, r4.w );
126
+
127
+ // Row 5: GPU 路径动画计算
128
+ if ( uPathTexActive > 0 ) {
129
+ vec4 r5 = s3mSampleBatch( uBatchTex, uBatchTex2, vec2( s3mU, 0.91666667 ), uBatchMix );
130
+ float pathId = r5.x;
131
+ float speed = r5.y;
132
+ float phase = r5.z;
133
+ float mode = r5.w;
134
+ if ( pathId >= 0.0 && mode > 0.5 && uPathCount > 0.0 ) {
135
+ float t = phase + uPathTime * speed;
136
+ bool autoHeading = true;
137
+ if ( mode >= 4.0 ) {
138
+ autoHeading = false;
139
+ mode -= 3.0;
140
+ }
141
+ if ( mode < 1.5 ) {
142
+ t = fract( t );
143
+ } else if ( mode < 2.5 ) {
144
+ t = clamp( t, 0.0, 1.0 );
145
+ } else {
146
+ t = mod( t, 2.0 );
147
+ t = ( t > 1.0 ) ? ( 2.0 - t ) : t;
148
+ }
149
+ float pathU = ( t * 255.0 + 0.5 ) / 256.0;
150
+ float pathV = ( pathId + 0.5 ) / uPathCount;
151
+ vec4 pathSample = texture2D( uPathTex, vec2( pathU, pathV ) );
152
+ vec3 pathPos = pathSample.xyz;
153
+ float pathYaw = pathSample.w;
154
+ if ( autoHeading ) {
155
+ float c = cos( pathYaw );
156
+ float s = sin( pathYaw );
157
+ mat3 rotHeading = mat3(
158
+ c, -s, 0.0,
159
+ s, c, 0.0,
160
+ 0.0, 0.0, 1.0
161
+ );
162
+ s3mRot = rotHeading * s3mRot;
163
+ }
164
+ s3mCustomOffset += pathPos;
165
+ }
91
166
  }
92
- s3mA += s3mOffset;
93
- s3mB += s3mOffset;
94
167
  }
95
168
 
169
+ s3mA = s3mRot * ( s3mA - s3mPivot ) + s3mPivot + s3mCustomOffset;
170
+ s3mB = s3mRot * ( s3mB - s3mPivot ) + s3mPivot + s3mCustomOffset;
171
+
96
172
  // 选中单体平移/拔高:与着色器里 transformed += uTranslation 保持同一口径(物体空间)
97
173
  vec3 offset = uTranslation + vec3( 0.0, 0.0, uElevation );
98
174
  vec4 clipA = projectionMatrix * modelViewMatrix * vec4( s3mA + offset, 1.0 );
@@ -158,10 +234,16 @@ export function createThickLineMaterial(
158
234
  if (opts.opacity !== undefined && styleUniforms) style.uOpacity.value = opts.opacity;
159
235
  if (opts.width !== undefined && styleUniforms) style.uWidth.value = opts.width;
160
236
 
161
- const batch: Required<ThickLineBatchUniforms> = batchUniforms ?? {
162
- uBatchTex: { value: DUMMY_BATCH_TEX },
163
- uBatchTexWidth: { value: 1 },
164
- uBatchTexActive: { value: 0 },
237
+ const batch: Required<ThickLineBatchUniforms> = {
238
+ uBatchTex: batchUniforms?.uBatchTex ?? { value: DUMMY_BATCH_TEX },
239
+ uBatchTex2: batchUniforms?.uBatchTex2 ?? { value: DUMMY_BATCH_TEX },
240
+ uBatchMix: batchUniforms?.uBatchMix ?? { value: 0 },
241
+ uBatchTexWidth: batchUniforms?.uBatchTexWidth ?? { value: 1 },
242
+ uBatchTexActive: batchUniforms?.uBatchTexActive ?? { value: 0 },
243
+ uPathTex: batchUniforms?.uPathTex ?? { value: GPUPathManager.DUMMY_PATH_TEX },
244
+ uPathCount: batchUniforms?.uPathCount ?? { value: 1 },
245
+ uPathTexActive: batchUniforms?.uPathTexActive ?? { value: 0 },
246
+ uPathTime: batchUniforms?.uPathTime ?? { value: 0 },
165
247
  };
166
248
 
167
249
  const mat = new THREE.ShaderMaterial({
@@ -174,8 +256,14 @@ export function createThickLineMaterial(
174
256
  uElevation: style.uElevation ?? { value: opts.elevation ?? 0 },
175
257
  uTranslation: { value: new THREE.Vector3(0, 0, 0) },
176
258
  uBatchTex: batch.uBatchTex,
259
+ uBatchTex2: batch.uBatchTex2,
260
+ uBatchMix: batch.uBatchMix,
177
261
  uBatchTexWidth: batch.uBatchTexWidth,
178
262
  uBatchTexActive: batch.uBatchTexActive,
263
+ uPathTex: batch.uPathTex,
264
+ uPathCount: batch.uPathCount,
265
+ uPathTexActive: batch.uPathTexActive,
266
+ uPathTime: batch.uPathTime,
179
267
  },
180
268
  vertexShader: VERT,
181
269
  fragmentShader: FRAG,