gltf-parser-plugin 1.1.6 → 1.1.8

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.
package/build/index.d.ts CHANGED
@@ -1,16 +1,38 @@
1
1
  import { Box3 } from 'three';
2
2
  import { Color } from 'three';
3
+ import { Euler } from 'three';
3
4
  import { EventDispatcher } from 'three';
4
5
  import { Intersection } from 'three';
5
6
  import { Material } from 'three';
6
7
  import { Mesh } from 'three';
7
8
  import { Texture } from 'three';
9
+ import { Tileset } from '3d-tiles-renderer/core';
8
10
  import { TilesRenderer } from '3d-tiles-renderer';
9
11
  import { Vector3 } from 'three';
10
12
  import { WebGLRenderer } from 'three';
11
13
 
14
+ /**
15
+ * 与 StyleHelper 中 `show`、`conditions` 条件项的表达式求值一致
16
+ * 在 propertyData 的键作为变量名的上下文中执行 `Boolean(expr)`
17
+ *
18
+ * 实现:对每个表达式字符串只编译一次 `new Function('data', 'with(d){...}')`,
19
+ * 避免按「表达式 × 属性键集合」重复编译,也避免每次求值排序/拼接 cacheKey。
20
+ */
21
+ /**
22
+ * 清空表达式编译缓存(热更新或单测可调用)
23
+ */
24
+ export declare function clearStyleConditionCache(): void;
25
+
26
+ /** 可解析为 THREE.Color 的输入 */
12
27
  export declare type ColorInput = number | string | Color;
13
28
 
29
+ /**
30
+ * 同步解析 `data:application/x-gzip;base64,...`:base64 → 二进制 → gunzip → UTF-8 文本。
31
+ */
32
+ export declare function decodeGzipBase64DataUriSync(dataUri: string): string;
33
+
34
+ export declare function evaluateStyleCondition(expr: string | boolean, propertyData: Record<string, unknown> | null): boolean;
35
+
14
36
  /**
15
37
  * Hit object feature information interface
16
38
  */
@@ -23,6 +45,9 @@ export declare interface FeatureInfo {
23
45
  error?: string;
24
46
  }
25
47
 
