s3m-three 0.1.1 → 0.3.0

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.
@@ -38,6 +38,8 @@ export class GroundManager {
38
38
  gridSize: number;
39
39
  excavationBounds: [number, number, number, number] | null = null;
40
40
  size: number;
41
+ /** 物理地表网格的高度(米,场景 ENU Z 坐标),默认 0 */
42
+ groundHeight = 0;
41
43
 
42
44
  readonly group: THREE.Group;
43
45
  private _mesh: THREE.Mesh | null = null;
@@ -153,7 +155,18 @@ export class GroundManager {
153
155
  */
154
156
  update(camera?: THREE.Camera | null): void {
155
157
  if (!camera || this.mode === 'none') return;
156
- this.group.position.set(camera.position.x, camera.position.y, 0);
158
+ this.group.position.set(camera.position.x, camera.position.y, this.groundHeight);
159
+ }
160
+
161
+ /**
162
+ * 设置物理地表网格的高度(米,场景 ENU Z 坐标)
163
+ *
164
+ * 数据集被抬到真实地面高程后,地表网格需要同步抬高,
165
+ * 否则「地表覆盖 / 地下透视」的物理关系会与被抬升的模型脱节。
166
+ */
167
+ setGroundHeight(height: number): void {
168
+ this.groundHeight = height;
169
+ this.group.position.z = height;
157
170
  }
158
171
 
159
172
  setMode(mode: GroundMode): void {
@@ -508,15 +508,18 @@ export class S3MViewer {
508
508
  }
509
509
 
510
510
  /**
511
- * 获取指定数据集的垂直高程偏移(米)。
512
- * 若不传 id,默认获取第一个(或默认)数据集的高程偏移。
511
+ * 获取指定数据集的应用层附加垂直偏移(米,不含 align 基准)。
512
+ * 若不传 id,默认获取第一个(或默认)数据集的偏移。
513
513
  */
514
514
  getDatasetHeight(id?: string): number {
515
515
  return this._datasetManager.getDatasetHeight(id);
516
516
  }
517
517
 
518
518
  /**
519
- * 设置指定数据集的垂直高程偏移(米),正数抬升,负数下降。
519
+ * 设置指定数据集的应用层附加垂直偏移(米),正数抬升,负数下降。
520
+ *
521
+ * 语义为「在当前 align 基准之上再抬升多少米」:贴地(把模型抬到真实地面高程)
522
+ * 不会破坏 align='top' 等对齐语义。
520
523
  */
521
524
  setDatasetHeight(idOrHeight: string | number, heightOffset?: number): void {
522
525
  let id: string;
@@ -529,10 +532,22 @@ export class S3MViewer {
529
532
  h = heightOffset ?? 0;
530
533
  }
531
534
  this._datasetManager.setDatasetHeight(id, h, this.geo);
535
+ this._syncGroundHeight();
532
536
  this._refreshAllHeights();
533
537
  this._requestRepaint();
534
538
  }
535
539
 
540
+ /**
541
+ * 物理地表网格的高度跟随「主数据集的应用层抬升量」,
542
+ * 保证贴地后地表覆盖 / 地下透视的物理关系与被抬升的模型一致。
543
+ */
544
+ private _syncGroundHeight(): void {
545
+ const primaryId = this.datasets.keys().next().value;
546
+ if (!primaryId) return;
547
+ const userOffset = this._datasetManager.getDatasetHeight(primaryId);
548
+ this.groundManager.setGroundHeight(userOffset);
549
+ }
550
+
536
551
  /**
537
552
  * 动态设置指定数据集的垂直对齐基准('origin' | 'bottom' | 'top' | 'center')。
538
553
  */
@@ -387,13 +387,15 @@ export class S3MTileset {
387
387
 
388
388
  this._onTile(node);
389
389
  } catch (e) {
390
- this.stats.failed++;
391
390
  const attempts = (this._retryCount.get(url) ?? 0) + 1;
392
391
  this._retryCount.set(url, attempts);
393
392
  if (attempts <= this._maxRetries) {
394
393
  // 退避重试:不进 failed,下一帧 update() 会重新入队,避免网络抖一下就留个永久空洞
395
394
  this._retryAt.set(url, performance.now() + 800 * attempts);
396
395
  } else {
396
+ // 只有重试耗尽的瓦片才计入 failed:瞬态失败下一轮就成功了,
397
+ // 计进去会让状态栏永久挂着一个「N 个瓦片失败」的假警告
398
+ this.stats.failed++;
397
399
  this.failed.add(url);
398
400
  this._retryAt.delete(url);
399
401
  }