gltf-parser-plugin 1.1.7 → 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/gltf-parser-plugin.module.js +1588 -435
- package/build/gltf-parser-plugin.module.js.map +1 -1
- package/build/index.d.ts +232 -45
- package/package.json +9 -8
|
@@ -1,23 +1,68 @@
|
|
|
1
|
-
import { Box2, Box3, BufferAttribute, BufferGeometry, Color, CustomBlending, DataTexture, DoubleSide, EdgesGeometry, EventDispatcher, Float32BufferAttribute, FrontSide, Group, InstancedMesh, LineSegments, Loader, Matrix2, Matrix3, Matrix4, Mesh, MeshBasicMaterial, MeshStandardMaterial, OneFactor, OrthographicCamera, Quaternion, RGBAFormat, SRGBColorSpace, Scene, ShaderMaterial, Texture, Triangle, UnsignedByteType, Vector2, Vector3, Vector4, WebGLRenderTarget, WebGLRenderer, ZeroFactor } from "three";
|
|
2
|
-
//#region src/mesh-helper/
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
1
|
+
import { Box2, Box3, BufferAttribute, BufferGeometry, Color, CustomBlending, DataTexture, DoubleSide, EdgesGeometry, Euler, EventDispatcher, Float32BufferAttribute, FrontSide, Group, InstancedMesh, LineSegments, Loader, Material, Matrix2, Matrix3, Matrix4, Mesh, MeshBasicMaterial, MeshStandardMaterial, OneFactor, OrthographicCamera, Quaternion, RGBAFormat, SRGBColorSpace, Scene, ShaderMaterial, Texture, Triangle, UnsignedByteType, Vector2, Vector3, Vector4, WebGLRenderTarget, WebGLRenderer, ZeroFactor } from "three";
|
|
2
|
+
//#region src/mesh-helper/index-visibility.ts
|
|
3
|
+
/** 从 mesh 的 idMap 和 hiddenOids 构建需要隐藏的 feature ID 集合 */
|
|
4
|
+
function getHiddenFeatureIds(mesh, hiddenOids) {
|
|
5
|
+
const idMap = mesh.userData?.idMap;
|
|
6
|
+
if (!idMap) return /* @__PURE__ */ new Set();
|
|
7
|
+
const hidden = /* @__PURE__ */ new Set();
|
|
8
|
+
for (const oid of hiddenOids) {
|
|
9
|
+
const fid = idMap[oid];
|
|
10
|
+
if (fid !== void 0) hidden.add(fid);
|
|
11
|
+
}
|
|
12
|
+
return hidden;
|
|
13
|
+
}
|
|
14
|
+
/** 对单个 mesh 应用可见性过滤(通过修改 index 排除隐藏的三角形) */
|
|
15
|
+
function applyVisibilityToMesh(mesh, hiddenOids) {
|
|
16
|
+
const { meshFeatures } = mesh.userData;
|
|
17
|
+
if (!meshFeatures) return;
|
|
18
|
+
const geometry = mesh.geometry;
|
|
19
|
+
const index = geometry.index;
|
|
20
|
+
const featureIdAttr = geometry.getAttribute("_feature_id_0");
|
|
21
|
+
if (!index || !featureIdAttr) return;
|
|
22
|
+
const hiddenFeatureIds = getHiddenFeatureIds(mesh, hiddenOids);
|
|
23
|
+
if (hiddenFeatureIds.size === 0) {
|
|
24
|
+
restoreMeshIndex(mesh);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (!mesh.userData._originalIndex) mesh.userData._originalIndex = index.array.slice(0);
|
|
28
|
+
const originalArray = mesh.userData._originalIndex;
|
|
29
|
+
const filtered = originalArray instanceof Uint32Array ? new Uint32Array(originalArray.length) : new Uint16Array(originalArray.length);
|
|
30
|
+
let writeOffset = 0;
|
|
31
|
+
for (let i = 0; i < originalArray.length; i += 3) {
|
|
32
|
+
const fid = featureIdAttr.getX(originalArray[i]);
|
|
33
|
+
if (hiddenFeatureIds.has(fid)) continue;
|
|
34
|
+
filtered[writeOffset++] = originalArray[i];
|
|
35
|
+
filtered[writeOffset++] = originalArray[i + 1];
|
|
36
|
+
filtered[writeOffset++] = originalArray[i + 2];
|
|
37
|
+
}
|
|
38
|
+
const filteredArray = filtered.subarray(0, writeOffset);
|
|
39
|
+
geometry.setIndex(new BufferAttribute(filteredArray, 1));
|
|
40
|
+
geometry.index.needsUpdate = true;
|
|
41
|
+
}
|
|
42
|
+
/** 恢复 mesh 的原始 index */
|
|
43
|
+
function restoreMeshIndex(mesh) {
|
|
44
|
+
const original = mesh.userData?._originalIndex;
|
|
45
|
+
if (!original) return;
|
|
46
|
+
const geometry = mesh.geometry;
|
|
47
|
+
if (!geometry?.index) return;
|
|
48
|
+
geometry.setIndex(new BufferAttribute(original, 1));
|
|
49
|
+
geometry.index.needsUpdate = true;
|
|
50
|
+
}
|
|
51
|
+
/** 遍历 scene 中所有 tile mesh,应用可见性过滤 */
|
|
52
|
+
function applyVisibilityToScene(scene, hiddenOids) {
|
|
53
|
+
const oidSet = hiddenOids;
|
|
54
|
+
if (oidSet.size === 0) {
|
|
55
|
+
scene.traverse((obj) => {
|
|
56
|
+
const mesh = obj;
|
|
57
|
+
if (mesh.userData?.meshFeatures && !mesh.userData?.isSplit) restoreMeshIndex(mesh);
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
19
60
|
}
|
|
20
|
-
|
|
61
|
+
scene.traverse((obj) => {
|
|
62
|
+
const mesh = obj;
|
|
63
|
+
if (mesh.userData?.meshFeatures && mesh.userData?.structuralMetadata && !mesh.userData?.isSplit) applyVisibilityToMesh(mesh, oidSet);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
21
66
|
//#endregion
|
|
22
67
|
//#region src/mesh-helper/idmap.ts
|
|
23
68
|
var FEATURE_INDEX = 0;
|
|
@@ -108,87 +153,143 @@ function queryFeatureFromIntersection(hit) {
|
|
|
108
153
|
//#endregion
|
|
109
154
|
//#region src/mesh-helper/mesh.ts
|
|
110
155
|
/**
|
|
111
|
-
*
|
|
156
|
+
* 合并多个 feature 的三角形为单一 BufferGeometry(共享顶点属性,index 为并集)
|
|
112
157
|
*/
|
|
113
|
-
function
|
|
114
|
-
|
|
115
|
-
for (let i = 0; i < featureIdAttr.count; i++) {
|
|
116
|
-
const featureId = featureIdAttr.getX(i);
|
|
117
|
-
if (!featureIdMap.has(featureId)) featureIdMap.set(featureId, /* @__PURE__ */ new Set());
|
|
118
|
-
featureIdMap.get(featureId).add(i);
|
|
119
|
-
}
|
|
120
|
-
return featureIdMap;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Create a geometry for a specified feature ID
|
|
124
|
-
*/
|
|
125
|
-
function createGeometryForFeatureId(originalGeometry, featureIdMap, targetFeatureId) {
|
|
158
|
+
function createGeometryForFeatureIdSet(originalGeometry, featureIdAttr, targetFids) {
|
|
159
|
+
if (targetFids.size === 0 || !originalGeometry.index) return null;
|
|
126
160
|
const newGeometry = new BufferGeometry();
|
|
127
|
-
const targetVertexIndices = featureIdMap.get(targetFeatureId);
|
|
128
|
-
if (!targetVertexIndices || targetVertexIndices.size === 0) return null;
|
|
129
161
|
const attributes = originalGeometry.attributes;
|
|
130
162
|
for (const attributeName in attributes) newGeometry.setAttribute(attributeName, attributes[attributeName]);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
163
|
+
const originalIndex = originalGeometry.index.array;
|
|
164
|
+
const newIndices = [];
|
|
165
|
+
for (let i = 0; i < originalIndex.length; i += 3) {
|
|
166
|
+
const a = originalIndex[i];
|
|
167
|
+
const b = originalIndex[i + 1];
|
|
168
|
+
const c = originalIndex[i + 2];
|
|
169
|
+
const fa = featureIdAttr.getX(a);
|
|
170
|
+
if (fa === featureIdAttr.getX(b) && fa === featureIdAttr.getX(c) && targetFids.has(fa)) newIndices.push(a, b, c);
|
|
171
|
+
}
|
|
172
|
+
if (newIndices.length === 0) return null;
|
|
173
|
+
newGeometry.setIndex(newIndices);
|
|
142
174
|
return newGeometry;
|
|
143
175
|
}
|
|
144
176
|
/**
|
|
145
|
-
*
|
|
177
|
+
* 将同一瓦片 mesh 内、属于给定 OID 集合的所有 feature 合并为 **单个** Mesh(每瓦片最多一个)
|
|
146
178
|
*/
|
|
147
|
-
function
|
|
179
|
+
function splitMeshByOidsMerged(originalMesh, oidSet) {
|
|
180
|
+
if (oidSet.size === 0) return null;
|
|
181
|
+
const idMap = originalMesh.userData?.idMap;
|
|
182
|
+
if (!idMap) return null;
|
|
148
183
|
const { meshFeatures, structuralMetadata } = originalMesh.userData;
|
|
149
184
|
const { geometry, featureIds } = meshFeatures;
|
|
150
185
|
const featureId = featureIds[0];
|
|
151
186
|
const featureIdAttr = geometry.getAttribute(`_feature_id_${featureId.attribute}`);
|
|
152
187
|
if (!featureIdAttr) {
|
|
153
188
|
console.warn("No feature ID attribute found");
|
|
154
|
-
return
|
|
155
|
-
}
|
|
156
|
-
const
|
|
157
|
-
const
|
|
158
|
-
for (const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
_oid = propertyData?._oid;
|
|
164
|
-
if (_oid === oid) {
|
|
165
|
-
const newGeometry = createGeometryForFeatureId(geometry, featureIdMap, fid);
|
|
166
|
-
if (newGeometry && newGeometry.attributes.position.count > 0) {
|
|
167
|
-
const newMesh = new Mesh(newGeometry, originalMesh.material.clone());
|
|
168
|
-
newMesh.parent = originalMesh.parent;
|
|
169
|
-
newMesh.position.copy(originalMesh.position);
|
|
170
|
-
newMesh.rotation.copy(originalMesh.rotation);
|
|
171
|
-
newMesh.scale.copy(originalMesh.scale);
|
|
172
|
-
newMesh.matrixWorld.copy(originalMesh.matrixWorld);
|
|
173
|
-
newMesh.userData = {
|
|
174
|
-
...originalMesh.userData,
|
|
175
|
-
featureId: fid,
|
|
176
|
-
oid,
|
|
177
|
-
originalMesh,
|
|
178
|
-
propertyData,
|
|
179
|
-
isSplit: true
|
|
180
|
-
};
|
|
181
|
-
newMesh.name = `feature_${fid}_${oid || ""}`;
|
|
182
|
-
currentBatchMeshes.push(newMesh);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
} catch (e) {
|
|
186
|
-
console.warn(`Failed to get property data for feature ${fid}:`, e);
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
const targetFids = /* @__PURE__ */ new Set();
|
|
192
|
+
const oidsOnMesh = [];
|
|
193
|
+
for (const oid of oidSet) {
|
|
194
|
+
const fid = idMap[oid];
|
|
195
|
+
if (fid !== void 0) {
|
|
196
|
+
targetFids.add(fid);
|
|
197
|
+
oidsOnMesh.push(oid);
|
|
187
198
|
}
|
|
188
|
-
} catch (error) {
|
|
189
|
-
console.warn(`Error creating mesh for feature ${fid}:`, error);
|
|
190
199
|
}
|
|
191
|
-
return
|
|
200
|
+
if (targetFids.size === 0) return null;
|
|
201
|
+
const newGeometry = createGeometryForFeatureIdSet(geometry, featureIdAttr, targetFids);
|
|
202
|
+
if (!newGeometry || newGeometry.attributes.position.count === 0) return null;
|
|
203
|
+
const newMesh = new Mesh(newGeometry, originalMesh.material.clone());
|
|
204
|
+
newMesh.parent = originalMesh.parent;
|
|
205
|
+
newMesh.position.copy(originalMesh.position);
|
|
206
|
+
newMesh.rotation.copy(originalMesh.rotation);
|
|
207
|
+
newMesh.scale.copy(originalMesh.scale);
|
|
208
|
+
newMesh.matrixWorld.copy(originalMesh.matrixWorld);
|
|
209
|
+
oidsOnMesh.sort((a, b) => a - b);
|
|
210
|
+
const primaryOid = oidsOnMesh[0];
|
|
211
|
+
let propertyData = null;
|
|
212
|
+
if (structuralMetadata && idMap[primaryOid] !== void 0) try {
|
|
213
|
+
propertyData = structuralMetadata.getPropertyTableData(featureId.propertyTable, idMap[primaryOid]);
|
|
214
|
+
} catch {}
|
|
215
|
+
newMesh.userData = {
|
|
216
|
+
...originalMesh.userData,
|
|
217
|
+
featureId: idMap[primaryOid],
|
|
218
|
+
oid: primaryOid,
|
|
219
|
+
collectorOids: oidsOnMesh,
|
|
220
|
+
originalMesh,
|
|
221
|
+
propertyData,
|
|
222
|
+
isSplit: true,
|
|
223
|
+
isMergedSplit: true
|
|
224
|
+
};
|
|
225
|
+
newMesh.name = `merged_features_${oidsOnMesh.length}_${primaryOid}`;
|
|
226
|
+
return newMesh;
|
|
227
|
+
}
|
|
228
|
+
/** 瓦片内原始 feature mesh(非 split 子网格) */
|
|
229
|
+
function isFeatureSourceMesh(mesh) {
|
|
230
|
+
const u = mesh.userData;
|
|
231
|
+
return Boolean(u?.meshFeatures && u?.structuralMetadata && !u?.isSplit);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* 从瓦片中获取所有 OID
|
|
235
|
+
*/
|
|
236
|
+
function getAllOidsFromTiles(tiles) {
|
|
237
|
+
const oidSet = /* @__PURE__ */ new Set();
|
|
238
|
+
tiles.group.traverse((child) => {
|
|
239
|
+
const mesh = child;
|
|
240
|
+
if (!isFeatureSourceMesh(mesh)) return;
|
|
241
|
+
const idMap = mesh.userData.idMap;
|
|
242
|
+
if (!idMap) return;
|
|
243
|
+
for (const oid of Object.keys(idMap).map(Number)) oidSet.add(oid);
|
|
244
|
+
});
|
|
245
|
+
return Array.from(oidSet);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* 根据 OID 获取属性数据(从瓦片 structuralMetadata)
|
|
249
|
+
*/
|
|
250
|
+
function getPropertyDataByOid(tiles, oid) {
|
|
251
|
+
let result = null;
|
|
252
|
+
tiles.group.traverse((child) => {
|
|
253
|
+
if (result) return;
|
|
254
|
+
const mesh = child;
|
|
255
|
+
if (!isFeatureSourceMesh(mesh)) return;
|
|
256
|
+
const idMap = mesh.userData.idMap;
|
|
257
|
+
if (!idMap || idMap[oid] === void 0) return;
|
|
258
|
+
const { meshFeatures, structuralMetadata } = mesh.userData;
|
|
259
|
+
const featureId = meshFeatures.featureIds[0];
|
|
260
|
+
const fid = idMap[oid];
|
|
261
|
+
try {
|
|
262
|
+
result = structuralMetadata.getPropertyTableData(featureId.propertyTable, fid);
|
|
263
|
+
} catch {}
|
|
264
|
+
});
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* 单次遍历场景构建 OID → 属性表数据。
|
|
269
|
+
* 批量样式/筛选时使用,避免对每个 OID 重复 traverse(O(n×场景节点))。
|
|
270
|
+
*/
|
|
271
|
+
function getPropertyDataMapFromTiles(tiles) {
|
|
272
|
+
const map = /* @__PURE__ */ new Map();
|
|
273
|
+
tiles.group.traverse((child) => {
|
|
274
|
+
const mesh = child;
|
|
275
|
+
if (!isFeatureSourceMesh(mesh)) return;
|
|
276
|
+
const idMap = mesh.userData.idMap;
|
|
277
|
+
if (!idMap) return;
|
|
278
|
+
const { meshFeatures, structuralMetadata } = mesh.userData;
|
|
279
|
+
const propertyTable = meshFeatures.featureIds[0].propertyTable;
|
|
280
|
+
for (const oid of Object.keys(idMap).map(Number)) {
|
|
281
|
+
if (map.has(oid)) continue;
|
|
282
|
+
const fid = idMap[oid];
|
|
283
|
+
if (fid === void 0) continue;
|
|
284
|
+
try {
|
|
285
|
+
const data = structuralMetadata.getPropertyTableData(propertyTable, fid);
|
|
286
|
+
map.set(oid, data);
|
|
287
|
+
} catch {
|
|
288
|
+
map.set(oid, null);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
return map;
|
|
192
293
|
}
|
|
193
294
|
/**
|
|
194
295
|
* 根据OID获取包含该OID的瓦片mesh
|
|
@@ -197,9 +298,7 @@ function getTileMeshesByOid(tiles, oid) {
|
|
|
197
298
|
const tileMeshes = [];
|
|
198
299
|
tiles.group.traverse((child) => {
|
|
199
300
|
const mesh = child;
|
|
200
|
-
if (mesh
|
|
201
|
-
if (checkMeshContainsOid(mesh, oid)) tileMeshes.push(mesh);
|
|
202
|
-
}
|
|
301
|
+
if (isFeatureSourceMesh(mesh) && checkMeshContainsOid(mesh, oid)) tileMeshes.push(mesh);
|
|
203
302
|
});
|
|
204
303
|
return tileMeshes;
|
|
205
304
|
}
|
|
@@ -208,43 +307,74 @@ function checkMeshContainsOid(mesh, oid) {
|
|
|
208
307
|
if (!idMap) return false;
|
|
209
308
|
return idMap[oid] !== void 0;
|
|
210
309
|
}
|
|
310
|
+
//#endregion
|
|
311
|
+
//#region src/MeshCollector.ts
|
|
312
|
+
/** 去重并排序 OID */
|
|
313
|
+
function normalizeMeshCollectorOids(oids) {
|
|
314
|
+
return [...new Set(oids)].sort((a, b) => a - b);
|
|
315
|
+
}
|
|
211
316
|
/**
|
|
212
|
-
*
|
|
317
|
+
* 与 MeshCollector.getCacheKey()、插件 collectorCache 键一致
|
|
213
318
|
*/
|
|
214
|
-
function
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return
|
|
319
|
+
function meshCollectorQueryCacheKey(query) {
|
|
320
|
+
const oidsNorm = normalizeMeshCollectorOids(query.oids ?? []);
|
|
321
|
+
const oidPart = oidsNorm.length > 0 ? oidsNorm.join(",") : "*";
|
|
322
|
+
const condRaw = query.condition?.trim() ?? "";
|
|
323
|
+
return `${oidPart}@@${condRaw === "" ? "_" : encodeURIComponent(condRaw)}`;
|
|
324
|
+
}
|
|
325
|
+
/** @deprecated 请使用 meshCollectorQueryCacheKey({ oids }) */
|
|
326
|
+
function meshCollectorGroupKey(oids) {
|
|
327
|
+
return meshCollectorQueryCacheKey({ oids });
|
|
223
328
|
}
|
|
224
|
-
//#endregion
|
|
225
|
-
//#region src/MeshCollector.ts
|
|
226
329
|
/**
|
|
227
|
-
* MeshCollector -
|
|
228
|
-
* 随着瓦片变化,会自动更新 meshes 并触发 mesh-change 事件
|
|
330
|
+
* MeshCollector - 按查询条件监听并收集 split mesh
|
|
229
331
|
*/
|
|
230
332
|
var MeshCollector = class extends EventDispatcher {
|
|
231
|
-
|
|
333
|
+
queryOids;
|
|
334
|
+
condition;
|
|
335
|
+
cacheKey;
|
|
232
336
|
plugin;
|
|
233
337
|
_meshes = [];
|
|
234
338
|
_disposed = false;
|
|
235
|
-
constructor(
|
|
339
|
+
constructor(query, plugin) {
|
|
236
340
|
super();
|
|
237
|
-
|
|
341
|
+
const oids = normalizeMeshCollectorOids(query.oids ?? []);
|
|
342
|
+
const condition = query.condition?.trim() || void 0;
|
|
343
|
+
if (oids.length === 0 && !condition) throw new Error("MeshCollector requires at least one OID in oids and/or a non-empty condition");
|
|
344
|
+
this.queryOids = oids;
|
|
345
|
+
this.condition = condition;
|
|
346
|
+
this.cacheKey = meshCollectorQueryCacheKey({
|
|
347
|
+
oids,
|
|
348
|
+
condition
|
|
349
|
+
});
|
|
238
350
|
this.plugin = plugin;
|
|
239
351
|
plugin._registerCollector(this);
|
|
240
352
|
this._updateMeshes();
|
|
241
353
|
}
|
|
354
|
+
getCacheKey() {
|
|
355
|
+
return this.cacheKey;
|
|
356
|
+
}
|
|
357
|
+
/** 查询里显式传入的 OID(规范化后);仅用 condition 筛选时可能为空数组 */
|
|
358
|
+
getOids() {
|
|
359
|
+
return this.queryOids;
|
|
360
|
+
}
|
|
361
|
+
/** 有显式 OID 时返回第一个;否则无意义(可能为 undefined) */
|
|
362
|
+
getOid() {
|
|
363
|
+
return this.queryOids[0];
|
|
364
|
+
}
|
|
242
365
|
get meshes() {
|
|
243
366
|
return this._meshes;
|
|
244
367
|
}
|
|
368
|
+
/** 与 setStyle 一致的条件表达式(若有) */
|
|
369
|
+
getCondition() {
|
|
370
|
+
return this.condition;
|
|
371
|
+
}
|
|
245
372
|
_updateMeshes() {
|
|
246
373
|
if (this._disposed) return;
|
|
247
|
-
const newMeshes = this.plugin.
|
|
374
|
+
const newMeshes = this.plugin._getMeshesForCollectorQueryInternal({
|
|
375
|
+
oids: this.queryOids,
|
|
376
|
+
condition: this.condition
|
|
377
|
+
});
|
|
248
378
|
if (newMeshes.length !== this._meshes.length || newMeshes.some((mesh, i) => mesh !== this._meshes[i])) {
|
|
249
379
|
this._meshes = newMeshes;
|
|
250
380
|
this.dispatchEvent({
|
|
@@ -253,9 +383,6 @@ var MeshCollector = class extends EventDispatcher {
|
|
|
253
383
|
});
|
|
254
384
|
}
|
|
255
385
|
}
|
|
256
|
-
getOid() {
|
|
257
|
-
return this.oid;
|
|
258
|
-
}
|
|
259
386
|
dispose() {
|
|
260
387
|
if (this._disposed) return;
|
|
261
388
|
this._disposed = true;
|
|
@@ -264,6 +391,51 @@ var MeshCollector = class extends EventDispatcher {
|
|
|
264
391
|
}
|
|
265
392
|
};
|
|
266
393
|
//#endregion
|
|
394
|
+
//#region src/plugin/style-condition-eval.ts
|
|
395
|
+
/**
|
|
396
|
+
* 与 StyleHelper 中 `show`、`conditions` 条件项的表达式求值一致
|
|
397
|
+
* 在 propertyData 的键作为变量名的上下文中执行 `Boolean(expr)`
|
|
398
|
+
*
|
|
399
|
+
* 实现:对每个表达式字符串只编译一次 `new Function('data', 'with(d){...}')`,
|
|
400
|
+
* 避免按「表达式 × 属性键集合」重复编译,也避免每次求值排序/拼接 cacheKey。
|
|
401
|
+
*/
|
|
402
|
+
var compiledCache = /* @__PURE__ */ new Map();
|
|
403
|
+
var MAX_CACHE_ENTRIES = 512;
|
|
404
|
+
function getCompiled(expr) {
|
|
405
|
+
let fn = compiledCache.get(expr);
|
|
406
|
+
if (fn) return fn;
|
|
407
|
+
try {
|
|
408
|
+
fn = new Function("data", `var d = data != null && typeof data === "object" ? data : {};
|
|
409
|
+
with (d) { return Boolean(${expr}); }`);
|
|
410
|
+
} catch {
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
413
|
+
if (compiledCache.size >= MAX_CACHE_ENTRIES) {
|
|
414
|
+
const first = compiledCache.keys().next().value;
|
|
415
|
+
if (first !== void 0) compiledCache.delete(first);
|
|
416
|
+
}
|
|
417
|
+
compiledCache.set(expr, fn);
|
|
418
|
+
return fn;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* 清空表达式编译缓存(热更新或单测可调用)
|
|
422
|
+
*/
|
|
423
|
+
function clearStyleConditionCache() {
|
|
424
|
+
compiledCache.clear();
|
|
425
|
+
}
|
|
426
|
+
function evaluateStyleCondition(expr, propertyData) {
|
|
427
|
+
if (expr === true) return true;
|
|
428
|
+
if (expr === false) return false;
|
|
429
|
+
if (typeof expr !== "string" || !expr.trim()) return true;
|
|
430
|
+
const fn = getCompiled(expr.trim());
|
|
431
|
+
if (!fn) return false;
|
|
432
|
+
try {
|
|
433
|
+
return fn(propertyData ?? {});
|
|
434
|
+
} catch {
|
|
435
|
+
return false;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
//#endregion
|
|
267
439
|
//#region src/utils/build-textures.ts
|
|
268
440
|
/**
|
|
269
441
|
* Build textures from GLTF data
|
|
@@ -566,15 +738,24 @@ function polygonIntersectsRect(polygon, minX, minY, maxX, maxY) {
|
|
|
566
738
|
return false;
|
|
567
739
|
}
|
|
568
740
|
/**
|
|
741
|
+
* 将 structure 中的 bbox 数组转为 Box3。
|
|
742
|
+
* 约定与 `selectByBox` 一致:`[minX, minY, minZ, maxX, maxY, maxZ]`,至少 6 个数。
|
|
743
|
+
*/
|
|
744
|
+
function bboxArrayToBox3(bbox) {
|
|
745
|
+
if (!bbox || bbox.length < 6) return null;
|
|
746
|
+
const box = new Box3();
|
|
747
|
+
box.min.set(bbox[0], bbox[1], bbox[2]);
|
|
748
|
+
box.max.set(bbox[3], bbox[4], bbox[5]);
|
|
749
|
+
return box;
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
569
752
|
* 从 OID 节点映射中按 Box3 范围筛选构件
|
|
570
753
|
*/
|
|
571
754
|
function selectByBoxFromOidMap(oidNodeMap, box) {
|
|
572
755
|
const result = [];
|
|
573
|
-
const nodeBox = new Box3();
|
|
574
756
|
for (const [oid, node] of oidNodeMap) {
|
|
575
|
-
|
|
576
|
-
nodeBox
|
|
577
|
-
nodeBox.max.set(node.bbox[3], node.bbox[4], node.bbox[5]);
|
|
757
|
+
const nodeBox = bboxArrayToBox3(node.bbox);
|
|
758
|
+
if (!nodeBox) continue;
|
|
578
759
|
if (box.intersectsBox(nodeBox)) result.push(oid);
|
|
579
760
|
}
|
|
580
761
|
return result;
|
|
@@ -619,7 +800,394 @@ function selectByPolygonFromOidMap(oidNodeMap, polygon, axis = "xz") {
|
|
|
619
800
|
return result;
|
|
620
801
|
}
|
|
621
802
|
//#endregion
|
|
622
|
-
//#region
|
|
803
|
+
//#region src/utils/color-input.ts
|
|
804
|
+
function toColor(value) {
|
|
805
|
+
return value instanceof Color ? value : new Color(value);
|
|
806
|
+
}
|
|
807
|
+
//#endregion
|
|
808
|
+
//#region node_modules/.pnpm/fflate@0.8.2/node_modules/fflate/esm/browser.js
|
|
809
|
+
var u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;
|
|
810
|
+
var fleb = new u8([
|
|
811
|
+
0,
|
|
812
|
+
0,
|
|
813
|
+
0,
|
|
814
|
+
0,
|
|
815
|
+
0,
|
|
816
|
+
0,
|
|
817
|
+
0,
|
|
818
|
+
0,
|
|
819
|
+
1,
|
|
820
|
+
1,
|
|
821
|
+
1,
|
|
822
|
+
1,
|
|
823
|
+
2,
|
|
824
|
+
2,
|
|
825
|
+
2,
|
|
826
|
+
2,
|
|
827
|
+
3,
|
|
828
|
+
3,
|
|
829
|
+
3,
|
|
830
|
+
3,
|
|
831
|
+
4,
|
|
832
|
+
4,
|
|
833
|
+
4,
|
|
834
|
+
4,
|
|
835
|
+
5,
|
|
836
|
+
5,
|
|
837
|
+
5,
|
|
838
|
+
5,
|
|
839
|
+
0,
|
|
840
|
+
0,
|
|
841
|
+
0,
|
|
842
|
+
0
|
|
843
|
+
]);
|
|
844
|
+
var fdeb = new u8([
|
|
845
|
+
0,
|
|
846
|
+
0,
|
|
847
|
+
0,
|
|
848
|
+
0,
|
|
849
|
+
1,
|
|
850
|
+
1,
|
|
851
|
+
2,
|
|
852
|
+
2,
|
|
853
|
+
3,
|
|
854
|
+
3,
|
|
855
|
+
4,
|
|
856
|
+
4,
|
|
857
|
+
5,
|
|
858
|
+
5,
|
|
859
|
+
6,
|
|
860
|
+
6,
|
|
861
|
+
7,
|
|
862
|
+
7,
|
|
863
|
+
8,
|
|
864
|
+
8,
|
|
865
|
+
9,
|
|
866
|
+
9,
|
|
867
|
+
10,
|
|
868
|
+
10,
|
|
869
|
+
11,
|
|
870
|
+
11,
|
|
871
|
+
12,
|
|
872
|
+
12,
|
|
873
|
+
13,
|
|
874
|
+
13,
|
|
875
|
+
0,
|
|
876
|
+
0
|
|
877
|
+
]);
|
|
878
|
+
var clim = new u8([
|
|
879
|
+
16,
|
|
880
|
+
17,
|
|
881
|
+
18,
|
|
882
|
+
0,
|
|
883
|
+
8,
|
|
884
|
+
7,
|
|
885
|
+
9,
|
|
886
|
+
6,
|
|
887
|
+
10,
|
|
888
|
+
5,
|
|
889
|
+
11,
|
|
890
|
+
4,
|
|
891
|
+
12,
|
|
892
|
+
3,
|
|
893
|
+
13,
|
|
894
|
+
2,
|
|
895
|
+
14,
|
|
896
|
+
1,
|
|
897
|
+
15
|
|
898
|
+
]);
|
|
899
|
+
var freb = function(eb, start) {
|
|
900
|
+
var b = new u16(31);
|
|
901
|
+
for (var i = 0; i < 31; ++i) b[i] = start += 1 << eb[i - 1];
|
|
902
|
+
var r = new i32(b[30]);
|
|
903
|
+
for (var i = 1; i < 30; ++i) for (var j = b[i]; j < b[i + 1]; ++j) r[j] = j - b[i] << 5 | i;
|
|
904
|
+
return {
|
|
905
|
+
b,
|
|
906
|
+
r
|
|
907
|
+
};
|
|
908
|
+
};
|
|
909
|
+
var _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;
|
|
910
|
+
fl[28] = 258, revfl[258] = 28;
|
|
911
|
+
var fd = freb(fdeb, 0).b;
|
|
912
|
+
var rev = new u16(32768);
|
|
913
|
+
for (var i = 0; i < 32768; ++i) {
|
|
914
|
+
var x = (i & 43690) >> 1 | (i & 21845) << 1;
|
|
915
|
+
x = (x & 52428) >> 2 | (x & 13107) << 2;
|
|
916
|
+
x = (x & 61680) >> 4 | (x & 3855) << 4;
|
|
917
|
+
rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
|
|
918
|
+
}
|
|
919
|
+
var hMap = (function(cd, mb, r) {
|
|
920
|
+
var s = cd.length;
|
|
921
|
+
var i = 0;
|
|
922
|
+
var l = new u16(mb);
|
|
923
|
+
for (; i < s; ++i) if (cd[i]) ++l[cd[i] - 1];
|
|
924
|
+
var le = new u16(mb);
|
|
925
|
+
for (i = 1; i < mb; ++i) le[i] = le[i - 1] + l[i - 1] << 1;
|
|
926
|
+
var co;
|
|
927
|
+
if (r) {
|
|
928
|
+
co = new u16(1 << mb);
|
|
929
|
+
var rvb = 15 - mb;
|
|
930
|
+
for (i = 0; i < s; ++i) if (cd[i]) {
|
|
931
|
+
var sv = i << 4 | cd[i];
|
|
932
|
+
var r_1 = mb - cd[i];
|
|
933
|
+
var v = le[cd[i] - 1]++ << r_1;
|
|
934
|
+
for (var m = v | (1 << r_1) - 1; v <= m; ++v) co[rev[v] >> rvb] = sv;
|
|
935
|
+
}
|
|
936
|
+
} else {
|
|
937
|
+
co = new u16(s);
|
|
938
|
+
for (i = 0; i < s; ++i) if (cd[i]) co[i] = rev[le[cd[i] - 1]++] >> 15 - cd[i];
|
|
939
|
+
}
|
|
940
|
+
return co;
|
|
941
|
+
});
|
|
942
|
+
var flt = new u8(288);
|
|
943
|
+
for (var i = 0; i < 144; ++i) flt[i] = 8;
|
|
944
|
+
for (var i = 144; i < 256; ++i) flt[i] = 9;
|
|
945
|
+
for (var i = 256; i < 280; ++i) flt[i] = 7;
|
|
946
|
+
for (var i = 280; i < 288; ++i) flt[i] = 8;
|
|
947
|
+
var fdt = new u8(32);
|
|
948
|
+
for (var i = 0; i < 32; ++i) fdt[i] = 5;
|
|
949
|
+
var flrm = /* @__PURE__ */ hMap(flt, 9, 1), fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
|
|
950
|
+
var max = function(a) {
|
|
951
|
+
var m = a[0];
|
|
952
|
+
for (var i = 1; i < a.length; ++i) if (a[i] > m) m = a[i];
|
|
953
|
+
return m;
|
|
954
|
+
};
|
|
955
|
+
var bits = function(d, p, m) {
|
|
956
|
+
var o = p / 8 | 0;
|
|
957
|
+
return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
|
|
958
|
+
};
|
|
959
|
+
var bits16 = function(d, p) {
|
|
960
|
+
var o = p / 8 | 0;
|
|
961
|
+
return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
|
|
962
|
+
};
|
|
963
|
+
var shft = function(p) {
|
|
964
|
+
return (p + 7) / 8 | 0;
|
|
965
|
+
};
|
|
966
|
+
var slc = function(v, s, e) {
|
|
967
|
+
if (s == null || s < 0) s = 0;
|
|
968
|
+
if (e == null || e > v.length) e = v.length;
|
|
969
|
+
return new u8(v.subarray(s, e));
|
|
970
|
+
};
|
|
971
|
+
var ec = [
|
|
972
|
+
"unexpected EOF",
|
|
973
|
+
"invalid block type",
|
|
974
|
+
"invalid length/literal",
|
|
975
|
+
"invalid distance",
|
|
976
|
+
"stream finished",
|
|
977
|
+
"no stream handler",
|
|
978
|
+
,
|
|
979
|
+
"no callback",
|
|
980
|
+
"invalid UTF-8 data",
|
|
981
|
+
"extra field too long",
|
|
982
|
+
"date not in range 1980-2099",
|
|
983
|
+
"filename too long",
|
|
984
|
+
"stream finishing",
|
|
985
|
+
"invalid zip data"
|
|
986
|
+
];
|
|
987
|
+
var err = function(ind, msg, nt) {
|
|
988
|
+
var e = new Error(msg || ec[ind]);
|
|
989
|
+
e.code = ind;
|
|
990
|
+
if (Error.captureStackTrace) Error.captureStackTrace(e, err);
|
|
991
|
+
if (!nt) throw e;
|
|
992
|
+
return e;
|
|
993
|
+
};
|
|
994
|
+
var inflt = function(dat, st, buf, dict) {
|
|
995
|
+
var sl = dat.length, dl = dict ? dict.length : 0;
|
|
996
|
+
if (!sl || st.f && !st.l) return buf || new u8(0);
|
|
997
|
+
var noBuf = !buf;
|
|
998
|
+
var resize = noBuf || st.i != 2;
|
|
999
|
+
var noSt = st.i;
|
|
1000
|
+
if (noBuf) buf = new u8(sl * 3);
|
|
1001
|
+
var cbuf = function(l) {
|
|
1002
|
+
var bl = buf.length;
|
|
1003
|
+
if (l > bl) {
|
|
1004
|
+
var nbuf = new u8(Math.max(bl * 2, l));
|
|
1005
|
+
nbuf.set(buf);
|
|
1006
|
+
buf = nbuf;
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
|
|
1010
|
+
var tbts = sl * 8;
|
|
1011
|
+
do {
|
|
1012
|
+
if (!lm) {
|
|
1013
|
+
final = bits(dat, pos, 1);
|
|
1014
|
+
var type = bits(dat, pos + 1, 3);
|
|
1015
|
+
pos += 3;
|
|
1016
|
+
if (!type) {
|
|
1017
|
+
var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
|
|
1018
|
+
if (t > sl) {
|
|
1019
|
+
if (noSt) err(0);
|
|
1020
|
+
break;
|
|
1021
|
+
}
|
|
1022
|
+
if (resize) cbuf(bt + l);
|
|
1023
|
+
buf.set(dat.subarray(s, t), bt);
|
|
1024
|
+
st.b = bt += l, st.p = pos = t * 8, st.f = final;
|
|
1025
|
+
continue;
|
|
1026
|
+
} else if (type == 1) lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
|
|
1027
|
+
else if (type == 2) {
|
|
1028
|
+
var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
|
1029
|
+
var tl = hLit + bits(dat, pos + 5, 31) + 1;
|
|
1030
|
+
pos += 14;
|
|
1031
|
+
var ldt = new u8(tl);
|
|
1032
|
+
var clt = new u8(19);
|
|
1033
|
+
for (var i = 0; i < hcLen; ++i) clt[clim[i]] = bits(dat, pos + i * 3, 7);
|
|
1034
|
+
pos += hcLen * 3;
|
|
1035
|
+
var clb = max(clt), clbmsk = (1 << clb) - 1;
|
|
1036
|
+
var clm = hMap(clt, clb, 1);
|
|
1037
|
+
for (var i = 0; i < tl;) {
|
|
1038
|
+
var r = clm[bits(dat, pos, clbmsk)];
|
|
1039
|
+
pos += r & 15;
|
|
1040
|
+
var s = r >> 4;
|
|
1041
|
+
if (s < 16) ldt[i++] = s;
|
|
1042
|
+
else {
|
|
1043
|
+
var c = 0, n = 0;
|
|
1044
|
+
if (s == 16) n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
|
|
1045
|
+
else if (s == 17) n = 3 + bits(dat, pos, 7), pos += 3;
|
|
1046
|
+
else if (s == 18) n = 11 + bits(dat, pos, 127), pos += 7;
|
|
1047
|
+
while (n--) ldt[i++] = c;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
|
|
1051
|
+
lbt = max(lt);
|
|
1052
|
+
dbt = max(dt);
|
|
1053
|
+
lm = hMap(lt, lbt, 1);
|
|
1054
|
+
dm = hMap(dt, dbt, 1);
|
|
1055
|
+
} else err(1);
|
|
1056
|
+
if (pos > tbts) {
|
|
1057
|
+
if (noSt) err(0);
|
|
1058
|
+
break;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
if (resize) cbuf(bt + 131072);
|
|
1062
|
+
var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
|
1063
|
+
var lpos = pos;
|
|
1064
|
+
for (;; lpos = pos) {
|
|
1065
|
+
var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
|
|
1066
|
+
pos += c & 15;
|
|
1067
|
+
if (pos > tbts) {
|
|
1068
|
+
if (noSt) err(0);
|
|
1069
|
+
break;
|
|
1070
|
+
}
|
|
1071
|
+
if (!c) err(2);
|
|
1072
|
+
if (sym < 256) buf[bt++] = sym;
|
|
1073
|
+
else if (sym == 256) {
|
|
1074
|
+
lpos = pos, lm = null;
|
|
1075
|
+
break;
|
|
1076
|
+
} else {
|
|
1077
|
+
var add = sym - 254;
|
|
1078
|
+
if (sym > 264) {
|
|
1079
|
+
var i = sym - 257, b = fleb[i];
|
|
1080
|
+
add = bits(dat, pos, (1 << b) - 1) + fl[i];
|
|
1081
|
+
pos += b;
|
|
1082
|
+
}
|
|
1083
|
+
var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
|
|
1084
|
+
if (!d) err(3);
|
|
1085
|
+
pos += d & 15;
|
|
1086
|
+
var dt = fd[dsym];
|
|
1087
|
+
if (dsym > 3) {
|
|
1088
|
+
var b = fdeb[dsym];
|
|
1089
|
+
dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
|
|
1090
|
+
}
|
|
1091
|
+
if (pos > tbts) {
|
|
1092
|
+
if (noSt) err(0);
|
|
1093
|
+
break;
|
|
1094
|
+
}
|
|
1095
|
+
if (resize) cbuf(bt + 131072);
|
|
1096
|
+
var end = bt + add;
|
|
1097
|
+
if (bt < dt) {
|
|
1098
|
+
var shift = dl - dt, dend = Math.min(dt, end);
|
|
1099
|
+
if (shift + bt < 0) err(3);
|
|
1100
|
+
for (; bt < dend; ++bt) buf[bt] = dict[shift + bt];
|
|
1101
|
+
}
|
|
1102
|
+
for (; bt < end; ++bt) buf[bt] = buf[bt - dt];
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
st.l = lm, st.p = lpos, st.b = bt, st.f = final;
|
|
1106
|
+
if (lm) final = 1, st.m = lbt, st.d = dm, st.n = dbt;
|
|
1107
|
+
} while (!final);
|
|
1108
|
+
return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
|
|
1109
|
+
};
|
|
1110
|
+
var et = /* @__PURE__ */ new u8(0);
|
|
1111
|
+
var gzs = function(d) {
|
|
1112
|
+
if (d[0] != 31 || d[1] != 139 || d[2] != 8) err(6, "invalid gzip data");
|
|
1113
|
+
var flg = d[3];
|
|
1114
|
+
var st = 10;
|
|
1115
|
+
if (flg & 4) st += (d[10] | d[11] << 8) + 2;
|
|
1116
|
+
for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++]);
|
|
1117
|
+
return st + (flg & 2);
|
|
1118
|
+
};
|
|
1119
|
+
var gzl = function(d) {
|
|
1120
|
+
var l = d.length;
|
|
1121
|
+
return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16 | d[l - 1] << 24) >>> 0;
|
|
1122
|
+
};
|
|
1123
|
+
/**
|
|
1124
|
+
* Expands GZIP data
|
|
1125
|
+
* @param data The data to decompress
|
|
1126
|
+
* @param opts The decompression options
|
|
1127
|
+
* @returns The decompressed version of the data
|
|
1128
|
+
*/
|
|
1129
|
+
function gunzipSync(data, opts) {
|
|
1130
|
+
var st = gzs(data);
|
|
1131
|
+
if (st + 8 > data.length) err(6, "invalid gzip data");
|
|
1132
|
+
return inflt(data.subarray(st, -8), { i: 2 }, opts && opts.out || new u8(gzl(data)), opts && opts.dictionary);
|
|
1133
|
+
}
|
|
1134
|
+
var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
|
|
1135
|
+
try {
|
|
1136
|
+
td.decode(et, { stream: true });
|
|
1137
|
+
} catch (e) {}
|
|
1138
|
+
//#endregion
|
|
1139
|
+
//#region src/utils/tileset-structure-uri.ts
|
|
1140
|
+
/** 从 tileset 取内嵌 structure 的 data URI(优先 MapTalks:`asset.extras.maptalks.structureUri`) */
|
|
1141
|
+
function getStructureDataUriFromTileset(root) {
|
|
1142
|
+
if (!root) return null;
|
|
1143
|
+
const maptalks = (root.asset?.extras)?.maptalks;
|
|
1144
|
+
if (maptalks && typeof maptalks === "object") {
|
|
1145
|
+
const uri = maptalks.structureUri;
|
|
1146
|
+
if (typeof uri === "string" && uri.trim()) return uri.trim();
|
|
1147
|
+
}
|
|
1148
|
+
const legacy = root.structureUri;
|
|
1149
|
+
if (typeof legacy === "string" && legacy.trim()) return legacy.trim();
|
|
1150
|
+
return null;
|
|
1151
|
+
}
|
|
1152
|
+
function base64ToUint8Array(b64) {
|
|
1153
|
+
const clean = b64.replace(/\s/g, "");
|
|
1154
|
+
if (typeof globalThis.atob === "function") {
|
|
1155
|
+
const bin = globalThis.atob(clean);
|
|
1156
|
+
const out = new Uint8Array(bin.length);
|
|
1157
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
1158
|
+
return out;
|
|
1159
|
+
}
|
|
1160
|
+
if (typeof Buffer !== "undefined") return new Uint8Array(Buffer.from(clean, "base64"));
|
|
1161
|
+
throw new Error("[tileset-structure-uri] No base64 decoder available");
|
|
1162
|
+
}
|
|
1163
|
+
/**
|
|
1164
|
+
* 同步解析 `data:application/x-gzip;base64,...`:base64 → 二进制 → gunzip → UTF-8 文本。
|
|
1165
|
+
*/
|
|
1166
|
+
function decodeGzipBase64DataUriSync(dataUri) {
|
|
1167
|
+
const comma = dataUri.indexOf(",");
|
|
1168
|
+
if (comma < 0) throw new Error("[tileset-structure-uri] Invalid data URI: missing comma");
|
|
1169
|
+
if (!dataUri.slice(0, comma).toLowerCase().includes("base64")) throw new Error("[tileset-structure-uri] Expected base64 data URI (e.g. data:application/x-gzip;base64,...)");
|
|
1170
|
+
const raw = gunzipSync(base64ToUint8Array(dataUri.slice(comma + 1)));
|
|
1171
|
+
return new TextDecoder("utf-8").decode(raw);
|
|
1172
|
+
}
|
|
1173
|
+
/**
|
|
1174
|
+
* 从已加载的根 tileset 读取内嵌 structure(`asset.extras.maptalks.structureUri`,
|
|
1175
|
+
* 若无则回退根级 `structureUri`),同步解码并解析。
|
|
1176
|
+
* - 无有效 URI 或解析失败时返回 `null`(不抛错)。
|
|
1177
|
+
*/
|
|
1178
|
+
function parseEmbeddedStructureDataFromTilesSync(tiles) {
|
|
1179
|
+
const uri = getStructureDataUriFromTileset(tiles.rootTileset);
|
|
1180
|
+
if (!uri) return null;
|
|
1181
|
+
try {
|
|
1182
|
+
const text = decodeGzipBase64DataUriSync(uri);
|
|
1183
|
+
return JSON.parse(text);
|
|
1184
|
+
} catch (e) {
|
|
1185
|
+
console.warn("[GLTFParserPlugin] Failed to decode tileset structureUri:", e);
|
|
1186
|
+
return null;
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
//#endregion
|
|
1190
|
+
//#region node_modules/.pnpm/3d-tiles-renderer@0.4.23_three@0.183.2/node_modules/3d-tiles-renderer/build/constants-D7SEibTb.js
|
|
623
1191
|
var N = 6378137;
|
|
624
1192
|
//#endregion
|
|
625
1193
|
//#region node_modules/.pnpm/three@0.183.2/node_modules/three/examples/jsm/postprocessing/Pass.js
|
|
@@ -700,22 +1268,22 @@ var FullScreenQuad = class {
|
|
|
700
1268
|
function q(a, e, t) {
|
|
701
1269
|
return a && e in a ? a[e] : t;
|
|
702
1270
|
}
|
|
703
|
-
function
|
|
1271
|
+
function An(a) {
|
|
704
1272
|
return a !== "BOOLEAN" && a !== "STRING" && a !== "ENUM";
|
|
705
1273
|
}
|
|
706
|
-
function
|
|
1274
|
+
function qi(a) {
|
|
707
1275
|
return /^FLOAT/.test(a);
|
|
708
1276
|
}
|
|
709
|
-
function
|
|
1277
|
+
function He(a) {
|
|
710
1278
|
return /^VEC/.test(a);
|
|
711
1279
|
}
|
|
712
|
-
function
|
|
1280
|
+
function qe(a) {
|
|
713
1281
|
return /^MAT/.test(a);
|
|
714
1282
|
}
|
|
715
|
-
function
|
|
716
|
-
return
|
|
1283
|
+
function In(a, e, t, s = null) {
|
|
1284
|
+
return qe(t) || He(t) ? s.fromArray(a, e) : a[e];
|
|
717
1285
|
}
|
|
718
|
-
function
|
|
1286
|
+
function Gt(a) {
|
|
719
1287
|
const { type: e, componentType: t } = a;
|
|
720
1288
|
switch (e) {
|
|
721
1289
|
case "SCALAR": return t === "INT64" ? 0n : 0;
|
|
@@ -730,7 +1298,7 @@ function Vt(a) {
|
|
|
730
1298
|
case "ENUM": return 0;
|
|
731
1299
|
}
|
|
732
1300
|
}
|
|
733
|
-
function
|
|
1301
|
+
function Ts(a, e) {
|
|
734
1302
|
if (e == null) return !1;
|
|
735
1303
|
switch (a) {
|
|
736
1304
|
case "SCALAR": return typeof e == "number" || typeof e == "bigint";
|
|
@@ -746,7 +1314,7 @@ function ys(a, e) {
|
|
|
746
1314
|
}
|
|
747
1315
|
throw new Error("ClassProperty: invalid type.");
|
|
748
1316
|
}
|
|
749
|
-
function
|
|
1317
|
+
function Fe(a, e = null) {
|
|
750
1318
|
switch (a) {
|
|
751
1319
|
case "INT8": return Int8Array;
|
|
752
1320
|
case "INT16": return Int16Array;
|
|
@@ -765,16 +1333,16 @@ function De(a, e = null) {
|
|
|
765
1333
|
}
|
|
766
1334
|
throw new Error("ClassProperty: invalid type.");
|
|
767
1335
|
}
|
|
768
|
-
function
|
|
1336
|
+
function Wi(a, e = null) {
|
|
769
1337
|
if (a.array) {
|
|
770
1338
|
e = e && Array.isArray(e) ? e : [], e.length = a.count;
|
|
771
|
-
for (let s = 0, n = e.length; s < n; s++) e[s] =
|
|
772
|
-
} else e =
|
|
1339
|
+
for (let s = 0, n = e.length; s < n; s++) e[s] = at(a, e[s]);
|
|
1340
|
+
} else e = at(a, e);
|
|
773
1341
|
return e;
|
|
774
1342
|
}
|
|
775
|
-
function
|
|
1343
|
+
function at(a, e = null) {
|
|
776
1344
|
const t = a.default, s = a.type;
|
|
777
|
-
if (e = e ||
|
|
1345
|
+
if (e = e || Gt(a), t === null) {
|
|
778
1346
|
switch (s) {
|
|
779
1347
|
case "SCALAR": return 0;
|
|
780
1348
|
case "VEC2": return e.set(0, 0);
|
|
@@ -788,31 +1356,31 @@ function nt(a, e = null) {
|
|
|
788
1356
|
case "ENUM": return "";
|
|
789
1357
|
}
|
|
790
1358
|
throw new Error("ClassProperty: invalid type.");
|
|
791
|
-
} else if (
|
|
792
|
-
else if (
|
|
1359
|
+
} else if (qe(s)) e.fromArray(t);
|
|
1360
|
+
else if (He(s)) e.fromArray(t);
|
|
793
1361
|
else return t;
|
|
794
1362
|
}
|
|
795
|
-
function
|
|
1363
|
+
function ji(a, e) {
|
|
796
1364
|
if (a.noData === null) return e;
|
|
797
1365
|
const t = a.noData, s = a.type;
|
|
798
1366
|
if (Array.isArray(e)) for (let r = 0, o = e.length; r < o; r++) e[r] = n(e[r]);
|
|
799
1367
|
else e = n(e);
|
|
800
1368
|
return e;
|
|
801
1369
|
function n(r) {
|
|
802
|
-
return i(r) && (r =
|
|
1370
|
+
return i(r) && (r = at(a, r)), r;
|
|
803
1371
|
}
|
|
804
1372
|
function i(r) {
|
|
805
|
-
if (
|
|
1373
|
+
if (qe(s)) {
|
|
806
1374
|
const o = r.elements;
|
|
807
1375
|
for (let l = 0, c = t.length; l < c; l++) if (t[l] !== o[l]) return !1;
|
|
808
1376
|
return !0;
|
|
809
|
-
} else if (
|
|
1377
|
+
} else if (He(s)) {
|
|
810
1378
|
for (let o = 0, l = t.length; o < l; o++) if (t[o] !== r.getComponent(o)) return !1;
|
|
811
1379
|
return !0;
|
|
812
1380
|
} else return t === r;
|
|
813
1381
|
}
|
|
814
1382
|
}
|
|
815
|
-
function
|
|
1383
|
+
function Xi(a, e) {
|
|
816
1384
|
switch (a) {
|
|
817
1385
|
case "INT8": return Math.max(e / 127, -1);
|
|
818
1386
|
case "INT16": return Math.max(e, 32767, -1);
|
|
@@ -824,13 +1392,13 @@ function Gi(a, e) {
|
|
|
824
1392
|
case "UINT64": return Number(e) / 0x10000000000000000;
|
|
825
1393
|
}
|
|
826
1394
|
}
|
|
827
|
-
function
|
|
1395
|
+
function Yi(a, e) {
|
|
828
1396
|
const { type: t, componentType: s, scale: n, offset: i, normalized: r } = a;
|
|
829
1397
|
if (Array.isArray(e)) for (let h = 0, d = e.length; h < d; h++) e[h] = o(e[h]);
|
|
830
1398
|
else e = o(e);
|
|
831
1399
|
return e;
|
|
832
1400
|
function o(h) {
|
|
833
|
-
return
|
|
1401
|
+
return qe(t) ? h = c(h) : He(t) ? h = l(h) : h = u(h), h;
|
|
834
1402
|
}
|
|
835
1403
|
function l(h) {
|
|
836
1404
|
return h.x = u(h.x), h.y = u(h.y), "z" in h && (h.z = u(h.z)), "w" in h && (h.w = u(h.w)), h;
|
|
@@ -841,24 +1409,24 @@ function zi(a, e) {
|
|
|
841
1409
|
return h;
|
|
842
1410
|
}
|
|
843
1411
|
function u(h) {
|
|
844
|
-
return r && (h =
|
|
1412
|
+
return r && (h = Xi(s, h)), (r || qi(s)) && (h = h * n + i), h;
|
|
845
1413
|
}
|
|
846
1414
|
}
|
|
847
|
-
function
|
|
1415
|
+
function Zt(a, e, t = null) {
|
|
848
1416
|
if (a.array) {
|
|
849
1417
|
Array.isArray(e) || (e = new Array(a.count || 0)), e.length = t !== null ? t : a.count;
|
|
850
|
-
for (let s = 0, n = e.length; s < n; s++)
|
|
851
|
-
} else
|
|
1418
|
+
for (let s = 0, n = e.length; s < n; s++) Ts(a.type, e[s]) || (e[s] = Gt(a));
|
|
1419
|
+
} else Ts(a.type, e) || (e = Gt(a));
|
|
852
1420
|
return e;
|
|
853
1421
|
}
|
|
854
|
-
function
|
|
1422
|
+
function lt(a, e) {
|
|
855
1423
|
for (const t in e) t in a || delete e[t];
|
|
856
1424
|
for (const t in a) {
|
|
857
1425
|
const s = a[t];
|
|
858
|
-
e[t] =
|
|
1426
|
+
e[t] = Zt(s, e[t]);
|
|
859
1427
|
}
|
|
860
1428
|
}
|
|
861
|
-
function
|
|
1429
|
+
function $i(a) {
|
|
862
1430
|
switch (a) {
|
|
863
1431
|
case "ENUM": return 1;
|
|
864
1432
|
case "SCALAR": return 1;
|
|
@@ -873,21 +1441,21 @@ function Hi(a) {
|
|
|
873
1441
|
default: return -1;
|
|
874
1442
|
}
|
|
875
1443
|
}
|
|
876
|
-
var
|
|
1444
|
+
var mt = class {
|
|
877
1445
|
constructor(e, t, s = null) {
|
|
878
1446
|
this.name = t.name || null, this.description = t.description || null, this.type = t.type, this.componentType = t.componentType || null, this.enumType = t.enumType || null, this.array = t.array || !1, this.count = t.count || 0, this.normalized = t.normalized || !1, this.offset = t.offset || 0, this.scale = q(t, "scale", 1), this.max = q(t, "max", Infinity), this.min = q(t, "min", -Infinity), this.required = t.required || !1, this.noData = q(t, "noData", null), this.default = q(t, "default", null), this.semantic = q(t, "semantic", null), this.enumSet = null, this.accessorProperty = s, s && (this.offset = q(s, "offset", this.offset), this.scale = q(s, "scale", this.scale), this.max = q(s, "max", this.max), this.min = q(s, "min", this.min)), t.type === "ENUM" && (this.enumSet = e[this.enumType], this.componentType === null && (this.componentType = q(this.enumSet, "valueType", "UINT16")));
|
|
879
1447
|
}
|
|
880
1448
|
shapeToProperty(e, t = null) {
|
|
881
|
-
return
|
|
1449
|
+
return Zt(this, e, t);
|
|
882
1450
|
}
|
|
883
1451
|
resolveDefaultElement(e) {
|
|
884
|
-
return
|
|
1452
|
+
return at(this, e);
|
|
885
1453
|
}
|
|
886
1454
|
resolveDefault(e) {
|
|
887
|
-
return
|
|
1455
|
+
return Wi(this, e);
|
|
888
1456
|
}
|
|
889
1457
|
resolveNoData(e) {
|
|
890
|
-
return
|
|
1458
|
+
return ji(this, e);
|
|
891
1459
|
}
|
|
892
1460
|
resolveEnumsToStrings(e) {
|
|
893
1461
|
const t = this.enumSet;
|
|
@@ -900,10 +1468,10 @@ var ht = class {
|
|
|
900
1468
|
}
|
|
901
1469
|
}
|
|
902
1470
|
adjustValueScaleOffset(e) {
|
|
903
|
-
return
|
|
1471
|
+
return An(this.type) ? Yi(this, e) : e;
|
|
904
1472
|
}
|
|
905
1473
|
};
|
|
906
|
-
var
|
|
1474
|
+
var Jt = class {
|
|
907
1475
|
constructor(e, t = {}, s = {}, n = null) {
|
|
908
1476
|
this.definition = e, this.class = t[e.class], this.className = e.class, this.enums = s, this.data = n, this.name = "name" in e ? e.name : null, this.properties = null;
|
|
909
1477
|
}
|
|
@@ -914,24 +1482,24 @@ var Qt = class {
|
|
|
914
1482
|
return !!this.definition.properties[e];
|
|
915
1483
|
}
|
|
916
1484
|
dispose() {}
|
|
917
|
-
_initProperties(e =
|
|
1485
|
+
_initProperties(e = mt) {
|
|
918
1486
|
const t = {};
|
|
919
1487
|
for (const s in this.class.properties) t[s] = new e(this.enums, this.class.properties[s], this.definition.properties[s]);
|
|
920
1488
|
this.properties = t;
|
|
921
1489
|
}
|
|
922
1490
|
};
|
|
923
|
-
var
|
|
1491
|
+
var Qi = class extends mt {
|
|
924
1492
|
constructor(e, t, s = null) {
|
|
925
1493
|
super(e, t, s), this.attribute = (s == null ? void 0 : s.attribute) ?? null;
|
|
926
1494
|
}
|
|
927
1495
|
};
|
|
928
|
-
var
|
|
1496
|
+
var Zi = class extends Jt {
|
|
929
1497
|
constructor(...e) {
|
|
930
|
-
super(...e), this.isPropertyAttributeAccessor = !0, this._initProperties(
|
|
1498
|
+
super(...e), this.isPropertyAttributeAccessor = !0, this._initProperties(Qi);
|
|
931
1499
|
}
|
|
932
1500
|
getData(e, t, s = {}) {
|
|
933
1501
|
const n = this.properties;
|
|
934
|
-
|
|
1502
|
+
lt(n, s);
|
|
935
1503
|
for (const i in n) s[i] = this.getPropertyValue(i, e, t, s[i]);
|
|
936
1504
|
return s;
|
|
937
1505
|
}
|
|
@@ -943,23 +1511,23 @@ var Wi = class extends Qt {
|
|
|
943
1511
|
} else throw new Error("PropertyAttributeAccessor: Requested class property does not exist.");
|
|
944
1512
|
n = i.shapeToProperty(n);
|
|
945
1513
|
const o = s.getAttribute(i.attribute.toLowerCase());
|
|
946
|
-
if (
|
|
1514
|
+
if (qe(r)) {
|
|
947
1515
|
const l = n.elements;
|
|
948
1516
|
for (let c = 0, u = l.length; c < u;) l[c] = o.getComponent(t, c);
|
|
949
|
-
} else if (
|
|
1517
|
+
} else if (He(r)) n.fromBufferAttribute(o, t);
|
|
950
1518
|
else if (r === "SCALAR" || r === "ENUM") n = o.getX(t);
|
|
951
1519
|
else throw new Error("StructuredMetadata.PropertyAttributeAccessor: BOOLEAN and STRING types are not supported by property attributes.");
|
|
952
1520
|
return n = i.adjustValueScaleOffset(n), n = i.resolveEnumsToStrings(n), n = i.resolveNoData(n), n;
|
|
953
1521
|
}
|
|
954
1522
|
};
|
|
955
|
-
var
|
|
1523
|
+
var Ji = class extends mt {
|
|
956
1524
|
constructor(e, t, s = null) {
|
|
957
|
-
super(e, t, s), this.values = (s == null ? void 0 : s.values) ?? null, this.valueLength =
|
|
1525
|
+
super(e, t, s), this.values = (s == null ? void 0 : s.values) ?? null, this.valueLength = $i(this.type), this.arrayOffsets = q(s, "arrayOffsets", null), this.stringOffsets = q(s, "stringOffsets", null), this.arrayOffsetType = q(s, "arrayOffsetType", "UINT32"), this.stringOffsetType = q(s, "stringOffsetType", "UINT32");
|
|
958
1526
|
}
|
|
959
1527
|
getArrayLengthFromId(e, t) {
|
|
960
1528
|
let s = this.count;
|
|
961
1529
|
if (this.arrayOffsets !== null) {
|
|
962
|
-
const { arrayOffsets: n, arrayOffsetType: i } = this, o = new (
|
|
1530
|
+
const { arrayOffsets: n, arrayOffsetType: i } = this, o = new (Fe(i))(e[n]);
|
|
963
1531
|
s = o[t + 1] - o[t];
|
|
964
1532
|
}
|
|
965
1533
|
return s;
|
|
@@ -968,29 +1536,29 @@ var ji = class extends ht {
|
|
|
968
1536
|
let s = t;
|
|
969
1537
|
if (this.arrayOffsets) {
|
|
970
1538
|
const { arrayOffsets: n, arrayOffsetType: i } = this;
|
|
971
|
-
s = new (
|
|
1539
|
+
s = new (Fe(i))(e[n])[s];
|
|
972
1540
|
} else this.array && (s *= this.count);
|
|
973
1541
|
return s;
|
|
974
1542
|
}
|
|
975
1543
|
};
|
|
976
|
-
var
|
|
1544
|
+
var Ki = class extends Jt {
|
|
977
1545
|
constructor(...e) {
|
|
978
|
-
super(...e), this.isPropertyTableAccessor = !0, this.count = this.definition.count, this._initProperties(
|
|
1546
|
+
super(...e), this.isPropertyTableAccessor = !0, this.count = this.definition.count, this._initProperties(Ji);
|
|
979
1547
|
}
|
|
980
1548
|
getData(e, t = {}) {
|
|
981
1549
|
const s = this.properties;
|
|
982
|
-
|
|
1550
|
+
lt(s, t);
|
|
983
1551
|
for (const n in s) t[n] = this.getPropertyValue(n, e, t[n]);
|
|
984
1552
|
return t;
|
|
985
1553
|
}
|
|
986
1554
|
_readValueAtIndex(e, t, s, n = null) {
|
|
987
|
-
const i = this.properties[e], { componentType: r, type: o } = i, l = this.data, c = l[i.values], h = new (
|
|
988
|
-
if (
|
|
1555
|
+
const i = this.properties[e], { componentType: r, type: o } = i, l = this.data, c = l[i.values], h = new (Fe(r, o))(c), d = i.getIndexOffsetFromId(l, t);
|
|
1556
|
+
if (An(o) || o === "ENUM") return In(h, (d + s) * i.valueLength, o, n);
|
|
989
1557
|
if (o === "STRING") {
|
|
990
1558
|
let m = d + s, f = 0;
|
|
991
1559
|
if (i.stringOffsets !== null) {
|
|
992
|
-
const { stringOffsets: g, stringOffsetType: y } = i,
|
|
993
|
-
f =
|
|
1560
|
+
const { stringOffsets: g, stringOffsetType: y } = i, b = new (Fe(y))(l[g]);
|
|
1561
|
+
f = b[m + 1] - b[m], m = b[m];
|
|
994
1562
|
}
|
|
995
1563
|
const p = new Uint8Array(h.buffer, m, f);
|
|
996
1564
|
n = new TextDecoder().decode(p);
|
|
@@ -1012,8 +1580,8 @@ var Yi = class extends Qt {
|
|
|
1012
1580
|
return s = n.adjustValueScaleOffset(s), s = n.resolveEnumsToStrings(s), s = n.resolveNoData(s), s;
|
|
1013
1581
|
}
|
|
1014
1582
|
};
|
|
1015
|
-
var
|
|
1016
|
-
var
|
|
1583
|
+
var Pe = /* @__PURE__ */ new Box2();
|
|
1584
|
+
var bs = class {
|
|
1017
1585
|
constructor() {
|
|
1018
1586
|
this._renderer = new WebGLRenderer(), this._target = new WebGLRenderTarget(1, 1), this._texTarget = new WebGLRenderTarget(), this._quad = new FullScreenQuad(new ShaderMaterial({
|
|
1019
1587
|
blending: CustomBlending,
|
|
@@ -1055,56 +1623,56 @@ var xs = class {
|
|
|
1055
1623
|
}
|
|
1056
1624
|
renderPixelToTarget(e, t, s) {
|
|
1057
1625
|
const { _renderer: n, _target: i } = this;
|
|
1058
|
-
|
|
1626
|
+
Pe.min.copy(t), Pe.max.copy(t), Pe.max.x += 1, Pe.max.y += 1, n.initRenderTarget(i), n.copyTextureToTexture(e, i.texture, Pe, s, 0);
|
|
1059
1627
|
}
|
|
1060
1628
|
};
|
|
1061
|
-
var
|
|
1629
|
+
var de = /* @__PURE__ */ new class {
|
|
1062
1630
|
constructor() {
|
|
1063
1631
|
let a = null;
|
|
1064
|
-
Object.getOwnPropertyNames(
|
|
1065
|
-
e !== "constructor" && (this[e] = (...t) => (a = a || new
|
|
1632
|
+
Object.getOwnPropertyNames(bs.prototype).forEach((e) => {
|
|
1633
|
+
e !== "constructor" && (this[e] = (...t) => (a = a || new bs(), a[e](...t)));
|
|
1066
1634
|
});
|
|
1067
1635
|
}
|
|
1068
|
-
}(),
|
|
1069
|
-
function
|
|
1636
|
+
}(), _s = /* @__PURE__ */ new Vector2(), Ss = /* @__PURE__ */ new Vector2(), Ms = /* @__PURE__ */ new Vector2();
|
|
1637
|
+
function er(a, e) {
|
|
1070
1638
|
return e === 0 ? a.getAttribute("uv") : a.getAttribute(`uv${e}`);
|
|
1071
1639
|
}
|
|
1072
|
-
function
|
|
1640
|
+
function vn(a, e, t = new Array(3)) {
|
|
1073
1641
|
let s = 3 * e, n = 3 * e + 1, i = 3 * e + 2;
|
|
1074
1642
|
return a.index && (s = a.index.getX(s), n = a.index.getX(n), i = a.index.getX(i)), t[0] = s, t[1] = n, t[2] = i, t;
|
|
1075
1643
|
}
|
|
1076
|
-
function
|
|
1077
|
-
const [i, r, o] = s, l =
|
|
1078
|
-
|
|
1644
|
+
function Ln(a, e, t, s, n) {
|
|
1645
|
+
const [i, r, o] = s, l = er(a, e);
|
|
1646
|
+
_s.fromBufferAttribute(l, i), Ss.fromBufferAttribute(l, r), Ms.fromBufferAttribute(l, o), n.set(0, 0, 0).addScaledVector(_s, t.x).addScaledVector(Ss, t.y).addScaledVector(Ms, t.z);
|
|
1079
1647
|
}
|
|
1080
|
-
function
|
|
1648
|
+
function En(a, e, t, s) {
|
|
1081
1649
|
const n = a.x - Math.floor(a.x), i = a.y - Math.floor(a.y), r = Math.floor(n * e % e), o = Math.floor(i * t % t);
|
|
1082
1650
|
return s.set(r, o), s;
|
|
1083
1651
|
}
|
|
1084
|
-
var
|
|
1085
|
-
var
|
|
1652
|
+
var Cs = /* @__PURE__ */ new Vector2(), As = /* @__PURE__ */ new Vector2(), Is = /* @__PURE__ */ new Vector2();
|
|
1653
|
+
var tr = class extends mt {
|
|
1086
1654
|
constructor(e, t, s = null) {
|
|
1087
1655
|
super(e, t, s), this.channels = q(s, "channels", [0]), this.index = q(s, "index", null), this.texCoord = q(s, "texCoord", null), this.valueLength = parseInt(this.type.replace(/[^0-9]/g, "")) || 1;
|
|
1088
1656
|
}
|
|
1089
1657
|
readDataFromBuffer(e, t, s = null) {
|
|
1090
1658
|
const n = this.type;
|
|
1091
1659
|
if (n === "BOOLEAN" || n === "STRING") throw new Error("PropertyTextureAccessor: BOOLEAN and STRING types not supported.");
|
|
1092
|
-
return
|
|
1660
|
+
return In(e, t * this.valueLength, n, s);
|
|
1093
1661
|
}
|
|
1094
1662
|
};
|
|
1095
|
-
var
|
|
1663
|
+
var sr = class extends Jt {
|
|
1096
1664
|
constructor(...e) {
|
|
1097
|
-
super(...e), this.isPropertyTextureAccessor = !0, this._asyncRead = !1, this._initProperties(
|
|
1665
|
+
super(...e), this.isPropertyTextureAccessor = !0, this._asyncRead = !1, this._initProperties(tr);
|
|
1098
1666
|
}
|
|
1099
1667
|
getData(e, t, s, n = {}) {
|
|
1100
1668
|
const i = this.properties;
|
|
1101
|
-
|
|
1669
|
+
lt(i, n);
|
|
1102
1670
|
const r = Object.keys(i), o = r.map((l) => n[l]);
|
|
1103
1671
|
return this.getPropertyValuesAtTexel(r, e, t, s, o), r.forEach((l, c) => n[l] = o[c]), n;
|
|
1104
1672
|
}
|
|
1105
1673
|
async getDataAsync(e, t, s, n = {}) {
|
|
1106
1674
|
const i = this.properties;
|
|
1107
|
-
|
|
1675
|
+
lt(i, n);
|
|
1108
1676
|
const r = Object.keys(i), o = r.map((l) => n[l]);
|
|
1109
1677
|
return await this.getPropertyValuesAtTexelAsync(r, e, t, s, o), r.forEach((l, c) => n[l] = o[c]), n;
|
|
1110
1678
|
}
|
|
@@ -1115,30 +1683,30 @@ var Qi = class extends Qt {
|
|
|
1115
1683
|
}
|
|
1116
1684
|
getPropertyValuesAtTexel(e, t, s, n, i = []) {
|
|
1117
1685
|
for (; i.length < e.length;) i.push(null);
|
|
1118
|
-
i.length = e.length,
|
|
1119
|
-
const r = this.data, o = this.definition.properties, l = this.properties, c =
|
|
1686
|
+
i.length = e.length, de.increaseSizeTo(i.length);
|
|
1687
|
+
const r = this.data, o = this.definition.properties, l = this.properties, c = vn(n, t);
|
|
1120
1688
|
for (let d = 0, m = e.length; d < m; d++) {
|
|
1121
1689
|
const f = e[d];
|
|
1122
1690
|
if (!o[f]) continue;
|
|
1123
1691
|
const p = l[f], g = r[p.index];
|
|
1124
|
-
|
|
1692
|
+
Ln(n, p.texCoord, s, c, Cs), En(Cs, g.image.width, g.image.height, As), Is.set(d, 0), de.renderPixelToTarget(g, As, Is);
|
|
1125
1693
|
}
|
|
1126
1694
|
const u = new Uint8Array(e.length * 4);
|
|
1127
|
-
if (this._asyncRead) return
|
|
1128
|
-
return
|
|
1695
|
+
if (this._asyncRead) return de.readDataAsync(u).then(() => (h.call(this), i));
|
|
1696
|
+
return de.readData(u), h.call(this), i;
|
|
1129
1697
|
function h() {
|
|
1130
1698
|
for (let d = 0, m = e.length; d < m; d++) {
|
|
1131
1699
|
const f = e[d], p = l[f], g = p.type;
|
|
1132
|
-
if (i[d] =
|
|
1700
|
+
if (i[d] = Zt(p, i[d]), p) {
|
|
1133
1701
|
if (!o[f]) {
|
|
1134
1702
|
i[d] = p.resolveDefault(i);
|
|
1135
1703
|
continue;
|
|
1136
1704
|
}
|
|
1137
1705
|
} else throw new Error("PropertyTextureAccessor: Requested property does not exist.");
|
|
1138
|
-
const y = p.valueLength * (p.count || 1), x = p.channels.map((
|
|
1706
|
+
const y = p.valueLength * (p.count || 1), x = p.channels.map((S) => u[4 * d + S]), b = p.componentType, M = new (Fe(b, g))(y);
|
|
1139
1707
|
if (new Uint8Array(M.buffer).set(x), p.array) {
|
|
1140
|
-
const
|
|
1141
|
-
for (let C = 0, v =
|
|
1708
|
+
const S = i[d];
|
|
1709
|
+
for (let C = 0, v = S.length; C < v; C++) S[C] = p.readDataFromBuffer(M, C, S[C]);
|
|
1142
1710
|
} else i[d] = p.readDataFromBuffer(M, 0, i[d]);
|
|
1143
1711
|
i[d] = p.adjustValueScaleOffset(i[d]), i[d] = p.resolveEnumsToStrings(i[d]), i[d] = p.resolveNoData(i[d]);
|
|
1144
1712
|
}
|
|
@@ -1150,25 +1718,37 @@ var Qi = class extends Qt {
|
|
|
1150
1718
|
});
|
|
1151
1719
|
}
|
|
1152
1720
|
};
|
|
1153
|
-
var
|
|
1721
|
+
var vs = class {
|
|
1154
1722
|
constructor(e, t, s, n = null, i = null) {
|
|
1155
|
-
const { schema: r, propertyTables: o = [], propertyTextures: l = [], propertyAttributes: c = [] } = e, { enums: u, classes: h } = r, d = o.map((p) => new
|
|
1723
|
+
const { schema: r, propertyTables: o = [], propertyTextures: l = [], propertyAttributes: c = [] } = e, { enums: u, classes: h } = r, d = o.map((p) => new Ki(p, h, u, s));
|
|
1156
1724
|
let m = [], f = [];
|
|
1157
|
-
n && (n.propertyTextures && (m = n.propertyTextures.map((p) => new
|
|
1725
|
+
n && (n.propertyTextures && (m = n.propertyTextures.map((p) => new sr(l[p], h, u, t))), n.propertyAttributes && (f = n.propertyAttributes.map((p) => new Zi(c[p], h, u)))), this.schema = r, this.tableAccessors = d, this.textureAccessors = m, this.attributeAccessors = f, this.object = i, this.textures = t, this.nodeMetadata = n;
|
|
1158
1726
|
}
|
|
1727
|
+
/**
|
|
1728
|
+
* Returns data from one or more property tables. Pass a single table index and row ID to
|
|
1729
|
+
* get one object, or parallel arrays of table indices and row IDs to get an array of
|
|
1730
|
+
* results. Each returned object conforms to the structure class referenced in the schema.
|
|
1731
|
+
* @param {number|Array<number>} tableIndices Table index or array of table indices.
|
|
1732
|
+
* @param {number|Array<number>} ids Row ID or array of row IDs.
|
|
1733
|
+
* @param {Object|Array|null} [target=null] Optional target object or array to write into.
|
|
1734
|
+
* @returns {Object|Array}
|
|
1735
|
+
*/
|
|
1159
1736
|
getPropertyTableData(e, t, s = null) {
|
|
1160
1737
|
if (!Array.isArray(e) || !Array.isArray(t)) s = s || {}, s = this.tableAccessors[e].getData(t, s);
|
|
1161
1738
|
else {
|
|
1162
1739
|
s = s || [];
|
|
1163
1740
|
const n = Math.min(e.length, t.length);
|
|
1164
1741
|
s.length = n;
|
|
1165
|
-
for (let i = 0; i < n; i++)
|
|
1166
|
-
const r = this.tableAccessors[e[i]];
|
|
1167
|
-
s[i] = r.getData(t[i], s[i]);
|
|
1168
|
-
}
|
|
1742
|
+
for (let i = 0; i < n; i++) s[i] = this.tableAccessors[e[i]].getData(t[i], s[i]);
|
|
1169
1743
|
}
|
|
1170
1744
|
return s;
|
|
1171
1745
|
}
|
|
1746
|
+
/**
|
|
1747
|
+
* Returns name and class information for one or more property tables. Defaults to all
|
|
1748
|
+
* tables when `tableIndices` is `null`.
|
|
1749
|
+
* @param {Array<number>|null} [tableIndices=null]
|
|
1750
|
+
* @returns {Array<{name: string, className: string}>|{name: string, className: string}}
|
|
1751
|
+
*/
|
|
1172
1752
|
getPropertyTableInfo(e = null) {
|
|
1173
1753
|
if (e === null && (e = this.tableAccessors.map((t, s) => s)), Array.isArray(e)) return e.map((t) => {
|
|
1174
1754
|
const s = this.tableAccessors[t];
|
|
@@ -1185,12 +1765,29 @@ var As = class {
|
|
|
1185
1765
|
};
|
|
1186
1766
|
}
|
|
1187
1767
|
}
|
|
1768
|
+
/**
|
|
1769
|
+
* Returns data from property textures at the given point on the mesh. Takes the triangle
|
|
1770
|
+
* index and barycentric coordinate from a raycast result. See `MeshFeatures.getFeatures`
|
|
1771
|
+
* for how to obtain these values.
|
|
1772
|
+
* @param {number} triangle Triangle index from a raycast hit.
|
|
1773
|
+
* @param {Vector3} barycoord Barycentric coordinate of the hit point.
|
|
1774
|
+
* @param {Array} [target=[]] Optional target array to write into.
|
|
1775
|
+
* @returns {Array}
|
|
1776
|
+
*/
|
|
1188
1777
|
getPropertyTextureData(e, t, s = []) {
|
|
1189
1778
|
const n = this.textureAccessors;
|
|
1190
1779
|
s.length = n.length;
|
|
1191
1780
|
for (let i = 0; i < n.length; i++) s[i] = n[i].getData(e, t, this.object.geometry, s[i]);
|
|
1192
1781
|
return s;
|
|
1193
1782
|
}
|
|
1783
|
+
/**
|
|
1784
|
+
* Returns the same data as `getPropertyTextureData` but performs texture reads
|
|
1785
|
+
* asynchronously.
|
|
1786
|
+
* @param {number} triangle Triangle index from a raycast hit.
|
|
1787
|
+
* @param {Vector3} barycoord Barycentric coordinate of the hit point.
|
|
1788
|
+
* @param {Array} [target=[]] Optional target array to write into.
|
|
1789
|
+
* @returns {Promise<Array>}
|
|
1790
|
+
*/
|
|
1194
1791
|
async getPropertyTextureDataAsync(e, t, s = []) {
|
|
1195
1792
|
const n = this.textureAccessors;
|
|
1196
1793
|
s.length = n.length;
|
|
@@ -1203,30 +1800,48 @@ var As = class {
|
|
|
1203
1800
|
}
|
|
1204
1801
|
return await Promise.all(i), s;
|
|
1205
1802
|
}
|
|
1803
|
+
/**
|
|
1804
|
+
* Returns information about the property texture accessors, including their class names
|
|
1805
|
+
* and per-property channel/texcoord mappings.
|
|
1806
|
+
* @returns {Array<{name: string, className: string, properties: Object}>}
|
|
1807
|
+
*/
|
|
1206
1808
|
getPropertyTextureInfo() {
|
|
1207
1809
|
return this.textureAccessors;
|
|
1208
1810
|
}
|
|
1811
|
+
/**
|
|
1812
|
+
* Returns data stored as property attributes for the given vertex index.
|
|
1813
|
+
* @param {number} attributeIndex Vertex index.
|
|
1814
|
+
* @param {Array} [target=[]] Optional target array to write into.
|
|
1815
|
+
* @returns {Array}
|
|
1816
|
+
*/
|
|
1209
1817
|
getPropertyAttributeData(e, t = []) {
|
|
1210
1818
|
const s = this.attributeAccessors;
|
|
1211
1819
|
t.length = s.length;
|
|
1212
1820
|
for (let n = 0; n < s.length; n++) t[n] = s[n].getData(e, this.object.geometry, t[n]);
|
|
1213
1821
|
return t;
|
|
1214
1822
|
}
|
|
1823
|
+
/**
|
|
1824
|
+
* Returns name and class information for all property attribute accessors.
|
|
1825
|
+
* @returns {Array<{name: string, className: string}>}
|
|
1826
|
+
*/
|
|
1215
1827
|
getPropertyAttributeInfo() {
|
|
1216
1828
|
return this.attributeAccessors.map((e) => ({
|
|
1217
1829
|
name: e.name,
|
|
1218
1830
|
className: e.definition.class
|
|
1219
1831
|
}));
|
|
1220
1832
|
}
|
|
1833
|
+
/**
|
|
1834
|
+
* Disposes all texture, table, and attribute accessors.
|
|
1835
|
+
*/
|
|
1221
1836
|
dispose() {
|
|
1222
1837
|
this.textureAccessors.forEach((e) => e.dispose()), this.tableAccessors.forEach((e) => e.dispose()), this.attributeAccessors.forEach((e) => e.dispose());
|
|
1223
1838
|
}
|
|
1224
1839
|
};
|
|
1225
|
-
var
|
|
1226
|
-
function
|
|
1840
|
+
var Ls = /* @__PURE__ */ new Vector2(), Es = /* @__PURE__ */ new Vector2(), ws = /* @__PURE__ */ new Vector2();
|
|
1841
|
+
function or(a) {
|
|
1227
1842
|
return a.x > a.y && a.x > a.z ? 0 : a.y > a.z ? 1 : 2;
|
|
1228
1843
|
}
|
|
1229
|
-
var
|
|
1844
|
+
var ar = class {
|
|
1230
1845
|
constructor(e, t, s) {
|
|
1231
1846
|
this.geometry = e, this.textures = t, this.data = s, this._asyncRead = !1, this.featureIds = s.featureIds.map((n) => {
|
|
1232
1847
|
const { texture: i, ...r } = n, o = {
|
|
@@ -1242,26 +1857,48 @@ var tr = class {
|
|
|
1242
1857
|
}), o;
|
|
1243
1858
|
});
|
|
1244
1859
|
}
|
|
1860
|
+
/**
|
|
1861
|
+
* Returns an indexed list of all textures used by features in the extension.
|
|
1862
|
+
* @returns {Array<Texture>}
|
|
1863
|
+
*/
|
|
1245
1864
|
getTextures() {
|
|
1246
1865
|
return this.textures;
|
|
1247
1866
|
}
|
|
1867
|
+
/**
|
|
1868
|
+
* Returns the feature ID info for each feature set defined on this primitive.
|
|
1869
|
+
* @returns {Array<FeatureInfo>}
|
|
1870
|
+
*/
|
|
1248
1871
|
getFeatureInfo() {
|
|
1249
1872
|
return this.featureIds;
|
|
1250
1873
|
}
|
|
1874
|
+
/**
|
|
1875
|
+
* Performs the same function as `getFeatures` but reads texture data asynchronously.
|
|
1876
|
+
* @param {number} triangle Triangle index from a raycast hit.
|
|
1877
|
+
* @param {Vector3} barycoord Barycentric coordinate of the hit point.
|
|
1878
|
+
* @returns {Promise<Array<number|null>>}
|
|
1879
|
+
*/
|
|
1251
1880
|
getFeaturesAsync(...e) {
|
|
1252
1881
|
this._asyncRead = !0;
|
|
1253
1882
|
const t = this.getFeatures(...e);
|
|
1254
1883
|
return this._asyncRead = !1, t;
|
|
1255
1884
|
}
|
|
1885
|
+
/**
|
|
1886
|
+
* Returns the list of feature IDs at the given point on the mesh. Takes the triangle
|
|
1887
|
+
* index from a raycast result and a barycentric coordinate. Results are indexed in the
|
|
1888
|
+
* same order as the feature info returned by `getFeatureInfo()`.
|
|
1889
|
+
* @param {number} triangle Triangle index from a raycast hit.
|
|
1890
|
+
* @param {Vector3} barycoord Barycentric coordinate of the hit point.
|
|
1891
|
+
* @returns {Array<number|null>}
|
|
1892
|
+
*/
|
|
1256
1893
|
getFeatures(e, t) {
|
|
1257
1894
|
const { geometry: s, textures: n, featureIds: i } = this, r = new Array(i.length).fill(null), o = i.length;
|
|
1258
|
-
|
|
1259
|
-
const l =
|
|
1895
|
+
de.increaseSizeTo(o);
|
|
1896
|
+
const l = vn(s, e), c = l[or(t)];
|
|
1260
1897
|
for (let d = 0, m = i.length; d < m; d++) {
|
|
1261
1898
|
const f = i[d], p = "nullFeatureId" in f ? f.nullFeatureId : null;
|
|
1262
1899
|
if ("texture" in f) {
|
|
1263
1900
|
const g = n[f.texture.index];
|
|
1264
|
-
|
|
1901
|
+
Ln(s, f.texture.texCoord, t, l, Ls), En(Ls, g.image.width, g.image.height, Es), ws.set(d, 0), de.renderPixelToTarget(n[f.texture.index], Es, ws);
|
|
1265
1902
|
} else if ("attribute" in f) {
|
|
1266
1903
|
const y = s.getAttribute(`_feature_id_${f.attribute}`).getX(c);
|
|
1267
1904
|
y !== p && (r[d] = y);
|
|
@@ -1271,8 +1908,8 @@ var tr = class {
|
|
|
1271
1908
|
}
|
|
1272
1909
|
}
|
|
1273
1910
|
const u = new Uint8Array(o * 4);
|
|
1274
|
-
if (this._asyncRead) return
|
|
1275
|
-
return
|
|
1911
|
+
if (this._asyncRead) return de.readDataAsync(u).then(() => (h(), r));
|
|
1912
|
+
return de.readData(u), h(), r;
|
|
1276
1913
|
function h() {
|
|
1277
1914
|
const d = new Uint32Array(1);
|
|
1278
1915
|
for (let m = 0, f = i.length; m < f; m++) {
|
|
@@ -1280,12 +1917,15 @@ var tr = class {
|
|
|
1280
1917
|
if ("texture" in p) {
|
|
1281
1918
|
const { channels: y } = p.texture, x = y.map((T) => u[4 * m + T]);
|
|
1282
1919
|
new Uint8Array(d.buffer).set(x);
|
|
1283
|
-
const
|
|
1284
|
-
|
|
1920
|
+
const b = d[0];
|
|
1921
|
+
b !== g && (r[m] = b);
|
|
1285
1922
|
}
|
|
1286
1923
|
}
|
|
1287
1924
|
}
|
|
1288
1925
|
}
|
|
1926
|
+
/**
|
|
1927
|
+
* Disposes all textures used by this instance.
|
|
1928
|
+
*/
|
|
1289
1929
|
dispose() {
|
|
1290
1930
|
this.textures.forEach((e) => {
|
|
1291
1931
|
e && (e.dispose(), e.image instanceof ImageBitmap && e.image.close());
|
|
@@ -1293,13 +1933,13 @@ var tr = class {
|
|
|
1293
1933
|
}
|
|
1294
1934
|
};
|
|
1295
1935
|
new FullScreenQuad(new MeshBasicMaterial());
|
|
1296
|
-
var
|
|
1936
|
+
var zt = new DataTexture(new Uint8Array([
|
|
1297
1937
|
255,
|
|
1298
1938
|
255,
|
|
1299
1939
|
255,
|
|
1300
1940
|
255
|
|
1301
1941
|
]), 1, 1);
|
|
1302
|
-
|
|
1942
|
+
zt.needsUpdate = !0;
|
|
1303
1943
|
Object.freeze({
|
|
1304
1944
|
NONE: 0,
|
|
1305
1945
|
SCREEN_ERROR: 1,
|
|
@@ -1472,7 +2112,7 @@ var GLTFWorkerLoader = class extends Loader {
|
|
|
1472
2112
|
if (hasStructuralMetadata && data.structuralMetadata) {
|
|
1473
2113
|
const rootExtension = data.json?.extensions?.[EXT_STRUCTURAL_METADATA];
|
|
1474
2114
|
if (rootExtension) {
|
|
1475
|
-
rootMetadata = new
|
|
2115
|
+
rootMetadata = new vs({
|
|
1476
2116
|
schema: data.structuralMetadata.schema,
|
|
1477
2117
|
propertyTables: data.structuralMetadata.propertyTables || [],
|
|
1478
2118
|
propertyTextures: rootExtension.propertyTextures || [],
|
|
@@ -1495,7 +2135,7 @@ var GLTFWorkerLoader = class extends Loader {
|
|
|
1495
2135
|
const primMetadataExt = extensions?.[EXT_STRUCTURAL_METADATA];
|
|
1496
2136
|
if (primMetadataExt) {
|
|
1497
2137
|
const rootExtension = data.json?.extensions?.[EXT_STRUCTURAL_METADATA];
|
|
1498
|
-
if (rootExtension) child.userData.structuralMetadata = new
|
|
2138
|
+
if (rootExtension) child.userData.structuralMetadata = new vs({
|
|
1499
2139
|
schema: data.structuralMetadata.schema,
|
|
1500
2140
|
propertyTables: data.structuralMetadata.propertyTables || [],
|
|
1501
2141
|
propertyTextures: rootExtension.propertyTextures || [],
|
|
@@ -1505,17 +2145,13 @@ var GLTFWorkerLoader = class extends Loader {
|
|
|
1505
2145
|
}
|
|
1506
2146
|
if (hasMeshFeatures) {
|
|
1507
2147
|
const meshFeaturesExt = extensions?.[EXT_MESH_FEATURES];
|
|
1508
|
-
if (meshFeaturesExt) child.userData.meshFeatures = new
|
|
2148
|
+
if (meshFeaturesExt) child.userData.meshFeatures = new ar(child.geometry, textures, meshFeaturesExt);
|
|
1509
2149
|
}
|
|
1510
2150
|
});
|
|
1511
2151
|
}
|
|
1512
2152
|
};
|
|
1513
2153
|
//#endregion
|
|
1514
2154
|
//#region src/plugin/PartColorHelper.ts
|
|
1515
|
-
function ensureColor$2(color) {
|
|
1516
|
-
if (color instanceof Color) return color;
|
|
1517
|
-
return new Color(color);
|
|
1518
|
-
}
|
|
1519
2155
|
function getMaterials(mesh) {
|
|
1520
2156
|
const mat = mesh.material;
|
|
1521
2157
|
if (!mat) return [];
|
|
@@ -1573,7 +2209,7 @@ var PartColorHelper = class {
|
|
|
1573
2209
|
setPartColorByOids(oids, color) {
|
|
1574
2210
|
const scene = this.context.getScene();
|
|
1575
2211
|
if (!scene) return;
|
|
1576
|
-
const material = getMaterialForColor(
|
|
2212
|
+
const material = getMaterialForColor(toColor(color));
|
|
1577
2213
|
for (const oid of oids) {
|
|
1578
2214
|
this.coloredOids.add(oid);
|
|
1579
2215
|
this.materialByOid.set(oid, material);
|
|
@@ -1699,10 +2335,6 @@ var PartColorHelper = class {
|
|
|
1699
2335
|
};
|
|
1700
2336
|
//#endregion
|
|
1701
2337
|
//#region src/plugin/PartBlinkHelper.ts
|
|
1702
|
-
function ensureColor$1(color) {
|
|
1703
|
-
if (color instanceof Color) return color;
|
|
1704
|
-
return new Color(color);
|
|
1705
|
-
}
|
|
1706
2338
|
/**
|
|
1707
2339
|
* 构件闪烁强调辅助器
|
|
1708
2340
|
* 通过 hidePartsByOids + split mesh + emissive 动画实现闪烁效果
|
|
@@ -1786,7 +2418,7 @@ var PartBlinkHelper = class {
|
|
|
1786
2418
|
* @param color 颜色值,支持 hex 数字、颜色字符串(如 "#ff0000")、THREE.Color 对象
|
|
1787
2419
|
*/
|
|
1788
2420
|
setBlinkColor(color) {
|
|
1789
|
-
const c =
|
|
2421
|
+
const c = toColor(color);
|
|
1790
2422
|
this.blinkColor.copy(c);
|
|
1791
2423
|
this.blinkMaterial.color.copy(c);
|
|
1792
2424
|
this.blinkMaterial.emissive.copy(c);
|
|
@@ -1831,10 +2463,6 @@ var PartBlinkHelper = class {
|
|
|
1831
2463
|
};
|
|
1832
2464
|
//#endregion
|
|
1833
2465
|
//#region src/plugin/PartFrameHelper.ts
|
|
1834
|
-
function ensureColor(color) {
|
|
1835
|
-
if (color instanceof Color) return color;
|
|
1836
|
-
return new Color(color);
|
|
1837
|
-
}
|
|
1838
2466
|
/**
|
|
1839
2467
|
* 构件线框显示辅助器
|
|
1840
2468
|
* 通过 hidePartsByOids + split mesh + 填充材质 + EdgesGeometry 实现线框效果
|
|
@@ -1967,7 +2595,7 @@ var PartFrameHelper = class {
|
|
|
1967
2595
|
* @param color 颜色值,支持 hex 数字、颜色字符串(如 "#ff0000")、THREE.Color 对象
|
|
1968
2596
|
*/
|
|
1969
2597
|
setFrameFillColor(oids, color) {
|
|
1970
|
-
const hex =
|
|
2598
|
+
const hex = toColor(color).getHex();
|
|
1971
2599
|
for (const oid of oids) {
|
|
1972
2600
|
if (!this.frameOids.has(oid)) continue;
|
|
1973
2601
|
this.fillColorByOid.set(oid, hex);
|
|
@@ -1980,7 +2608,7 @@ var PartFrameHelper = class {
|
|
|
1980
2608
|
* @param color 颜色值,支持 hex 数字、颜色字符串(如 "#ff0000")、THREE.Color 对象
|
|
1981
2609
|
*/
|
|
1982
2610
|
setFrameEdgeColor(oids, color) {
|
|
1983
|
-
const hex =
|
|
2611
|
+
const hex = toColor(color).getHex();
|
|
1984
2612
|
for (const oid of oids) {
|
|
1985
2613
|
if (!this.frameOids.has(oid)) continue;
|
|
1986
2614
|
this.edgeColorByOid.set(oid, hex);
|
|
@@ -1996,13 +2624,445 @@ var PartFrameHelper = class {
|
|
|
1996
2624
|
}
|
|
1997
2625
|
};
|
|
1998
2626
|
//#endregion
|
|
2627
|
+
//#region src/plugin/style-appearance-shared.ts
|
|
2628
|
+
function vec3Key(v) {
|
|
2629
|
+
if (v === void 0) return "";
|
|
2630
|
+
if (Array.isArray(v)) return `${v[0] ?? 0},${v[1] ?? 0},${v[2] ?? 0}`;
|
|
2631
|
+
const p = v;
|
|
2632
|
+
return `${p.x},${p.y},${p.z}`;
|
|
2633
|
+
}
|
|
2634
|
+
function eulerKey(r) {
|
|
2635
|
+
if (r === void 0) return "";
|
|
2636
|
+
if (Array.isArray(r)) return `${r[0] ?? 0},${r[1] ?? 0},${r[2] ?? 0},${r.length >= 4 && typeof r[3] === "string" ? r[3] : "XYZ"}`;
|
|
2637
|
+
const e = r;
|
|
2638
|
+
return `${e.x},${e.y},${e.z},${e.order}`;
|
|
2639
|
+
}
|
|
2640
|
+
function applyVec3(target, input) {
|
|
2641
|
+
if (Array.isArray(input)) target.set(input[0] ?? 0, input[1] ?? 0, input[2] ?? 0);
|
|
2642
|
+
else target.copy(input);
|
|
2643
|
+
}
|
|
2644
|
+
function applyEuler(target, input) {
|
|
2645
|
+
if (Array.isArray(input)) if (input.length >= 4 && typeof input[3] === "string") target.set(input[0] ?? 0, input[1] ?? 0, input[2] ?? 0, input[3]);
|
|
2646
|
+
else target.set(input[0] ?? 0, input[1] ?? 0, input[2] ?? 0, "XYZ");
|
|
2647
|
+
else target.copy(input);
|
|
2648
|
+
}
|
|
2649
|
+
function appearanceGroupKey(a) {
|
|
2650
|
+
return `${a.material.uuid}|${vec3Key(a.translation)}|${vec3Key(a.scale)}|${eulerKey(a.rotation)}|${vec3Key(a.origin)}`;
|
|
2651
|
+
}
|
|
2652
|
+
function buildPivotStyleMatrix(pivot, sx, sy, sz, euler) {
|
|
2653
|
+
const m = new Matrix4().makeTranslation(-pivot.x, -pivot.y, -pivot.z);
|
|
2654
|
+
m.premultiply(new Matrix4().makeScale(sx, sy, sz));
|
|
2655
|
+
m.premultiply(new Matrix4().makeRotationFromEuler(euler));
|
|
2656
|
+
m.premultiply(new Matrix4().makeTranslation(pivot.x, pivot.y, pivot.z));
|
|
2657
|
+
return m;
|
|
2658
|
+
}
|
|
2659
|
+
function resolveConditionsAppearance(conditions, propertyData) {
|
|
2660
|
+
if (!conditions?.length) return null;
|
|
2661
|
+
for (const [cond, value] of conditions) if (evaluateStyleCondition(cond, propertyData)) return value;
|
|
2662
|
+
return null;
|
|
2663
|
+
}
|
|
2664
|
+
function resolveStyleAppearance(conditions, propertyData) {
|
|
2665
|
+
return resolveConditionsAppearance(conditions, propertyData);
|
|
2666
|
+
}
|
|
2667
|
+
/** 与 setStyle 相同的 OID 分组逻辑(show + conditions → 外观分组 + 被 show 隐藏的 OID) */
|
|
2668
|
+
function buildAppearanceGroupsFromPropertyMap(propertyByOid, config) {
|
|
2669
|
+
const hiddenOidsList = [];
|
|
2670
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2671
|
+
const conditions = config.conditions ?? [];
|
|
2672
|
+
for (const [oid, propertyData] of propertyByOid) {
|
|
2673
|
+
if (propertyData == null) continue;
|
|
2674
|
+
if (config.show) {
|
|
2675
|
+
if (!evaluateStyleCondition(config.show, propertyData)) {
|
|
2676
|
+
hiddenOidsList.push(oid);
|
|
2677
|
+
continue;
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
const appearance = resolveStyleAppearance(conditions, propertyData);
|
|
2681
|
+
if (!appearance) continue;
|
|
2682
|
+
const gkey = appearanceGroupKey(appearance);
|
|
2683
|
+
let g = groups.get(gkey);
|
|
2684
|
+
if (!g) {
|
|
2685
|
+
g = {
|
|
2686
|
+
appearance,
|
|
2687
|
+
oids: []
|
|
2688
|
+
};
|
|
2689
|
+
groups.set(gkey, g);
|
|
2690
|
+
}
|
|
2691
|
+
g.oids.push(oid);
|
|
2692
|
+
}
|
|
2693
|
+
return {
|
|
2694
|
+
hiddenOidsList,
|
|
2695
|
+
groups
|
|
2696
|
+
};
|
|
2697
|
+
}
|
|
2698
|
+
function restoreMeshAppearanceMaps(mesh, maps) {
|
|
2699
|
+
const original = maps.originalMaterialByMesh.get(mesh.uuid);
|
|
2700
|
+
if (original) {
|
|
2701
|
+
mesh.material = original;
|
|
2702
|
+
maps.originalMaterialByMesh.delete(mesh.uuid);
|
|
2703
|
+
}
|
|
2704
|
+
const origT = maps.originalTransformByMesh.get(mesh.uuid);
|
|
2705
|
+
if (origT) {
|
|
2706
|
+
mesh.position.copy(origT.position);
|
|
2707
|
+
mesh.scale.copy(origT.scale);
|
|
2708
|
+
mesh.rotation.copy(origT.rotation);
|
|
2709
|
+
maps.originalTransformByMesh.delete(mesh.uuid);
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2712
|
+
/**
|
|
2713
|
+
* 将 StyleAppearance 应用到 mesh(与 StyleHelper.applyAppearanceToCollector 一致)
|
|
2714
|
+
*/
|
|
2715
|
+
function applyStyleAppearanceToMesh(mesh, appearance, scene, maps) {
|
|
2716
|
+
if (!maps.originalMaterialByMesh.has(mesh.uuid)) maps.originalMaterialByMesh.set(mesh.uuid, mesh.material);
|
|
2717
|
+
mesh.material = appearance.material;
|
|
2718
|
+
if (appearance.translation !== void 0 || appearance.scale !== void 0 || appearance.rotation !== void 0) {
|
|
2719
|
+
if (!maps.originalTransformByMesh.has(mesh.uuid)) maps.originalTransformByMesh.set(mesh.uuid, {
|
|
2720
|
+
position: mesh.position.clone(),
|
|
2721
|
+
scale: mesh.scale.clone(),
|
|
2722
|
+
rotation: mesh.rotation.clone()
|
|
2723
|
+
});
|
|
2724
|
+
const bt = maps.originalTransformByMesh.get(mesh.uuid);
|
|
2725
|
+
mesh.position.copy(bt.position);
|
|
2726
|
+
mesh.scale.copy(bt.scale);
|
|
2727
|
+
mesh.rotation.copy(bt.rotation);
|
|
2728
|
+
if (appearance.scale !== void 0 || appearance.rotation !== void 0) {
|
|
2729
|
+
const pivot = new Vector3();
|
|
2730
|
+
if (appearance.origin !== void 0) applyVec3(pivot, appearance.origin);
|
|
2731
|
+
else pivot.set(0, 0, 0);
|
|
2732
|
+
let sx = 1;
|
|
2733
|
+
let sy = 1;
|
|
2734
|
+
let sz = 1;
|
|
2735
|
+
if (appearance.scale !== void 0) if (Array.isArray(appearance.scale)) {
|
|
2736
|
+
sx = appearance.scale[0] ?? 1;
|
|
2737
|
+
sy = appearance.scale[1] ?? 1;
|
|
2738
|
+
sz = appearance.scale[2] ?? 1;
|
|
2739
|
+
} else {
|
|
2740
|
+
const sc = appearance.scale;
|
|
2741
|
+
sx = sc.x;
|
|
2742
|
+
sy = sc.y;
|
|
2743
|
+
sz = sc.z;
|
|
2744
|
+
}
|
|
2745
|
+
const euler = new Euler();
|
|
2746
|
+
if (appearance.rotation !== void 0) applyEuler(euler, appearance.rotation);
|
|
2747
|
+
else euler.set(0, 0, 0);
|
|
2748
|
+
const styleM = buildPivotStyleMatrix(pivot, sx, sy, sz, euler);
|
|
2749
|
+
mesh.updateMatrix();
|
|
2750
|
+
mesh.matrix.multiply(styleM);
|
|
2751
|
+
mesh.matrix.decompose(mesh.position, mesh.quaternion, mesh.scale);
|
|
2752
|
+
}
|
|
2753
|
+
if (appearance.translation !== void 0) applyVec3(mesh.position, appearance.translation);
|
|
2754
|
+
}
|
|
2755
|
+
mesh.updateMatrixWorld();
|
|
2756
|
+
scene.add(mesh);
|
|
2757
|
+
}
|
|
2758
|
+
//#endregion
|
|
2759
|
+
//#region src/plugin/StyleHelper.ts
|
|
2760
|
+
/**
|
|
2761
|
+
* 构件样式辅助器
|
|
2762
|
+
* 通过 show 表达式控制可见性,通过 conditions 应用条件材质与可选位姿
|
|
2763
|
+
*/
|
|
2764
|
+
var StyleHelper = class {
|
|
2765
|
+
/** 当前样式配置,可通过 plugin.style 获取 */
|
|
2766
|
+
style = null;
|
|
2767
|
+
styledOids = /* @__PURE__ */ new Set();
|
|
2768
|
+
hiddenOids = /* @__PURE__ */ new Set();
|
|
2769
|
+
originalMaterialByMesh = /* @__PURE__ */ new Map();
|
|
2770
|
+
originalTransformByMesh = /* @__PURE__ */ new Map();
|
|
2771
|
+
/** 按材质分组后的收集器,key 与 collector.getCacheKey() 一致 */
|
|
2772
|
+
meshChangeHandlers = /* @__PURE__ */ new Map();
|
|
2773
|
+
/** 当前样式占用的收集器(用于 clearStyle / 下次 applyStyle 前卸载监听) */
|
|
2774
|
+
styleCollectors = [];
|
|
2775
|
+
constructor(context) {
|
|
2776
|
+
this.context = context;
|
|
2777
|
+
}
|
|
2778
|
+
/**
|
|
2779
|
+
* 设置样式
|
|
2780
|
+
* @param style 样式配置,传 null 或空对象清除样式
|
|
2781
|
+
*/
|
|
2782
|
+
setStyle(style) {
|
|
2783
|
+
this.clearStyle();
|
|
2784
|
+
this.style = style;
|
|
2785
|
+
if (!style || !style.show && (!style.conditions || style.conditions.length === 0)) return;
|
|
2786
|
+
this.applyStyle();
|
|
2787
|
+
}
|
|
2788
|
+
/**
|
|
2789
|
+
* 清除样式,恢复默认显示
|
|
2790
|
+
*/
|
|
2791
|
+
clearStyle() {
|
|
2792
|
+
const styledOidsList = Array.from(this.styledOids);
|
|
2793
|
+
const hiddenOidsList = Array.from(this.hiddenOids);
|
|
2794
|
+
for (const collector of this.styleCollectors) {
|
|
2795
|
+
collector.meshes.forEach((mesh) => {
|
|
2796
|
+
const original = this.originalMaterialByMesh.get(mesh.uuid);
|
|
2797
|
+
if (original) {
|
|
2798
|
+
mesh.material = original;
|
|
2799
|
+
this.originalMaterialByMesh.delete(mesh.uuid);
|
|
2800
|
+
}
|
|
2801
|
+
const origT = this.originalTransformByMesh.get(mesh.uuid);
|
|
2802
|
+
if (origT) {
|
|
2803
|
+
mesh.position.copy(origT.position);
|
|
2804
|
+
mesh.scale.copy(origT.scale);
|
|
2805
|
+
mesh.rotation.copy(origT.rotation);
|
|
2806
|
+
this.originalTransformByMesh.delete(mesh.uuid);
|
|
2807
|
+
}
|
|
2808
|
+
mesh.removeFromParent();
|
|
2809
|
+
});
|
|
2810
|
+
const handler = this.meshChangeHandlers.get(collector.getCacheKey());
|
|
2811
|
+
if (handler) collector.removeEventListener("mesh-change", handler);
|
|
2812
|
+
}
|
|
2813
|
+
this.meshChangeHandlers.clear();
|
|
2814
|
+
this.styleCollectors = [];
|
|
2815
|
+
this.style = null;
|
|
2816
|
+
this.styledOids.clear();
|
|
2817
|
+
this.hiddenOids.clear();
|
|
2818
|
+
this.context.showPartsByOids([...styledOidsList, ...hiddenOidsList]);
|
|
2819
|
+
}
|
|
2820
|
+
applyStyle() {
|
|
2821
|
+
const style = this.style;
|
|
2822
|
+
if (!style) return;
|
|
2823
|
+
if (!this.context.getScene()) return;
|
|
2824
|
+
const tiles = this.context.getTiles();
|
|
2825
|
+
if (!tiles) return;
|
|
2826
|
+
const propertyByOid = getPropertyDataMapFromTiles(tiles);
|
|
2827
|
+
for (const collector of this.styleCollectors) {
|
|
2828
|
+
const h = this.meshChangeHandlers.get(collector.getCacheKey());
|
|
2829
|
+
if (h) collector.removeEventListener("mesh-change", h);
|
|
2830
|
+
}
|
|
2831
|
+
this.styleCollectors = [];
|
|
2832
|
+
this.meshChangeHandlers.clear();
|
|
2833
|
+
const { hiddenOidsList, groups } = buildAppearanceGroupsFromPropertyMap(propertyByOid, {
|
|
2834
|
+
show: style.show,
|
|
2835
|
+
conditions: style.conditions ?? []
|
|
2836
|
+
});
|
|
2837
|
+
for (const { oids } of groups.values()) for (const oid of oids) this.styledOids.add(oid);
|
|
2838
|
+
this.hiddenOids = new Set(hiddenOidsList);
|
|
2839
|
+
const oidsToHide = [...hiddenOidsList];
|
|
2840
|
+
for (const { oids } of groups.values()) oidsToHide.push(...oids);
|
|
2841
|
+
const maps = {
|
|
2842
|
+
originalMaterialByMesh: this.originalMaterialByMesh,
|
|
2843
|
+
originalTransformByMesh: this.originalTransformByMesh
|
|
2844
|
+
};
|
|
2845
|
+
for (const { appearance, oids } of groups.values()) {
|
|
2846
|
+
const sortedOids = normalizeMeshCollectorOids(oids);
|
|
2847
|
+
const collector = this.context.getMeshCollectorByCondition({ oids: sortedOids });
|
|
2848
|
+
this.styleCollectors.push(collector);
|
|
2849
|
+
const cacheKey = collector.getCacheKey();
|
|
2850
|
+
const handler = () => {
|
|
2851
|
+
const s = this.context.getScene();
|
|
2852
|
+
if (!s) return;
|
|
2853
|
+
collector.meshes.forEach((mesh) => {
|
|
2854
|
+
applyStyleAppearanceToMesh(mesh, appearance, s, maps);
|
|
2855
|
+
});
|
|
2856
|
+
};
|
|
2857
|
+
this.meshChangeHandlers.set(cacheKey, handler);
|
|
2858
|
+
collector.addEventListener("mesh-change", handler);
|
|
2859
|
+
handler();
|
|
2860
|
+
}
|
|
2861
|
+
this.context.hidePartsByOids(oidsToHide);
|
|
2862
|
+
}
|
|
2863
|
+
/**
|
|
2864
|
+
* 瓦片加载完成后重新应用样式(由插件调用)
|
|
2865
|
+
*/
|
|
2866
|
+
onTilesLoadEnd() {
|
|
2867
|
+
if (this.style) this.applyStyle();
|
|
2868
|
+
}
|
|
2869
|
+
dispose() {
|
|
2870
|
+
this.clearStyle();
|
|
2871
|
+
}
|
|
2872
|
+
};
|
|
2873
|
+
//#endregion
|
|
2874
|
+
//#region src/plugin/PartHighlightHelper.ts
|
|
2875
|
+
var highlightMaterialCache = /* @__PURE__ */ new Map();
|
|
2876
|
+
function getMaterialForHighlight(style) {
|
|
2877
|
+
const color = style.color != null ? toColor(style.color) : new Color(16776960);
|
|
2878
|
+
const opacity = style.opacity != null ? Math.max(0, Math.min(1, style.opacity)) : 1;
|
|
2879
|
+
const key = `${color.getHex()}_${opacity}`;
|
|
2880
|
+
if (!highlightMaterialCache.has(key)) {
|
|
2881
|
+
const mat = new MeshStandardMaterial({
|
|
2882
|
+
color: color.clone(),
|
|
2883
|
+
roughness: .5,
|
|
2884
|
+
metalness: .1,
|
|
2885
|
+
opacity,
|
|
2886
|
+
transparent: opacity < 1
|
|
2887
|
+
});
|
|
2888
|
+
highlightMaterialCache.set(key, mat);
|
|
2889
|
+
}
|
|
2890
|
+
return highlightMaterialCache.get(key);
|
|
2891
|
+
}
|
|
2892
|
+
function toMaterial(value) {
|
|
2893
|
+
if (value instanceof Material) return value;
|
|
2894
|
+
return getMaterialForHighlight(value);
|
|
2895
|
+
}
|
|
2896
|
+
function toStyleAppearance(ha) {
|
|
2897
|
+
return {
|
|
2898
|
+
material: toMaterial(ha.material),
|
|
2899
|
+
translation: ha.translation,
|
|
2900
|
+
scale: ha.scale,
|
|
2901
|
+
rotation: ha.rotation,
|
|
2902
|
+
origin: ha.origin
|
|
2903
|
+
};
|
|
2904
|
+
}
|
|
2905
|
+
/**
|
|
2906
|
+
* 构件高亮辅助器
|
|
2907
|
+
* 与 setStyle 相同的 show / conditions / 位姿语义,多组命名高亮;底层通过 hidePartsByOids + split mesh 实现
|
|
2908
|
+
*/
|
|
2909
|
+
var PartHighlightHelper = class {
|
|
2910
|
+
highlightGroups = /* @__PURE__ */ new Map();
|
|
2911
|
+
originalMaterialByMesh = /* @__PURE__ */ new Map();
|
|
2912
|
+
originalTransformByMesh = /* @__PURE__ */ new Map();
|
|
2913
|
+
meshChangeHandlers = /* @__PURE__ */ new Map();
|
|
2914
|
+
highlightCollectors = [];
|
|
2915
|
+
/** 上次 hidePartsByOids 传入的 OID 列表,用于重新应用前 showParts */
|
|
2916
|
+
lastHiddenOids = [];
|
|
2917
|
+
constructor(context) {
|
|
2918
|
+
this.context = context;
|
|
2919
|
+
}
|
|
2920
|
+
getMaps() {
|
|
2921
|
+
return {
|
|
2922
|
+
originalMaterialByMesh: this.originalMaterialByMesh,
|
|
2923
|
+
originalTransformByMesh: this.originalTransformByMesh
|
|
2924
|
+
};
|
|
2925
|
+
}
|
|
2926
|
+
/**
|
|
2927
|
+
* 合并多组命名高亮:按 Map 插入顺序,后写入的组覆盖同一 OID 的外观
|
|
2928
|
+
*/
|
|
2929
|
+
mergeAppearanceByOid(propertyByOid) {
|
|
2930
|
+
const appearanceByOid = /* @__PURE__ */ new Map();
|
|
2931
|
+
for (const [, hl] of this.highlightGroups) {
|
|
2932
|
+
const conditions = (hl.conditions ?? []).map(([c, h]) => [c, toStyleAppearance(h)]);
|
|
2933
|
+
for (const [oid, propertyData] of propertyByOid) {
|
|
2934
|
+
if (propertyData == null) continue;
|
|
2935
|
+
if (hl.oids && !hl.oids.includes(oid)) continue;
|
|
2936
|
+
if (hl.show && !evaluateStyleCondition(hl.show, propertyData)) continue;
|
|
2937
|
+
const app = resolveConditionsAppearance(conditions, propertyData);
|
|
2938
|
+
if (!app) continue;
|
|
2939
|
+
appearanceByOid.set(oid, app);
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2942
|
+
return appearanceByOid;
|
|
2943
|
+
}
|
|
2944
|
+
/** 各组 show 失败需隐藏的 OID(与 setStyle 一致:show 不满足则隐藏原片) */
|
|
2945
|
+
collectUnionShowHide(propertyByOid) {
|
|
2946
|
+
const unionHide = /* @__PURE__ */ new Set();
|
|
2947
|
+
for (const [, hl] of this.highlightGroups) for (const [oid, propertyData] of propertyByOid) {
|
|
2948
|
+
if (propertyData == null) continue;
|
|
2949
|
+
if (hl.oids && !hl.oids.includes(oid)) continue;
|
|
2950
|
+
if (hl.show && !evaluateStyleCondition(hl.show, propertyData)) unionHide.add(oid);
|
|
2951
|
+
}
|
|
2952
|
+
return unionHide;
|
|
2953
|
+
}
|
|
2954
|
+
clearCollectorsAndRestoreMeshes() {
|
|
2955
|
+
const maps = this.getMaps();
|
|
2956
|
+
for (const collector of this.highlightCollectors) {
|
|
2957
|
+
collector.meshes.forEach((mesh) => {
|
|
2958
|
+
restoreMeshAppearanceMaps(mesh, maps);
|
|
2959
|
+
mesh.removeFromParent();
|
|
2960
|
+
});
|
|
2961
|
+
const handler = this.meshChangeHandlers.get(collector.getCacheKey());
|
|
2962
|
+
if (handler) collector.removeEventListener("mesh-change", handler);
|
|
2963
|
+
}
|
|
2964
|
+
this.meshChangeHandlers.clear();
|
|
2965
|
+
this.highlightCollectors = [];
|
|
2966
|
+
}
|
|
2967
|
+
reapplyAll() {
|
|
2968
|
+
this.clearCollectorsAndRestoreMeshes();
|
|
2969
|
+
if (this.lastHiddenOids.length > 0) this.context.showPartsByOids(this.lastHiddenOids);
|
|
2970
|
+
if (this.highlightGroups.size === 0) {
|
|
2971
|
+
this.lastHiddenOids = [];
|
|
2972
|
+
return;
|
|
2973
|
+
}
|
|
2974
|
+
const tiles = this.context.getTiles();
|
|
2975
|
+
const scene = this.context.getScene();
|
|
2976
|
+
if (!tiles || !scene) return;
|
|
2977
|
+
const propertyByOid = getPropertyDataMapFromTiles(tiles);
|
|
2978
|
+
const appearanceByOid = this.mergeAppearanceByOid(propertyByOid);
|
|
2979
|
+
const unionHide = this.collectUnionShowHide(propertyByOid);
|
|
2980
|
+
const oidsToHide = [...new Set([...appearanceByOid.keys(), ...unionHide])];
|
|
2981
|
+
this.lastHiddenOids = oidsToHide;
|
|
2982
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2983
|
+
for (const [oid, app] of appearanceByOid) {
|
|
2984
|
+
const gkey = appearanceGroupKey(app);
|
|
2985
|
+
let g = groups.get(gkey);
|
|
2986
|
+
if (!g) {
|
|
2987
|
+
g = {
|
|
2988
|
+
appearance: app,
|
|
2989
|
+
oids: []
|
|
2990
|
+
};
|
|
2991
|
+
groups.set(gkey, g);
|
|
2992
|
+
}
|
|
2993
|
+
g.oids.push(oid);
|
|
2994
|
+
}
|
|
2995
|
+
const maps = this.getMaps();
|
|
2996
|
+
for (const { appearance, oids } of groups.values()) {
|
|
2997
|
+
const sortedOids = normalizeMeshCollectorOids(oids);
|
|
2998
|
+
const collector = this.context.getMeshCollectorByCondition({ oids: sortedOids });
|
|
2999
|
+
this.highlightCollectors.push(collector);
|
|
3000
|
+
const cacheKey = collector.getCacheKey();
|
|
3001
|
+
const handler = () => {
|
|
3002
|
+
const s = this.context.getScene();
|
|
3003
|
+
if (!s) return;
|
|
3004
|
+
collector.meshes.forEach((mesh) => {
|
|
3005
|
+
applyStyleAppearanceToMesh(mesh, appearance, s, maps);
|
|
3006
|
+
});
|
|
3007
|
+
};
|
|
3008
|
+
this.meshChangeHandlers.set(cacheKey, handler);
|
|
3009
|
+
collector.addEventListener("mesh-change", handler);
|
|
3010
|
+
handler();
|
|
3011
|
+
}
|
|
3012
|
+
this.context.hidePartsByOids(oidsToHide);
|
|
3013
|
+
}
|
|
3014
|
+
/**
|
|
3015
|
+
* 高亮指定构件(语义与 setStyle 一致,多 name 参数)
|
|
3016
|
+
*/
|
|
3017
|
+
highlight(options) {
|
|
3018
|
+
const { name, show, conditions, oids } = options;
|
|
3019
|
+
if (!show && (!conditions || conditions.length === 0)) {
|
|
3020
|
+
this.cancelHighlight(name);
|
|
3021
|
+
return;
|
|
3022
|
+
}
|
|
3023
|
+
this.highlightGroups.set(name, {
|
|
3024
|
+
show,
|
|
3025
|
+
conditions,
|
|
3026
|
+
oids
|
|
3027
|
+
});
|
|
3028
|
+
this.reapplyAll();
|
|
3029
|
+
}
|
|
3030
|
+
/**
|
|
3031
|
+
* 取消指定名称的高亮
|
|
3032
|
+
*/
|
|
3033
|
+
cancelHighlight(name) {
|
|
3034
|
+
if (!this.highlightGroups.has(name)) return;
|
|
3035
|
+
this.highlightGroups.delete(name);
|
|
3036
|
+
this.reapplyAll();
|
|
3037
|
+
}
|
|
3038
|
+
/**
|
|
3039
|
+
* 取消所有高亮
|
|
3040
|
+
*/
|
|
3041
|
+
cancelAllHighlight() {
|
|
3042
|
+
this.highlightGroups.clear();
|
|
3043
|
+
this.reapplyAll();
|
|
3044
|
+
}
|
|
3045
|
+
/**
|
|
3046
|
+
* 瓦片加载完成后重新应用高亮(由插件调用)
|
|
3047
|
+
*/
|
|
3048
|
+
onTilesLoadEnd() {
|
|
3049
|
+
if (this.highlightGroups.size === 0) return;
|
|
3050
|
+
this.reapplyAll();
|
|
3051
|
+
}
|
|
3052
|
+
dispose() {
|
|
3053
|
+
this.cancelAllHighlight();
|
|
3054
|
+
}
|
|
3055
|
+
};
|
|
3056
|
+
//#endregion
|
|
1999
3057
|
//#region src/plugin/InteractionFilter.ts
|
|
2000
3058
|
/**
|
|
2001
|
-
* 冻结与隔离逻辑:管理构件的交互过滤及
|
|
3059
|
+
* 冻结与隔离逻辑:管理构件的交互过滤及 MeshCollector 获取的 mesh 在场景中的显隐
|
|
3060
|
+
* split mesh 使用 userData.oid(单 feature)或 userData.collectorOids(合并 mesh):任一相关 OID 被冻结/隔离规则命中则整 mesh 脱离场景
|
|
2002
3061
|
*/
|
|
2003
3062
|
var InteractionFilter = class {
|
|
2004
3063
|
frozenOids = /* @__PURE__ */ new Set();
|
|
2005
3064
|
isolatedOids = /* @__PURE__ */ new Set();
|
|
3065
|
+
/** 按 collector 分组键追踪 mesh */
|
|
2006
3066
|
trackedMeshes = /* @__PURE__ */ new Map();
|
|
2007
3067
|
meshListeners = /* @__PURE__ */ new Map();
|
|
2008
3068
|
isPluginRemoving = false;
|
|
@@ -2014,12 +3074,19 @@ var InteractionFilter = class {
|
|
|
2014
3074
|
if (this.isolatedOids.size > 0 && !this.isolatedOids.has(oid)) return true;
|
|
2015
3075
|
return false;
|
|
2016
3076
|
}
|
|
2017
|
-
|
|
3077
|
+
/** 合并 split:任一 collector OID 被 block 则整 mesh 视为应隐藏 */
|
|
3078
|
+
isMeshInteractionBlocked(mesh) {
|
|
3079
|
+
const coids = mesh.userData?.collectorOids;
|
|
3080
|
+
if (coids && coids.length > 0) return coids.some((oid) => this.isOidBlocked(oid));
|
|
3081
|
+
const oid = mesh.userData?.oid;
|
|
3082
|
+
return oid !== void 0 && this.isOidBlocked(oid);
|
|
3083
|
+
}
|
|
3084
|
+
trackMesh(mesh) {
|
|
2018
3085
|
if (this.meshListeners.has(mesh)) return;
|
|
2019
3086
|
const onAdded = () => {
|
|
2020
3087
|
if (this.isPluginRemoving) return;
|
|
2021
3088
|
mesh.userData._detachedParent = null;
|
|
2022
|
-
if (this.
|
|
3089
|
+
if (this.isMeshInteractionBlocked(mesh) && mesh.parent) {
|
|
2023
3090
|
const parent = mesh.parent;
|
|
2024
3091
|
this.isPluginRemoving = true;
|
|
2025
3092
|
mesh.userData._detachedParent = parent;
|
|
@@ -2047,8 +3114,8 @@ var InteractionFilter = class {
|
|
|
2047
3114
|
}
|
|
2048
3115
|
mesh.userData._detachedParent = null;
|
|
2049
3116
|
}
|
|
2050
|
-
onCollectorMeshChange(
|
|
2051
|
-
const tracked = this.trackedMeshes.get(
|
|
3117
|
+
onCollectorMeshChange(groupKey, newMeshes) {
|
|
3118
|
+
const tracked = this.trackedMeshes.get(groupKey);
|
|
2052
3119
|
const newSet = new Set(newMeshes);
|
|
2053
3120
|
if (tracked) {
|
|
2054
3121
|
for (const mesh of tracked) if (!newSet.has(mesh)) {
|
|
@@ -2058,39 +3125,36 @@ var InteractionFilter = class {
|
|
|
2058
3125
|
}
|
|
2059
3126
|
const trackSet = tracked || /* @__PURE__ */ new Set();
|
|
2060
3127
|
for (const mesh of newMeshes) if (!trackSet.has(mesh)) {
|
|
2061
|
-
this.trackMesh(mesh
|
|
3128
|
+
this.trackMesh(mesh);
|
|
2062
3129
|
trackSet.add(mesh);
|
|
2063
3130
|
}
|
|
2064
|
-
this.trackedMeshes.set(
|
|
3131
|
+
this.trackedMeshes.set(groupKey, trackSet);
|
|
2065
3132
|
}
|
|
2066
3133
|
syncCollectorMeshes() {
|
|
2067
3134
|
this.isPluginRemoving = true;
|
|
2068
|
-
for (const [
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
if (!
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
storedParent.add(mesh);
|
|
2082
|
-
mesh.userData._detachedParent = null;
|
|
2083
|
-
}
|
|
3135
|
+
for (const [, collector] of this.context.getCollectorCache()) for (const mesh of collector.meshes) {
|
|
3136
|
+
if (!this.meshListeners.has(mesh)) continue;
|
|
3137
|
+
if (this.isMeshInteractionBlocked(mesh)) {
|
|
3138
|
+
if (mesh.parent && !mesh.userData._detachedParent) {
|
|
3139
|
+
const parent = mesh.parent;
|
|
3140
|
+
mesh.userData._detachedParent = parent;
|
|
3141
|
+
parent.remove(mesh);
|
|
3142
|
+
}
|
|
3143
|
+
} else {
|
|
3144
|
+
const storedParent = mesh.userData._detachedParent;
|
|
3145
|
+
if (storedParent && !mesh.parent) {
|
|
3146
|
+
storedParent.add(mesh);
|
|
3147
|
+
mesh.userData._detachedParent = null;
|
|
2084
3148
|
}
|
|
2085
3149
|
}
|
|
2086
3150
|
}
|
|
2087
3151
|
this.isPluginRemoving = false;
|
|
2088
3152
|
}
|
|
2089
|
-
onUnregisterCollector(
|
|
2090
|
-
const tracked = this.trackedMeshes.get(
|
|
3153
|
+
onUnregisterCollector(groupKey) {
|
|
3154
|
+
const tracked = this.trackedMeshes.get(groupKey);
|
|
2091
3155
|
if (tracked) {
|
|
2092
3156
|
for (const mesh of tracked) this.untrackMesh(mesh);
|
|
2093
|
-
this.trackedMeshes.delete(
|
|
3157
|
+
this.trackedMeshes.delete(groupKey);
|
|
2094
3158
|
}
|
|
2095
3159
|
}
|
|
2096
3160
|
freezeByOids(oids) {
|
|
@@ -2098,16 +3162,14 @@ var InteractionFilter = class {
|
|
|
2098
3162
|
this.syncCollectorMeshes();
|
|
2099
3163
|
}
|
|
2100
3164
|
freezeByOid(oid) {
|
|
2101
|
-
this.
|
|
2102
|
-
this.syncCollectorMeshes();
|
|
3165
|
+
this.freezeByOids([oid]);
|
|
2103
3166
|
}
|
|
2104
3167
|
unfreezeByOids(oids) {
|
|
2105
3168
|
for (const oid of oids) this.frozenOids.delete(oid);
|
|
2106
3169
|
this.syncCollectorMeshes();
|
|
2107
3170
|
}
|
|
2108
3171
|
unfreezeByOid(oid) {
|
|
2109
|
-
this.
|
|
2110
|
-
this.syncCollectorMeshes();
|
|
3172
|
+
this.unfreezeByOids([oid]);
|
|
2111
3173
|
}
|
|
2112
3174
|
unfreeze() {
|
|
2113
3175
|
this.frozenOids.clear();
|
|
@@ -2129,8 +3191,7 @@ var InteractionFilter = class {
|
|
|
2129
3191
|
this.syncCollectorMeshes();
|
|
2130
3192
|
}
|
|
2131
3193
|
unisolateByOid(oid) {
|
|
2132
|
-
this.
|
|
2133
|
-
this.syncCollectorMeshes();
|
|
3194
|
+
this.unisolateByOids([oid]);
|
|
2134
3195
|
}
|
|
2135
3196
|
unisolate() {
|
|
2136
3197
|
this.isolatedOids.clear();
|
|
@@ -2242,18 +3303,23 @@ var GLTFParserPlugin = class {
|
|
|
2242
3303
|
_options;
|
|
2243
3304
|
_structureData = null;
|
|
2244
3305
|
_oidNodeMap = /* @__PURE__ */ new Map();
|
|
2245
|
-
|
|
3306
|
+
/** rootTileset 已存在且已尝试过内嵌解析后仍为 null,则不再重复 gunzip */
|
|
3307
|
+
_structureEmbedResolved = false;
|
|
2246
3308
|
_modelInfo = null;
|
|
2247
3309
|
_modelInfoPromise = null;
|
|
2248
3310
|
_interactionFilter;
|
|
2249
3311
|
_partColorHelper = null;
|
|
2250
3312
|
_partBlinkHelper = null;
|
|
2251
3313
|
_partFrameHelper = null;
|
|
3314
|
+
_styleHelper = null;
|
|
3315
|
+
_partHighlightHelper = null;
|
|
2252
3316
|
oids = [];
|
|
2253
|
-
|
|
3317
|
+
/** WebGLRenderer 实例,用于 mesh helper 等扩展 */
|
|
3318
|
+
get renderer() {
|
|
3319
|
+
return this._renderer;
|
|
3320
|
+
}
|
|
3321
|
+
_renderer = null;
|
|
2254
3322
|
splitMeshCache = /* @__PURE__ */ new Map();
|
|
2255
|
-
maxUniformVectors = 1024;
|
|
2256
|
-
featureIdCount = 32;
|
|
2257
3323
|
collectors = /* @__PURE__ */ new Set();
|
|
2258
3324
|
collectorCache = /* @__PURE__ */ new Map();
|
|
2259
3325
|
/**
|
|
@@ -2267,7 +3333,7 @@ var GLTFParserPlugin = class {
|
|
|
2267
3333
|
useIndexedDB: false,
|
|
2268
3334
|
...options
|
|
2269
3335
|
};
|
|
2270
|
-
if (options?.renderer) this.
|
|
3336
|
+
if (options?.renderer) this._renderer = options.renderer;
|
|
2271
3337
|
this._interactionFilter = new InteractionFilter({ getCollectorCache: () => this.collectorCache });
|
|
2272
3338
|
setMaxWorkers(this._options.maxWorkers);
|
|
2273
3339
|
}
|
|
@@ -2276,38 +3342,43 @@ var GLTFParserPlugin = class {
|
|
|
2276
3342
|
*/
|
|
2277
3343
|
init(tiles) {
|
|
2278
3344
|
this.tiles = tiles;
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
getScene: () => this.tiles?.group ?? null
|
|
2290
|
-
});
|
|
2291
|
-
this._partFrameHelper = new PartFrameHelper({
|
|
2292
|
-
hidePartsByOids: (oids) => this.hidePartsByOids(oids),
|
|
2293
|
-
showPartsByOids: (oids) => this.showPartsByOids(oids),
|
|
2294
|
-
getMeshCollectorByOid: (oid) => this.getMeshCollectorByOid(oid),
|
|
2295
|
-
getScene: () => this.tiles?.group ?? null
|
|
3345
|
+
const partFx = this._createPartEffectHost();
|
|
3346
|
+
this._partColorHelper = new PartColorHelper(partFx);
|
|
3347
|
+
this._partBlinkHelper = new PartBlinkHelper(partFx);
|
|
3348
|
+
this._partFrameHelper = new PartFrameHelper(partFx);
|
|
3349
|
+
this._styleHelper = new StyleHelper({
|
|
3350
|
+
getTiles: () => this.tiles,
|
|
3351
|
+
hidePartsByOids: partFx.hidePartsByOids,
|
|
3352
|
+
showPartsByOids: partFx.showPartsByOids,
|
|
3353
|
+
getMeshCollectorByCondition: partFx.getMeshCollectorByCondition,
|
|
3354
|
+
getScene: partFx.getScene
|
|
2296
3355
|
});
|
|
3356
|
+
this._partHighlightHelper = new PartHighlightHelper(partFx);
|
|
2297
3357
|
this._loader = new GLTFWorkerLoader(tiles.manager, {
|
|
2298
3358
|
metadata: this._options.metadata,
|
|
2299
3359
|
materialBuilder: this._options.materialBuilder
|
|
2300
3360
|
});
|
|
2301
3361
|
tiles.manager.addHandler(this._gltfRegex, this._loader);
|
|
2302
|
-
if (this.renderer) this._updateWebGLLimits();
|
|
2303
3362
|
tiles.addEventListener("load-model", this._onLoadModelCB);
|
|
2304
3363
|
tiles.addEventListener("tiles-load-end", this._onTilesLoadEndCB);
|
|
3364
|
+
tiles.addEventListener("load-root-tileset", this._onLoadRootTilesetCB);
|
|
3365
|
+
this._syncStructureFromTileset();
|
|
2305
3366
|
tiles.traverse((tile) => {
|
|
2306
3367
|
const tileWithCache = tile;
|
|
2307
|
-
if (tileWithCache.
|
|
3368
|
+
if (tileWithCache.engineData?.scene) this._onLoadModel(tileWithCache.engineData.scene);
|
|
2308
3369
|
return true;
|
|
2309
3370
|
}, null);
|
|
2310
3371
|
}
|
|
3372
|
+
_createPartEffectHost() {
|
|
3373
|
+
return {
|
|
3374
|
+
getTiles: () => this.tiles ?? null,
|
|
3375
|
+
hidePartsByOids: (oids) => this.hidePartsByOids(oids),
|
|
3376
|
+
showPartsByOids: (oids) => this.showPartsByOids(oids),
|
|
3377
|
+
getMeshCollectorByOid: (oid) => this.getMeshCollectorByOid(oid),
|
|
3378
|
+
getMeshCollectorByCondition: (q) => this.getMeshCollectorByCondition(q),
|
|
3379
|
+
getScene: () => this.tiles?.group ?? null
|
|
3380
|
+
};
|
|
3381
|
+
}
|
|
2311
3382
|
/**
|
|
2312
3383
|
* Fetch tile data with IndexedDB caching support
|
|
2313
3384
|
*/
|
|
@@ -2339,56 +3410,51 @@ var GLTFParserPlugin = class {
|
|
|
2339
3410
|
if (this._options.beforeParseTile) buffer = await this._options.beforeParseTile(buffer, tile, extension, uri, abortSignal);
|
|
2340
3411
|
return this.tiles.parseTile(buffer, tile, extension, uri, abortSignal);
|
|
2341
3412
|
}
|
|
2342
|
-
|
|
3413
|
+
/** 与 tileset 同目录的侧车 JSON,如 structure.json / modelInfo.json */
|
|
3414
|
+
_sidecarJsonUrl(fileName) {
|
|
2343
3415
|
const rootURL = this.tiles?.rootURL;
|
|
2344
3416
|
if (!rootURL) return null;
|
|
2345
|
-
return rootURL.replace(/[^/]+$/,
|
|
3417
|
+
return rootURL.replace(/[^/]+$/, fileName);
|
|
2346
3418
|
}
|
|
2347
3419
|
_buildOidNodeMap(node, map) {
|
|
2348
3420
|
if (node.id !== void 0) map.set(node.id, node);
|
|
2349
3421
|
if (node.children) for (const child of node.children) this._buildOidNodeMap(child, map);
|
|
2350
3422
|
}
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
const data = await response.json();
|
|
2364
|
-
this._structureData = data;
|
|
2365
|
-
this._oidNodeMap.clear();
|
|
2366
|
-
if (data.trees) for (const tree of data.trees) this._buildOidNodeMap(tree, this._oidNodeMap);
|
|
2367
|
-
return data;
|
|
2368
|
-
} catch (error) {
|
|
2369
|
-
console.error("[GLTFParserPlugin] Error loading structure.json:", error);
|
|
2370
|
-
return null;
|
|
2371
|
-
}
|
|
2372
|
-
}
|
|
2373
|
-
async _ensureStructureLoaded() {
|
|
3423
|
+
/** 仅根 tileset 变化时重解析 structureUri(子 tileset 的 load-tileset 不会触发) */
|
|
3424
|
+
_onLoadRootTilesetCB = () => {
|
|
3425
|
+
this._structureData = null;
|
|
3426
|
+
this._oidNodeMap.clear();
|
|
3427
|
+
this._structureEmbedResolved = false;
|
|
3428
|
+
this._syncStructureFromTileset();
|
|
3429
|
+
};
|
|
3430
|
+
/**
|
|
3431
|
+
* 从已加载根 tileset 的内嵌 structure(优先 asset.extras.maptalks.structureUri)同步解压并建索引。
|
|
3432
|
+
* rootTileset 尚未就绪时返回 null,可稍后再次调用;已成功或已判定无内嵌数据后见 _structureEmbedResolved。
|
|
3433
|
+
*/
|
|
3434
|
+
_syncStructureFromTileset() {
|
|
2374
3435
|
if (this._structureData) return this._structureData;
|
|
2375
|
-
if (
|
|
2376
|
-
|
|
3436
|
+
if (this._structureEmbedResolved) return null;
|
|
3437
|
+
if (!this.tiles?.rootTileset) return null;
|
|
3438
|
+
const embedded = parseEmbeddedStructureDataFromTilesSync(this.tiles);
|
|
3439
|
+
this._structureEmbedResolved = true;
|
|
3440
|
+
if (!embedded) return null;
|
|
3441
|
+
this._structureData = embedded;
|
|
3442
|
+
this._oidNodeMap.clear();
|
|
3443
|
+
if (embedded.trees) for (const tree of embedded.trees) this._buildOidNodeMap(tree, this._oidNodeMap);
|
|
3444
|
+
return embedded;
|
|
2377
3445
|
}
|
|
2378
3446
|
/**
|
|
2379
|
-
* 根据 oid
|
|
2380
|
-
* 包含 bbox、children、name 等完整结构信息
|
|
2381
|
-
* 首次调用时会自动从 tileset URL 推导并请求 structure.json
|
|
3447
|
+
* 根据 oid 获取结构树节点(数据来自 tileset 内嵌 structureUri 同步解压)
|
|
2382
3448
|
*/
|
|
2383
|
-
|
|
2384
|
-
|
|
3449
|
+
getNodeTreeByOid(oid) {
|
|
3450
|
+
this._syncStructureFromTileset();
|
|
2385
3451
|
return this._oidNodeMap.get(oid) ?? null;
|
|
2386
3452
|
}
|
|
2387
3453
|
/**
|
|
2388
|
-
* 根据 oid
|
|
3454
|
+
* 根据 oid 数组批量获取结构树节点
|
|
2389
3455
|
*/
|
|
2390
|
-
|
|
2391
|
-
|
|
3456
|
+
getNodeTreeByOids(oids) {
|
|
3457
|
+
this._syncStructureFromTileset();
|
|
2392
3458
|
const result = /* @__PURE__ */ new Map();
|
|
2393
3459
|
for (const oid of oids) {
|
|
2394
3460
|
const node = this._oidNodeMap.get(oid);
|
|
@@ -2397,41 +3463,58 @@ var GLTFParserPlugin = class {
|
|
|
2397
3463
|
return result;
|
|
2398
3464
|
}
|
|
2399
3465
|
/**
|
|
2400
|
-
*
|
|
2401
|
-
*
|
|
3466
|
+
* 根据 oid 从结构数据取轴对齐包围盒(`bbox` 为 `[minX,minY,minZ,maxX,maxY,maxZ]`,与 `selectByBox` 一致)
|
|
3467
|
+
* @returns 无对应节点或缺少有效 bbox 时返回 `null`
|
|
2402
3468
|
*/
|
|
2403
|
-
|
|
2404
|
-
|
|
3469
|
+
getBoundingBoxByOid(oid) {
|
|
3470
|
+
this._syncStructureFromTileset();
|
|
3471
|
+
return bboxArrayToBox3(this._oidNodeMap.get(oid)?.bbox);
|
|
2405
3472
|
}
|
|
2406
3473
|
/**
|
|
2407
|
-
*
|
|
2408
|
-
*
|
|
2409
|
-
* @returns 范围内所有构件的 oid 数组
|
|
3474
|
+
* 计算给定 OID 集合的几何中心(世界坐标系与结构 bbox / 瓦片 mesh 一致)。
|
|
3475
|
+
* 优先合并结构树中的轴对齐 bbox;若无有效 bbox 则合并对应 split mesh 的世界包围盒。
|
|
2410
3476
|
*/
|
|
2411
|
-
|
|
2412
|
-
|
|
3477
|
+
getCenterByOids(oids) {
|
|
3478
|
+
if (!this.tiles || oids.length === 0) return null;
|
|
3479
|
+
const unique = [...new Set(oids)];
|
|
3480
|
+
if (unique.length === 0) return null;
|
|
3481
|
+
return this._getCenterFromOidList(unique);
|
|
3482
|
+
}
|
|
3483
|
+
/**
|
|
3484
|
+
* 按属性条件筛选构件(语义同 `setStyle` 的 `show` / conditions 中的表达式字符串),
|
|
3485
|
+
* 返回筛选结果的整体中心点;合并方式同 {@link getCenterByOids}。
|
|
3486
|
+
*/
|
|
3487
|
+
getCenterByCondition(condition) {
|
|
3488
|
+
if (!this.tiles) return null;
|
|
3489
|
+
const cond = condition.trim();
|
|
3490
|
+
if (!cond) return null;
|
|
3491
|
+
const targetOids = [];
|
|
3492
|
+
for (const oid of getAllOidsFromTiles(this.tiles)) if (evaluateStyleCondition(cond, getPropertyDataByOid(this.tiles, oid))) targetOids.push(oid);
|
|
3493
|
+
if (targetOids.length === 0) return null;
|
|
3494
|
+
return this._getCenterFromOidList(targetOids);
|
|
3495
|
+
}
|
|
3496
|
+
/**
|
|
3497
|
+
* 完整结构数据(与内嵌 structure JSON 一致)
|
|
3498
|
+
*/
|
|
3499
|
+
getStructureData() {
|
|
3500
|
+
return this._syncStructureFromTileset();
|
|
3501
|
+
}
|
|
3502
|
+
/**
|
|
3503
|
+
* 选择包围盒范围内的构件(坐标系与结构 bbox 一致)
|
|
3504
|
+
*/
|
|
3505
|
+
selectByBox(box) {
|
|
3506
|
+
this._syncStructureFromTileset();
|
|
2413
3507
|
return selectByBoxFromOidMap(this._oidNodeMap, box);
|
|
2414
3508
|
}
|
|
2415
3509
|
/**
|
|
2416
|
-
*
|
|
2417
|
-
* @param polygon 多边形顶点数组(Vector3),按顺序连接构成闭合多边形
|
|
2418
|
-
* @param axis 投影平面,决定使用 bbox 的哪两个轴做 2D 判定
|
|
2419
|
-
* - 'xz'(默认):俯视图,取 bbox 的 x/z 坐标
|
|
2420
|
-
* - 'xy':正视图,取 bbox 的 x/y 坐标
|
|
2421
|
-
* - 'yz':侧视图,取 bbox 的 y/z 坐标
|
|
2422
|
-
* @returns 范围内所有构件的 oid 数组
|
|
3510
|
+
* 选择多边形(平面投影)范围内的构件
|
|
2423
3511
|
*/
|
|
2424
|
-
|
|
2425
|
-
|
|
3512
|
+
selectByPolygon(polygon, axis = "xz") {
|
|
3513
|
+
this._syncStructureFromTileset();
|
|
2426
3514
|
return selectByPolygonFromOidMap(this._oidNodeMap, polygon, axis);
|
|
2427
3515
|
}
|
|
2428
|
-
_getModelInfoUrl() {
|
|
2429
|
-
const rootURL = this.tiles?.rootURL;
|
|
2430
|
-
if (!rootURL) return null;
|
|
2431
|
-
return rootURL.replace(/[^/]+$/, "modelInfo.json");
|
|
2432
|
-
}
|
|
2433
3516
|
async _fetchModelInfo() {
|
|
2434
|
-
const url = this.
|
|
3517
|
+
const url = this._sidecarJsonUrl("modelInfo.json");
|
|
2435
3518
|
if (!url) {
|
|
2436
3519
|
console.warn("[GLTFParserPlugin] Cannot derive modelInfo.json URL: tiles not initialized");
|
|
2437
3520
|
return null;
|
|
@@ -2481,83 +3564,41 @@ var GLTFParserPlugin = class {
|
|
|
2481
3564
|
scene.traverse((c) => {
|
|
2482
3565
|
if (c.material) this._setupMaterial(c);
|
|
2483
3566
|
});
|
|
3567
|
+
applyVisibilityToScene(scene, new Set(this.oids));
|
|
2484
3568
|
}
|
|
2485
3569
|
_notifyCollectors() {
|
|
2486
3570
|
for (const collector of this.collectors) collector._updateMeshes();
|
|
3571
|
+
this._styleHelper?.onTilesLoadEnd();
|
|
2487
3572
|
}
|
|
2488
3573
|
_registerCollector(collector) {
|
|
2489
3574
|
this.collectors.add(collector);
|
|
2490
3575
|
}
|
|
2491
3576
|
_unregisterCollector(collector) {
|
|
2492
|
-
const
|
|
3577
|
+
const key = collector.getCacheKey();
|
|
2493
3578
|
this.collectors.delete(collector);
|
|
2494
|
-
this.collectorCache.delete(
|
|
2495
|
-
this._interactionFilter.onUnregisterCollector(
|
|
2496
|
-
}
|
|
2497
|
-
_updateWebGLLimits() {
|
|
2498
|
-
const gl = this.renderer.getContext();
|
|
2499
|
-
this.maxUniformVectors = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS);
|
|
3579
|
+
this.collectorCache.delete(key);
|
|
3580
|
+
this._interactionFilter.onUnregisterCollector(key);
|
|
2500
3581
|
}
|
|
2501
3582
|
/**
|
|
2502
|
-
*
|
|
3583
|
+
* 遍历所有已加载瓦片,应用可见性过滤
|
|
2503
3584
|
*/
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
const
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
3585
|
+
_applyVisibilityToAllTiles() {
|
|
3586
|
+
if (!this.tiles) return;
|
|
3587
|
+
const hiddenSet = new Set(this.oids);
|
|
3588
|
+
this.tiles.traverse((tile) => {
|
|
3589
|
+
const tileWithCache = tile;
|
|
3590
|
+
if (tileWithCache.engineData?.scene) applyVisibilityToScene(tileWithCache.engineData.scene, hiddenSet);
|
|
3591
|
+
return true;
|
|
3592
|
+
}, null);
|
|
2512
3593
|
}
|
|
2513
3594
|
/**
|
|
2514
|
-
*
|
|
3595
|
+
* 设置材质(DoubleSide 等基础配置)
|
|
2515
3596
|
*/
|
|
2516
3597
|
_setupMaterial(mesh) {
|
|
2517
3598
|
const material = mesh.material;
|
|
2518
3599
|
if (material.userData._meshHelperSetup) return;
|
|
2519
3600
|
material.userData._meshHelperSetup = true;
|
|
2520
3601
|
material.side = DoubleSide;
|
|
2521
|
-
const previousOnBeforeCompile = material.onBeforeCompile;
|
|
2522
|
-
if (!material.defines) material.defines = {};
|
|
2523
|
-
material.userData._materialFeatureIdCount = this.featureIdCount;
|
|
2524
|
-
Object.defineProperty(material.defines, "FEATURE_ID_COUNT", {
|
|
2525
|
-
get: () => {
|
|
2526
|
-
if (material.userData._materialFeatureIdCount !== this.featureIdCount) {
|
|
2527
|
-
material.userData._materialFeatureIdCount = this.featureIdCount;
|
|
2528
|
-
material.needsUpdate = true;
|
|
2529
|
-
}
|
|
2530
|
-
return material.userData._materialFeatureIdCount;
|
|
2531
|
-
},
|
|
2532
|
-
enumerable: true,
|
|
2533
|
-
configurable: true
|
|
2534
|
-
});
|
|
2535
|
-
material.onBeforeCompile = (shader, renderer) => {
|
|
2536
|
-
previousOnBeforeCompile?.call(material, shader, renderer);
|
|
2537
|
-
if (shader.vertexShader.includes("varying float vFeatureId;")) return;
|
|
2538
|
-
shader.uniforms.hiddenFeatureIds = new FeatureIdUniforms(mesh, this);
|
|
2539
|
-
shader.vertexShader = shader.vertexShader.replace("#include <common>", `#include <common>
|
|
2540
|
-
attribute float _feature_id_0;
|
|
2541
|
-
varying float vFeatureId;`);
|
|
2542
|
-
shader.vertexShader = shader.vertexShader.replace("#include <begin_vertex>", `#include <begin_vertex>
|
|
2543
|
-
vFeatureId = _feature_id_0;`);
|
|
2544
|
-
shader.fragmentShader = shader.fragmentShader.replace("#include <common>", `#include <common>
|
|
2545
|
-
uniform float hiddenFeatureIds[FEATURE_ID_COUNT];
|
|
2546
|
-
varying float vFeatureId;
|
|
2547
|
-
|
|
2548
|
-
bool shouldHideFeature(float featureId) {
|
|
2549
|
-
for(int i = 0; i < FEATURE_ID_COUNT; i++) {
|
|
2550
|
-
if(abs(hiddenFeatureIds[i] - featureId) < 0.001) {
|
|
2551
|
-
return true;
|
|
2552
|
-
}
|
|
2553
|
-
}
|
|
2554
|
-
return false;
|
|
2555
|
-
}`);
|
|
2556
|
-
shader.fragmentShader = shader.fragmentShader.replace("void main() {", `void main() {
|
|
2557
|
-
if(shouldHideFeature(vFeatureId)) {
|
|
2558
|
-
discard;
|
|
2559
|
-
}`);
|
|
2560
|
-
};
|
|
2561
3602
|
}
|
|
2562
3603
|
/**
|
|
2563
3604
|
* Query feature information from intersection
|
|
@@ -2610,44 +3651,112 @@ var GLTFParserPlugin = class {
|
|
|
2610
3651
|
return this._interactionFilter.getIsolatedOids();
|
|
2611
3652
|
}
|
|
2612
3653
|
/**
|
|
2613
|
-
*
|
|
3654
|
+
* 合并 OID 列表对应的结构 bbox;若无可用 bbox 则使用 split mesh 世界包围盒并求中心。
|
|
2614
3655
|
*/
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
const
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
if (!
|
|
2622
|
-
|
|
2623
|
-
|
|
3656
|
+
_getCenterFromOidList(oids) {
|
|
3657
|
+
this._syncStructureFromTileset();
|
|
3658
|
+
const union = new Box3();
|
|
3659
|
+
let hasStructureBox = false;
|
|
3660
|
+
for (const oid of oids) {
|
|
3661
|
+
const b = this.getBoundingBoxByOid(oid);
|
|
3662
|
+
if (b && !b.isEmpty()) if (!hasStructureBox) {
|
|
3663
|
+
union.copy(b);
|
|
3664
|
+
hasStructureBox = true;
|
|
3665
|
+
} else union.union(b);
|
|
3666
|
+
}
|
|
3667
|
+
if (hasStructureBox && !union.isEmpty()) return union.getCenter(new Vector3());
|
|
3668
|
+
const meshes = this._getMeshesByOidsInternal(oids);
|
|
3669
|
+
if (meshes.length === 0) return null;
|
|
3670
|
+
const meshBox = new Box3();
|
|
3671
|
+
for (const mesh of meshes) {
|
|
3672
|
+
mesh.updateMatrixWorld(true);
|
|
3673
|
+
meshBox.expandByObject(mesh);
|
|
3674
|
+
}
|
|
3675
|
+
if (meshBox.isEmpty()) return null;
|
|
3676
|
+
return meshBox.getCenter(new Vector3());
|
|
3677
|
+
}
|
|
3678
|
+
/**
|
|
3679
|
+
* 按 OID 集合:每个瓦片 mesh 只生成 **一个** 合并后的 split mesh(同一组 oid / condition 一条几何)
|
|
3680
|
+
*/
|
|
3681
|
+
_getMergedSplitMeshesForOidSet(oidSet) {
|
|
3682
|
+
if (!this.tiles || oidSet.size === 0) return [];
|
|
3683
|
+
const sortedKey = [...oidSet].sort((a, b) => a - b).join(",");
|
|
3684
|
+
const result = [];
|
|
3685
|
+
const candidateTiles = /* @__PURE__ */ new Set();
|
|
3686
|
+
for (const oid of oidSet) for (const tm of getTileMeshesByOid(this.tiles, oid)) candidateTiles.add(tm);
|
|
3687
|
+
for (const tileMesh of candidateTiles) {
|
|
3688
|
+
const cacheKey = `merged|${tileMesh.uuid}|${sortedKey}`;
|
|
3689
|
+
let cached = this.splitMeshCache.get(cacheKey);
|
|
3690
|
+
if (!cached) {
|
|
3691
|
+
const m = splitMeshByOidsMerged(tileMesh, oidSet);
|
|
3692
|
+
cached = m ? [m] : [];
|
|
3693
|
+
this.splitMeshCache.set(cacheKey, cached);
|
|
2624
3694
|
}
|
|
2625
|
-
|
|
3695
|
+
result.push(...cached);
|
|
2626
3696
|
}
|
|
2627
|
-
return
|
|
3697
|
+
return result;
|
|
2628
3698
|
}
|
|
2629
3699
|
/**
|
|
2630
|
-
*
|
|
2631
|
-
* MeshCollector 会监听瓦片变化,自动更新 meshes 并触发 mesh-change 事件
|
|
2632
|
-
* 内部缓存:相同 oid 多次调用会返回同一个 collector 实例
|
|
3700
|
+
* 内部方法:根据单个 oid 获取 split mesh(每瓦片合并为一条)
|
|
2633
3701
|
*/
|
|
2634
|
-
|
|
2635
|
-
|
|
3702
|
+
_getMeshesByOidInternal(oid) {
|
|
3703
|
+
return this._getMergedSplitMeshesForOidSet(new Set([oid]));
|
|
3704
|
+
}
|
|
3705
|
+
/**
|
|
3706
|
+
* 内部方法:根据多个 oid 获取合并 split mesh(每瓦片一条,而非每 oid 一条)
|
|
3707
|
+
*/
|
|
3708
|
+
_getMeshesByOidsInternal(oids) {
|
|
3709
|
+
return this._getMergedSplitMeshesForOidSet(new Set(oids));
|
|
3710
|
+
}
|
|
3711
|
+
/**
|
|
3712
|
+
* 按查询收集 mesh:可只传 oids、只传 condition(全场景 OID 上筛选)、或两者组合
|
|
3713
|
+
* condition 与 setStyle 的 show / conditions 中字符串表达式语义一致
|
|
3714
|
+
*/
|
|
3715
|
+
_getMeshesForCollectorQueryInternal(params) {
|
|
3716
|
+
if (!this.tiles) return [];
|
|
3717
|
+
const cond = params.condition?.trim();
|
|
3718
|
+
let targetOids;
|
|
3719
|
+
if (!cond) {
|
|
3720
|
+
if (params.oids.length === 0) return [];
|
|
3721
|
+
targetOids = [...new Set(params.oids)].sort((a, b) => a - b);
|
|
3722
|
+
} else {
|
|
3723
|
+
const candidate = params.oids.length === 0 ? getAllOidsFromTiles(this.tiles) : [...new Set(params.oids)];
|
|
3724
|
+
targetOids = [];
|
|
3725
|
+
for (const oid of candidate) if (evaluateStyleCondition(cond, getPropertyDataByOid(this.tiles, oid))) targetOids.push(oid);
|
|
3726
|
+
targetOids.sort((a, b) => a - b);
|
|
3727
|
+
}
|
|
3728
|
+
return this._getMeshesByOidsInternal(targetOids);
|
|
3729
|
+
}
|
|
3730
|
+
/**
|
|
3731
|
+
* 根据查询获取 MeshCollector(oids + 可选 condition,缓存键相同则复用实例)
|
|
3732
|
+
*/
|
|
3733
|
+
getMeshCollectorByCondition(query) {
|
|
3734
|
+
const hasOids = normalizeMeshCollectorOids(query.oids ?? []).length > 0;
|
|
3735
|
+
const hasCond = Boolean(query.condition?.trim());
|
|
3736
|
+
if (!hasOids && !hasCond) throw new Error("getMeshCollectorByCondition requires non-empty oids and/or a condition string");
|
|
3737
|
+
const key = meshCollectorQueryCacheKey(query);
|
|
3738
|
+
const existing = this.collectorCache.get(key);
|
|
2636
3739
|
if (existing) return existing;
|
|
2637
|
-
const collector = new MeshCollector(
|
|
2638
|
-
this.collectorCache.set(
|
|
2639
|
-
this._interactionFilter.onCollectorMeshChange(
|
|
3740
|
+
const collector = new MeshCollector(query, this);
|
|
3741
|
+
this.collectorCache.set(key, collector);
|
|
3742
|
+
this._interactionFilter.onCollectorMeshChange(key, collector.meshes);
|
|
2640
3743
|
collector.addEventListener("mesh-change", (event) => {
|
|
2641
|
-
this._interactionFilter.onCollectorMeshChange(
|
|
3744
|
+
this._interactionFilter.onCollectorMeshChange(key, event.meshes);
|
|
2642
3745
|
});
|
|
2643
3746
|
return collector;
|
|
2644
3747
|
}
|
|
2645
3748
|
/**
|
|
3749
|
+
* 根据单个 oid 获取 MeshCollector(等价于 getMeshCollectorByCondition({ oids: [oid] }))
|
|
3750
|
+
*/
|
|
3751
|
+
getMeshCollectorByOid(oid) {
|
|
3752
|
+
return this.getMeshCollectorByCondition({ oids: [oid] });
|
|
3753
|
+
}
|
|
3754
|
+
/**
|
|
2646
3755
|
* Hide the corresponding part of the original mesh according to the OID array
|
|
2647
3756
|
*/
|
|
2648
3757
|
hidePartsByOids(oids) {
|
|
2649
3758
|
this.oids = oids;
|
|
2650
|
-
this.
|
|
3759
|
+
this._applyVisibilityToAllTiles();
|
|
2651
3760
|
}
|
|
2652
3761
|
/**
|
|
2653
3762
|
* Restore the display of the corresponding mesh according to the OID array
|
|
@@ -2655,7 +3764,7 @@ var GLTFParserPlugin = class {
|
|
|
2655
3764
|
showPartsByOids(oids) {
|
|
2656
3765
|
const oidSet = new Set(oids);
|
|
2657
3766
|
this.oids = this.oids.filter((existingOid) => !oidSet.has(existingOid));
|
|
2658
|
-
this.
|
|
3767
|
+
this._applyVisibilityToAllTiles();
|
|
2659
3768
|
}
|
|
2660
3769
|
/**
|
|
2661
3770
|
* 根据 oid 数组设置构件颜色
|
|
@@ -2746,17 +3855,56 @@ var GLTFParserPlugin = class {
|
|
|
2746
3855
|
this._partFrameHelper?.setFrameEdgeColor(oids, color);
|
|
2747
3856
|
}
|
|
2748
3857
|
/**
|
|
3858
|
+
* 设置构件样式(条件可见性 + 条件材质)
|
|
3859
|
+
* @param style 样式配置,传 null 清除样式
|
|
3860
|
+
*/
|
|
3861
|
+
setStyle(style) {
|
|
3862
|
+
this._styleHelper?.setStyle(style);
|
|
3863
|
+
}
|
|
3864
|
+
/**
|
|
3865
|
+
* 当前样式配置,只读
|
|
3866
|
+
*/
|
|
3867
|
+
get style() {
|
|
3868
|
+
return this._styleHelper?.style ?? null;
|
|
3869
|
+
}
|
|
3870
|
+
/**
|
|
3871
|
+
* 清除构件样式
|
|
3872
|
+
*/
|
|
3873
|
+
clearStyle() {
|
|
3874
|
+
this._styleHelper?.clearStyle();
|
|
3875
|
+
}
|
|
3876
|
+
/**
|
|
3877
|
+
* 高亮指定构件(语义与 setStyle 一致:show、conditions、可选 oids,另需 name 标识分组)
|
|
3878
|
+
* @param options 高亮配置
|
|
3879
|
+
*/
|
|
3880
|
+
highlight(options) {
|
|
3881
|
+
this._partHighlightHelper?.highlight(options);
|
|
3882
|
+
}
|
|
3883
|
+
/**
|
|
3884
|
+
* 取消指定名称的高亮
|
|
3885
|
+
* @param name 高亮组名称
|
|
3886
|
+
*/
|
|
3887
|
+
cancelHighlight(name) {
|
|
3888
|
+
this._partHighlightHelper?.cancelHighlight(name);
|
|
3889
|
+
}
|
|
3890
|
+
/**
|
|
3891
|
+
* 取消所有高亮
|
|
3892
|
+
*/
|
|
3893
|
+
cancelAllHighlight() {
|
|
3894
|
+
this._partHighlightHelper?.cancelAllHighlight();
|
|
3895
|
+
}
|
|
3896
|
+
/**
|
|
2749
3897
|
* Restore the original materials of the mesh
|
|
2750
3898
|
*/
|
|
2751
3899
|
showAllParts() {
|
|
2752
3900
|
this.oids = [];
|
|
2753
|
-
this.
|
|
3901
|
+
this._applyVisibilityToAllTiles();
|
|
2754
3902
|
}
|
|
2755
3903
|
/**
|
|
2756
|
-
*
|
|
3904
|
+
* 获取当前隐藏的 OID 数量(兼容旧 API)
|
|
2757
3905
|
*/
|
|
2758
3906
|
getFeatureIdCount() {
|
|
2759
|
-
return this.
|
|
3907
|
+
return this.oids.length;
|
|
2760
3908
|
}
|
|
2761
3909
|
/**
|
|
2762
3910
|
* Plugin disposal
|
|
@@ -2766,6 +3914,7 @@ var GLTFParserPlugin = class {
|
|
|
2766
3914
|
this.tiles.manager.removeHandler(this._gltfRegex);
|
|
2767
3915
|
this.tiles.removeEventListener("load-model", this._onLoadModelCB);
|
|
2768
3916
|
this.tiles.removeEventListener("tiles-load-end", this._onTilesLoadEndCB);
|
|
3917
|
+
this.tiles.removeEventListener("load-root-tileset", this._onLoadRootTilesetCB);
|
|
2769
3918
|
}
|
|
2770
3919
|
if (this._loader) this._loader.removeListeners();
|
|
2771
3920
|
for (const collector of this.collectors) collector.dispose();
|
|
@@ -2774,7 +3923,7 @@ var GLTFParserPlugin = class {
|
|
|
2774
3923
|
this.splitMeshCache.clear();
|
|
2775
3924
|
this._structureData = null;
|
|
2776
3925
|
this._oidNodeMap.clear();
|
|
2777
|
-
this.
|
|
3926
|
+
this._structureEmbedResolved = false;
|
|
2778
3927
|
this._modelInfo = null;
|
|
2779
3928
|
this._modelInfoPromise = null;
|
|
2780
3929
|
this._interactionFilter.dispose();
|
|
@@ -2783,11 +3932,15 @@ var GLTFParserPlugin = class {
|
|
|
2783
3932
|
this._partBlinkHelper = null;
|
|
2784
3933
|
this._partFrameHelper?.dispose();
|
|
2785
3934
|
this._partFrameHelper = null;
|
|
3935
|
+
this._styleHelper?.dispose();
|
|
3936
|
+
this._styleHelper = null;
|
|
3937
|
+
this._partHighlightHelper?.dispose();
|
|
3938
|
+
this._partHighlightHelper = null;
|
|
2786
3939
|
this._loader = null;
|
|
2787
3940
|
this.tiles = null;
|
|
2788
3941
|
}
|
|
2789
3942
|
};
|
|
2790
3943
|
//#endregion
|
|
2791
|
-
export { GLTFParserPlugin, MeshCollector };
|
|
3944
|
+
export { GLTFParserPlugin, MeshCollector, clearStyleConditionCache, decodeGzipBase64DataUriSync, evaluateStyleCondition, getStructureDataUriFromTileset, meshCollectorGroupKey, meshCollectorQueryCacheKey, normalizeMeshCollectorOids, parseEmbeddedStructureDataFromTilesSync };
|
|
2792
3945
|
|
|
2793
3946
|
//# sourceMappingURL=gltf-parser-plugin.module.js.map
|