48
+ /** 从 tileset 取内嵌 structure 的 data URI(优先 MapTalks:`asset.extras.maptalks.structureUri`) */
49
+ export declare function getStructureDataUriFromTileset(root: Tileset | null): string | null;
50
+
26
51
  export declare class GLTFParserPlugin implements MeshHelperHost {
27
52
  name: string;
28
53
  private tiles;
@@ -31,18 +56,21 @@ export declare class GLTFParserPlugin implements MeshHelperHost {
31
56
  private readonly _options;
32
57
  private _structureData;
33
58
  private _oidNodeMap;
34
- private _structurePromise;
59
+ /** rootTileset 已存在且已尝试过内嵌解析后仍为 null,则不再重复 gunzip */
60
+ private _structureEmbedResolved;
35
61
  private _modelInfo;
36
62
  private _modelInfoPromise;
37
63
  private _interactionFilter;
38
64
  private _partColorHelper;
39
65
  private _partBlinkHelper;
40
66
  private _partFrameHelper;
67
+ private _styleHelper;
68
+ private _partHighlightHelper;
41
69
  oids: number[];
42
- private renderer;
70
+ /** WebGLRenderer 实例,用于 mesh helper 等扩展 */
71
+ get renderer(): WebGLRenderer | null;
72
+ private _renderer;
43
73
  private splitMeshCache;
44
- private maxUniformVectors;
45
- private featureIdCount;
46
74
  private collectors;
47
75
  private collectorCache;
48
76
  /**
@@ -54,6 +82,7 @@ export declare class GLTFParserPlugin implements MeshHelperHost {
54
82
  * Plugin initialization, called by TilesRenderer
55
83
  */
56
84
  init(tiles: TilesRenderer): void;
85
+ private _createPartEffectHost;
57
86
  /**
58
87
  * Fetch tile data with IndexedDB caching support
59
88
  */
@@ -63,42 +92,51 @@ export declare class GLTFParserPlugin implements MeshHelperHost {
63
92
  */
64
93
  clearCache(): Promise<void>;
65
94
  parseTile(buffer: ArrayBuffer, tile: any, extension: any, uri: string, abortSignal: AbortSignal): Promise<any>;
66
- private _getStructureUrl;
95
+ /** 与 tileset 同目录的侧车 JSON,如 structure.json / modelInfo.json */
96
+ private _sidecarJsonUrl;
67
97
  private _buildOidNodeMap;
68
- private _fetchStructureData;
69
- private _ensureStructureLoaded;
98
+ /** 仅根 tileset 变化时重解析 structureUri(子 tileset 的 load-tileset 不会触发) */
99
+ private _onLoadRootTilesetCB;
70
100
  /**
71
- * 根据 oid 获取 structure.json 中对应的节点树数据
72
- * 包含 bbox、children、name 等完整结构信息
73
- * 首次调用时会自动从 tileset URL 推导并请求 structure.json
101
+ * 从已加载根 tileset 的内嵌 structure(优先 asset.extras.maptalks.structureUri)同步解压并建索引。
102
+ * rootTileset 尚未就绪时返回 null,可稍后再次调用;已成功或已判定无内嵌数据后见 _structureEmbedResolved。
74
103
  */
75
- getNodeTreeByOid(oid: number): Promise<StructureNode | null>;
104
+ private _syncStructureFromTileset;
76
105
  /**
77
- * 根据 oid 数组批量获取 structure.json 中对应的节点树数据
106
+ * 根据 oid 获取结构树节点(数据来自 tileset 内嵌 structureUri 同步解压)
78
107
  */
79
- getNodeTreeByOids(oids: number[]): Promise<Map<number, StructureNode>>;
108
+ getNodeTreeByOid(oid: number): StructureNode | null;
80
109
  /**
81
- * 获取完整的 structure.json 数据
82
- * 首次调用时会自动请求
110
+ * 根据 oid 数组批量获取结构树节点
83
111
  */
84
- getStructureData(): Promise<StructureData | null>;
112
+ getNodeTreeByOids(oids: number[]): Map<number, StructureNode>;
85
113
  /**
86
- * 选择包围盒范围内的构件(包含相交和包含两种情况)
87
- * @param box 查询用的 Box3 范围,坐标系与 structure.json 中 bbox 一致
88
- * @returns 范围内所有构件的 oid 数组
114
+ * 根据 oid 从结构数据取轴对齐包围盒(`bbox` 为 `[minX,minY,minZ,maxX,maxY,maxZ]`,与 `selectByBox` 一致)
115
+ * @returns 无对应节点或缺少有效 bbox 时返回 `null`
89
116
  */
90
- selectByBox(box: Box3): Promise<number[]>;
117
+ getBoundingBoxByOid(oid: number): Box3 | null;
91
118
  /**
92
- * 选择多边形(平面投影)范围内的构件(包含相交和包含两种情况)
93
- * @param polygon 多边形顶点数组(Vector3),按顺序连接构成闭合多边形
94
- * @param axis 投影平面,决定使用 bbox 的哪两个轴做 2D 判定
95
- * - 'xz'(默认):俯视图,取 bbox 的 x/z 坐标
96
- * - 'xy':正视图,取 bbox 的 x/y 坐标
97
- * - 'yz':侧视图,取 bbox 的 y/z 坐标
98
- * @returns 范围内所有构件的 oid 数组
119
+ * 计算给定 OID 集合的几何中心(世界坐标系与结构 bbox / 瓦片 mesh 一致)。
120
+ * 优先合并结构树中的轴对齐 bbox;若无有效 bbox 则合并对应 split mesh 的世界包围盒。
99
121
  */
100
- selectByPolygon(polygon: Vector3[], axis?: "xy" | "xz" | "yz"): Promise<number[]>;
101
- private _getModelInfoUrl;
122
+ getCenterByOids(oids: readonly number[]): Vector3 | null;
123
+ /**
124
+ * 按属性条件筛选构件(语义同 `setStyle` 的 `show` / conditions 中的表达式字符串),
125
+ * 返回筛选结果的整体中心点;合并方式同 {@link getCenterByOids}。
126
+ */
127
+ getCenterByCondition(condition: string): Vector3 | null;
128
+ /**
129
+ * 完整结构数据(与内嵌 structure JSON 一致)
130
+ */
131
+ getStructureData(): StructureData | null;
132
+ /**
133
+ * 选择包围盒范围内的构件(坐标系与结构 bbox 一致)
134
+ */
135
+ selectByBox(box: Box3): number[];
136
+ /**
137
+ * 选择多边形(平面投影)范围内的构件
138
+ */
139
+ selectByPolygon(polygon: Vector3[], axis?: "xy" | "xz" | "yz"): number[];
102
140
  private _fetchModelInfo;
103
141
  private _ensureModelInfoLoaded;
104
142
  /**
@@ -119,13 +157,12 @@ export declare class GLTFParserPlugin implements MeshHelperHost {
119
157
  private _notifyCollectors;
120
158
  _registerCollector(collector: MeshCollector): void;
121
159
  _unregisterCollector(collector: MeshCollector): void;
122
- private _updateWebGLLimits;
123
160
  /**
124
- * Dynamically calculate FEATURE_ID_COUNT based on WebGL limits and current oid count
161
+ * 遍历所有已加载瓦片,应用可见性过滤
125
162
  */
126
- private _calculateFeatureIdCount;
163
+ private _applyVisibilityToAllTiles;
127
164
  /**
128
- * Set up shader modification for hiding specific features
165
+ * 设置材质(DoubleSide 等基础配置)
129
166
  */
130
167
  private _setupMaterial;
131
168
  /**
@@ -146,23 +183,45 @@ export declare class GLTFParserPlugin implements MeshHelperHost {
146
183
  unisolate(): void;
147
184
  getIsolatedOids(): number[];
148
185
  /**
149
- * 内部方法:根据 oid 获取 mesh 数组
186
+ * 合并 OID 列表对应的结构 bbox;若无可用 bbox 则使用 split mesh 世界包围盒并求中心。
187
+ */
188
+ private _getCenterFromOidList;
189
+ /**
190
+ * 按 OID 集合:每个瓦片 mesh 只生成 **一个** 合并后的 split mesh(同一组 oid / condition 一条几何)
191
+ */
192
+ private _getMergedSplitMeshesForOidSet;
193
+ /**
194
+ * 内部方法:根据单个 oid 获取 split mesh(每瓦片合并为一条)
150
195
  */
151
196
  _getMeshesByOidInternal(oid: number): Mesh[];
152
197
  /**
153
- * 根据 oid 获取 MeshCollector
154
- * MeshCollector 会监听瓦片变化,自动更新 meshes 并触发 mesh-change 事件
155
- * 内部缓存:相同 oid 多次调用会返回同一个 collector 实例
198
+ * 内部方法:根据多个 oid 获取合并 split mesh(每瓦片一条,而非每 oid 一条)
199
+ */
200
+ _getMeshesByOidsInternal(oids: readonly number[]): Mesh[];
201
+ /**
202
+ * 按查询收集 mesh:可只传 oids、只传 condition(全场景 OID 上筛选)、或两者组合
203
+ * condition 与 setStyle 的 show / conditions 中字符串表达式语义一致
204
+ */
205
+ _getMeshesForCollectorQueryInternal(params: {
206
+ oids: readonly number[];
207
+ condition?: string;
208
+ }): Mesh[];
209
+ /**
210
+ * 根据查询获取 MeshCollector(oids + 可选 condition,缓存键相同则复用实例)
211
+ */
212
+ getMeshCollectorByCondition(query: MeshCollectorQuery): MeshCollector;
213
+ /**
214
+ * 根据单个 oid 获取 MeshCollector(等价于 getMeshCollectorByCondition({ oids: [oid] }))
156
215
  */
157
216
  getMeshCollectorByOid(oid: number): MeshCollector;
158
217
  /**
159
218
  * Hide the corresponding part of the original mesh according to the OID array
160
219
  */
161
- hideByOids(oids: number[]): void;
220
+ hidePartsByOids(oids: number[]): void;
162
221
  /**
163
222
  * Restore the display of the corresponding mesh according to the OID array
164
223
  */
165
- unhideByOids(oids: number[]): void;
224
+ showPartsByOids(oids: number[]): void;
166
225
  /**
167
226
  * 根据 oid 数组设置构件颜色
168
227
  * 隐藏原 mesh,将 split mesh 替换材质后加入场景(使用 tiles.group)
@@ -172,7 +231,7 @@ export declare class GLTFParserPlugin implements MeshHelperHost {
172
231
  setPartColorByOids(oids: number[], color: ColorInput): void;
173
232
  /**
174
233
  * 恢复指定构件的颜色
175
- * 从场景移除 split mesh,unhide mesh
234
+ * 从场景移除 split mesh,恢复原 mesh 显示
176
235
  * @param oids 构件 OID 数组
177
236
  */
178
237
  restorePartColorByOids(oids: number[]): void;
@@ -215,12 +274,51 @@ export declare class GLTFParserPlugin implements MeshHelperHost {
215
274
  * 清除所有线框显示构件
216
275
  */
217
276
  clearAllFrameParts(): void;
277
+ /**
278
+ * 设置指定构件的线框填充颜色
279
+ * @param oids 构件 OID 数组
280
+ * @param color 颜色值,支持 hex 数字、颜色字符串(如 "#ff0000")、THREE.Color 对象
281
+ */
282
+ setFrameFillColor(oids: number[], color: ColorInput): void;
283
+ /**
284
+ * 设置指定构件的线框边框颜色
285
+ * @param oids 构件 OID 数组
286
+ * @param color 颜色值,支持 hex 数字、颜色字符串(如 "#ff0000")、THREE.Color 对象
287
+ */
288
+ setFrameEdgeColor(oids: number[], color: ColorInput): void;
289
+ /**
290
+ * 设置构件样式(条件可见性 + 条件材质)
291
+ * @param style 样式配置,传 null 清除样式
292
+ */
293
+ setStyle(style: StyleConfig | null): void;
294
+ /**
295
+ * 当前样式配置,只读
296
+ */
297
+ get style(): StyleConfig | null;
298
+ /**
299
+ * 清除构件样式
300
+ */
301
+ clearStyle(): void;
302
+ /**
303
+ * 高亮指定构件(语义与 setStyle 一致:show、conditions、可选 oids,另需 name 标识分组)
304
+ * @param options 高亮配置
305
+ */
306
+ highlight(options: HighlightOptions): void;
307
+ /**
308
+ * 取消指定名称的高亮
309
+ * @param name 高亮组名称
310
+ */
311
+ cancelHighlight(name: string): void;
312
+ /**
313
+ * 取消所有高亮
314
+ */
315
+ cancelAllHighlight(): void;
218
316
  /**
219
317
  * Restore the original materials of the mesh
220
318
  */
221
- unhide(): void;
319
+ showAllParts(): void;
222
320
  /**
223
- * Get the current feature ID count
321
+ * 获取当前隐藏的 OID 数量(兼容旧 API)
224
322
  */
225
323
  getFeatureIdCount(): number;
226
324
  /**
@@ -234,7 +332,7 @@ export declare class GLTFParserPlugin implements MeshHelperHost {
234
332
  */
235
333
  export declare interface GLTFParserPluginOptions {
236
334
  /**
237
- * WebGLRenderer instance, required for mesh helper features (hideByOids, etc.)
335
+ * WebGLRenderer instance, required for mesh helper features (hidePartsByOids, etc.)
238
336
  */
239
337
  renderer?: WebGLRenderer;
240
338
  /**
@@ -266,6 +364,35 @@ export declare interface GLTFParserPluginOptions {
266
364
  useIndexedDB?: boolean;
267
365
  }
268
366
 
367
+ /** 条件命中后的外观:材质可为简写,位姿与 setStyle 一致 */
368
+ export declare interface HighlightAppearance {
369
+ material: HighlightMaterial;
370
+ translation?: StyleVec3Input;
371
+ scale?: StyleVec3Input;
372
+ rotation?: StyleEulerInput;
373
+ origin?: StyleVec3Input;
374
+ }
375
+
376
+ export declare type HighlightCondition = [string | boolean, HighlightAppearance];
377
+
378
+ /** 高亮材质:Three.js Material 或 { color, opacity } */
379
+ export declare type HighlightMaterial = Material | {
380
+ color?: ColorInput;
381
+ opacity?: number;
382
+ };
383
+
384
+ /** 高亮配置:语义与 setStyle 一致,并多一个 name 用于命名分组 */
385
+ export declare interface HighlightOptions {
386
+ /** 高亮组名称,用于 cancelHighlight(name) 取消 */
387
+ name: string;
388
+ /** 可见性表达式,仅满足条件的构件参与高亮,如 'foo === bar' */
389
+ show?: string;
390
+ /** 条件外观数组,第一个满足条件的应用对应外观;[true, appearance] 为默认 */
391
+ conditions?: HighlightCondition[];
392
+ /** 若指定,仅在这些 OID 与属性数据的交集中应用(与 conditions 组合) */
393
+ oids?: number[];
394
+ }
395
+
269
396
  declare type MaterialBuilder = (matData: unknown, textureMap: Map<number, Texture>) => Material;
270
397
 
271
398
  export declare interface MeshChangeEvent {
@@ -274,18 +401,25 @@ export declare interface MeshChangeEvent {
274
401
  }
275
402
 
276
403
  /**
277
- * MeshCollector - 用于监听和收集特定 oid 对应的 mesh
278
- * 随着瓦片变化,会自动更新 meshes 并触发 mesh-change 事件
404
+ * MeshCollector - 按查询条件监听并收集 split mesh
279
405
  */
280
406
  export declare class MeshCollector extends EventDispatcher<MeshCollectorEventMap> {
281
- private oid;
407
+ private readonly queryOids;
408
+ private readonly condition;
409
+ private readonly cacheKey;
282
410
  private plugin;
283
411
  private _meshes;
284
412
  private _disposed;
285
- constructor(oid: number, plugin: MeshHelperHost);
413
+ constructor(query: MeshCollectorQuery, plugin: MeshHelperHost);
414
+ getCacheKey(): string;
415
+ /** 查询里显式传入的 OID(规范化后);仅用 condition 筛选时可能为空数组 */
416
+ getOids(): readonly number[];
417
+ /** 有显式 OID 时返回第一个;否则无意义(可能为 undefined) */
418
+ getOid(): number | undefined;
286
419
  get meshes(): Mesh[];
420
+ /** 与 setStyle 一致的条件表达式(若有) */
421
+ getCondition(): string | undefined;
287
422
  _updateMeshes(): void;
288
- getOid(): number;
289
423
  dispose(): void;
290
424
  }
291
425
 
@@ -293,10 +427,33 @@ export declare type MeshCollectorEventMap = {
293
427
  "mesh-change": MeshChangeEvent;
294
428
  };
295
429
 
296
- declare interface MeshHelperHost {
430
+ /** @deprecated 请使用 meshCollectorQueryCacheKey({ oids }) */
431
+ export declare function meshCollectorGroupKey(oids: readonly number[]): string;
432
+
433
+ /** 收集器查询:OID 范围 + 可选属性条件(语义同 setStyle 的 show / conditions 中的表达式字符串) */
434
+ export declare interface MeshCollectorQuery {
435
+ /**
436
+ * 限定在这些 OID 内收集;不传或空数组时,若提供 condition 则从全场景 OID 中筛选
437
+ */
438
+ oids?: readonly number[];
439
+ /**
440
+ * 属性表达式,如 `type === "wall"`,与 setStyle 里 `show` 或 `conditions[i][0]`(为 string 时)相同
441
+ */
442
+ condition?: string;
443
+ }
444
+
445
+ /**
446
+ * 与 MeshCollector.getCacheKey()、插件 collectorCache 键一致
447
+ */
448
+ export declare function meshCollectorQueryCacheKey(query: MeshCollectorQuery): string;
449
+
450
+ export declare interface MeshHelperHost {
297
451
  _registerCollector(collector: MeshCollector): void;
298
452
  _unregisterCollector(collector: MeshCollector): void;
299
- _getMeshesByOidInternal(oid: number): Mesh[];
453
+ _getMeshesForCollectorQueryInternal(params: {
454
+ oids: readonly number[];
455
+ condition?: string;
456
+ }): Mesh[];
300
457
  }
301
458
 
302
459
  /**
@@ -312,6 +469,18 @@ export declare interface ModelInfo {
312
469
  vertices: number;
313
470
  }
314
471
 
472
+ /** 去重并排序 OID */
473
+ export declare function normalizeMeshCollectorOids(oids: readonly number[]): number[];
474
+
475
+ /**
476
+ * 从已加载的根 tileset 读取内嵌 structure(`asset.extras.maptalks.structureUri`,
477
+ * 若无则回退根级 `structureUri`),同步解码并解析。
478
+ * - 无有效 URI 或解析失败时返回 `null`(不抛错)。
479
+ */
480
+ export declare function parseEmbeddedStructureDataFromTilesSync(tiles: {
481
+ rootTileset: Tileset | null;
482
+ }): StructureData | null;
483
+
315
484
  /**
316
485
  * structure.json 的完整数据结构
317
486
  */
@@ -332,4 +501,34 @@ export declare interface StructureNode {
332
501
  [key: string]: unknown;
333
502
  }
334
503
 
504
+ /** 条件命中后的外观:材质必填,位姿可选(未传则不改对应分量) */
505
+ export declare interface StyleAppearance {
506
+ material: Material;
507
+ translation?: StyleVec3Input;
508
+ scale?: StyleVec3Input;
509
+ rotation?: StyleEulerInput;
510
+ /** mesh 局部空间中的枢轴;未传则 (0,0,0) */
511
+ origin?: StyleVec3Input;
512
+ }
513
+
514
+ /** 条件项:[条件表达式或 true, 外观对象] */
515
+ export declare type StyleCondition = [string | boolean, StyleAppearance];
516
+
517
+ /** 样式配置 */
518
+ export declare interface StyleConfig {
519
+ show?: string;
520
+ conditions?: StyleCondition[];
521
+ }
522
+
523
+ /** 与 Euler 等价:Three 的 Euler,或 [x,y,z] / [x,y,z,order] */
524
+ export declare type StyleEulerInput = Euler | readonly number[];
525
+
526
+ /** 与 Vector3 等价:Three 的 Vector3 或长度≥3 的 [x,y,z] 数组 */
527
+ export declare type StyleVec3Input = Vector3 | readonly number[];
528
+
529
+ /** 兼容:少数 tileset 在根级挂 structureUri */
530
+ export declare type TilesetWithStructureUri = Tileset & {
531
+ structureUri?: string;
532
+ };
533
+
335
534
  export { }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gltf-parser-plugin",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "A plugin for parsing GLTF files",
5
5
  "type": "module",
6
6
  "main": "./build/gltf-parser-plugin.module.js",
@@ -30,18 +30,19 @@
30
30
  "devDependencies": {
31
31
  "@types/node": "^25.5.0",
32
32
  "@types/three": "^0.183.1",
33
- "@typescript-eslint/eslint-plugin": "^8.57.0",
34
- "@typescript-eslint/parser": "^8.57.0",
35
- "eslint": "^10.0.3",
36
- "typescript": "^5.9.3",
37
- "vite": "^8.0.0",
33
+ "@typescript-eslint/eslint-plugin": "^8.57.2",
34
+ "@typescript-eslint/parser": "^8.57.2",
35
+ "eslint": "^10.1.0",
36
+ "typescript": "^5.8.2",
37
+ "vite": "^8.0.2",
38
38
  "vite-plugin-dts": "^4.5.4",
39
- "vitest": "^4.1.0"
39
+ "vitest": "^4.1.1"
40
40
  },
41
41
  "dependencies": {
42
- "3d-tiles-renderer": "^0.4.22",
42
+ "3d-tiles-renderer": "^0.4.23",
43
43
  "@maptalks/gltf-loader": "^0.124.4",
44
44
  "@maptalks/transcoders.draco": "^0.124.4",
45
+ "fflate": "^0.8.2",
45
46
  "three": "^0.183.2"
46
47
  }
47
48
  }