@inweb/viewer-three 26.7.2 → 26.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/viewer-three.js +386 -246
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +4 -2
- package/dist/viewer-three.module.js +340 -161
- package/dist/viewer-three.module.js.map +1 -1
- package/lib/Viewer/components/HighlighterComponent.d.ts +2 -2
- package/lib/Viewer/loaders/GLTFCloudDynamicLoader.d.ts +0 -2
- package/lib/Viewer/loaders/index.d.ts +1 -1
- package/package.json +5 -5
- package/src/Viewer/Viewer.ts +6 -1
- package/src/Viewer/commands/SetSelected.ts +1 -0
- package/src/Viewer/commands/index.ts +1 -1
- package/src/Viewer/components/CameraComponent.ts +0 -1
- package/src/Viewer/components/HighlighterComponent.ts +38 -16
- package/src/Viewer/components/LightComponent.ts +11 -15
- package/src/Viewer/components/SelectionComponent.ts +1 -2
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +187 -65
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicModelImpl.ts +7 -12
- package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +120 -114
- package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +7 -13
- package/src/Viewer/loaders/index.ts +1 -1
|
@@ -86,7 +86,9 @@ export class DynamicGltfLoader {
|
|
|
86
86
|
this.mergedPoints = new Set();
|
|
87
87
|
|
|
88
88
|
this.isolatedObjects = [];
|
|
89
|
-
|
|
89
|
+
//!!window.WebGL2RenderingContext && this.renderer.getContext() instanceof WebGL2RenderingContext
|
|
90
|
+
this.useVAO = false;
|
|
91
|
+
this.visibleEdges = true;
|
|
90
92
|
|
|
91
93
|
this.handleToOptimizedObjects = new Map();
|
|
92
94
|
|
|
@@ -95,6 +97,10 @@ export class DynamicGltfLoader {
|
|
|
95
97
|
this.oldOptimizeObjects = new Set();
|
|
96
98
|
}
|
|
97
99
|
|
|
100
|
+
setVisibleEdges(visible) {
|
|
101
|
+
this.visibleEdges = visible;
|
|
102
|
+
}
|
|
103
|
+
|
|
98
104
|
getAvailableMemory() {
|
|
99
105
|
let memoryLimit = 6 * 1024 * 1024 * 1024;
|
|
100
106
|
try {
|
|
@@ -115,7 +121,7 @@ export class DynamicGltfLoader {
|
|
|
115
121
|
console.warn("Error detecting available memory:", error);
|
|
116
122
|
}
|
|
117
123
|
|
|
118
|
-
return memoryLimit;
|
|
124
|
+
return memoryLimit / 3;
|
|
119
125
|
}
|
|
120
126
|
|
|
121
127
|
getAbortController() {
|
|
@@ -220,7 +226,7 @@ export class DynamicGltfLoader {
|
|
|
220
226
|
console.log(`Final memory usage: ${Math.round(currentMemoryUsage / (1024 * 1024))}MB`);
|
|
221
227
|
}
|
|
222
228
|
|
|
223
|
-
async loadNode(nodeId) {
|
|
229
|
+
async loadNode(nodeId, onLoadFinishCb) {
|
|
224
230
|
const node = this.nodes.get(nodeId);
|
|
225
231
|
if (!node || node.loaded || node.loading) return;
|
|
226
232
|
|
|
@@ -228,38 +234,138 @@ export class DynamicGltfLoader {
|
|
|
228
234
|
const meshDef = node.structure.getJson().meshes[node.meshIndex];
|
|
229
235
|
|
|
230
236
|
try {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
+
const bufferRequests = [];
|
|
238
|
+
const primitiveReqMap = new Map();
|
|
239
|
+
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
240
|
+
const primitive = meshDef.primitives[primIdx];
|
|
241
|
+
const reqs = [];
|
|
242
|
+
|
|
243
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
244
|
+
const accessorIndex = primitive.attributes.POSITION;
|
|
245
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
246
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
247
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
248
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
249
|
+
const count = accessor.count;
|
|
250
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
251
|
+
reqs.push({
|
|
252
|
+
offset: byteOffset,
|
|
253
|
+
length: byteLength,
|
|
254
|
+
componentType: accessor.componentType,
|
|
255
|
+
accessorIndex,
|
|
256
|
+
type: "position",
|
|
257
|
+
primIdx,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
237
260
|
|
|
238
261
|
if (primitive.attributes.NORMAL !== undefined) {
|
|
239
|
-
|
|
262
|
+
const accessorIndex = primitive.attributes.NORMAL;
|
|
263
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
264
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
265
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
266
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
267
|
+
const count = accessor.count;
|
|
268
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
269
|
+
reqs.push({
|
|
270
|
+
offset: byteOffset,
|
|
271
|
+
length: byteLength,
|
|
272
|
+
componentType: accessor.componentType,
|
|
273
|
+
accessorIndex,
|
|
274
|
+
type: "normal",
|
|
275
|
+
primIdx,
|
|
276
|
+
});
|
|
240
277
|
}
|
|
241
278
|
|
|
242
279
|
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
243
|
-
|
|
280
|
+
const accessorIndex = primitive.attributes.TEXCOORD_0;
|
|
281
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
282
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
283
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
284
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
285
|
+
const count = accessor.count;
|
|
286
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
287
|
+
reqs.push({
|
|
288
|
+
offset: byteOffset,
|
|
289
|
+
length: byteLength,
|
|
290
|
+
componentType: accessor.componentType,
|
|
291
|
+
accessorIndex,
|
|
292
|
+
type: "uv",
|
|
293
|
+
primIdx,
|
|
294
|
+
});
|
|
244
295
|
}
|
|
245
296
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
297
|
+
if (primitive.indices !== undefined) {
|
|
298
|
+
const accessorIndex = primitive.indices;
|
|
299
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
300
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
301
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
302
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
303
|
+
const count = accessor.count;
|
|
304
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
305
|
+
reqs.push({
|
|
306
|
+
offset: byteOffset,
|
|
307
|
+
length: byteLength,
|
|
308
|
+
componentType: accessor.componentType,
|
|
309
|
+
accessorIndex,
|
|
310
|
+
type: "index",
|
|
311
|
+
primIdx,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
primitiveReqMap.set(primIdx, reqs);
|
|
315
|
+
bufferRequests.push(...reqs);
|
|
316
|
+
}
|
|
252
317
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
318
|
+
if (bufferRequests.length === 0) {
|
|
319
|
+
node.loaded = true;
|
|
320
|
+
node.loading = false;
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
bufferRequests.sort((a, b) => a.offset - b.offset);
|
|
324
|
+
const minOffset = bufferRequests[0].offset;
|
|
325
|
+
const maxOffset = Math.max(...bufferRequests.map((r) => r.offset + r.length));
|
|
326
|
+
const totalLength = maxOffset - minOffset;
|
|
327
|
+
|
|
328
|
+
const { buffer, relOffset: baseRelOffset } = await node.structure.scheduleRequest({
|
|
329
|
+
offset: minOffset,
|
|
330
|
+
length: totalLength,
|
|
331
|
+
componentType: null,
|
|
332
|
+
});
|
|
256
333
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
334
|
+
for (const req of bufferRequests) {
|
|
335
|
+
const relOffset = req.offset - minOffset;
|
|
336
|
+
req.data = node.structure.createTypedArray(buffer, baseRelOffset + relOffset, req.length, req.componentType);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
340
|
+
const primitive = meshDef.primitives[primIdx];
|
|
341
|
+
const geometry = new BufferGeometry();
|
|
342
|
+
const reqs = primitiveReqMap.get(primIdx);
|
|
343
|
+
|
|
344
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
345
|
+
const req = reqs.find((r) => r.type === "position" && r.accessorIndex === primitive.attributes.POSITION);
|
|
346
|
+
const accessor = node.structure.json.accessors[primitive.attributes.POSITION];
|
|
347
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
348
|
+
geometry.setAttribute("position", new BufferAttribute(req.data, components));
|
|
260
349
|
}
|
|
261
350
|
|
|
262
|
-
|
|
351
|
+
if (primitive.attributes.NORMAL !== undefined) {
|
|
352
|
+
const req = reqs.find((r) => r.type === "normal" && r.accessorIndex === primitive.attributes.NORMAL);
|
|
353
|
+
const accessor = node.structure.json.accessors[primitive.attributes.NORMAL];
|
|
354
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
355
|
+
geometry.setAttribute("normal", new BufferAttribute(req.data, components));
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
359
|
+
const req = reqs.find((r) => r.type === "uv" && r.accessorIndex === primitive.attributes.TEXCOORD_0);
|
|
360
|
+
const accessor = node.structure.json.accessors[primitive.attributes.TEXCOORD_0];
|
|
361
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
362
|
+
geometry.setAttribute("uv", new BufferAttribute(req.data, components));
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (primitive.indices !== undefined) {
|
|
366
|
+
const req = reqs.find((r) => r.type === "index" && r.accessorIndex === primitive.indices);
|
|
367
|
+
geometry.setIndex(new BufferAttribute(req.data, 1));
|
|
368
|
+
}
|
|
263
369
|
|
|
264
370
|
let material;
|
|
265
371
|
if (primitive.material !== undefined) {
|
|
@@ -274,8 +380,7 @@ export class DynamicGltfLoader {
|
|
|
274
380
|
Material.prototype.copy.call(pointsMaterial, material);
|
|
275
381
|
pointsMaterial.color.copy(material.color);
|
|
276
382
|
pointsMaterial.map = material.map;
|
|
277
|
-
pointsMaterial.sizeAttenuation = false;
|
|
278
|
-
|
|
383
|
+
pointsMaterial.sizeAttenuation = false;
|
|
279
384
|
mesh = new Points(geometry, pointsMaterial);
|
|
280
385
|
} else if (
|
|
281
386
|
primitive.mode === GL_CONSTANTS.TRIANGLES ||
|
|
@@ -284,7 +389,6 @@ export class DynamicGltfLoader {
|
|
|
284
389
|
primitive.mode === undefined
|
|
285
390
|
) {
|
|
286
391
|
mesh = new Mesh(geometry, material);
|
|
287
|
-
|
|
288
392
|
if (primitive.mode === GL_CONSTANTS.TRIANGLE_STRIP) {
|
|
289
393
|
mesh.drawMode = TriangleStripDrawMode;
|
|
290
394
|
} else if (primitive.mode === GL_CONSTANTS.TRIANGLE_FAN) {
|
|
@@ -297,39 +401,30 @@ export class DynamicGltfLoader {
|
|
|
297
401
|
} else if (primitive.mode === GL_CONSTANTS.LINE_LOOP) {
|
|
298
402
|
mesh = new LineLoop(geometry, material);
|
|
299
403
|
}
|
|
300
|
-
|
|
301
404
|
if (node.extras) {
|
|
302
405
|
mesh.userData = { ...mesh.userData, ...node.extras };
|
|
303
406
|
}
|
|
304
|
-
|
|
305
407
|
if (meshDef.extras) {
|
|
306
408
|
mesh.userData = { ...mesh.userData, ...meshDef.extras };
|
|
307
409
|
}
|
|
308
|
-
|
|
309
410
|
if (primitive.extras) {
|
|
310
411
|
mesh.userData = { ...mesh.userData, ...primitive.extras };
|
|
311
412
|
}
|
|
312
|
-
|
|
313
413
|
if (node.handle) {
|
|
314
414
|
mesh.userData.handle = node.handle;
|
|
315
415
|
} else {
|
|
316
416
|
mesh.userData.handle = `${node.structure.id}_${mesh.userData.handle}`;
|
|
317
417
|
}
|
|
318
|
-
|
|
319
418
|
if (mesh.material.name === "edges") {
|
|
320
419
|
mesh.userData.isEdge = true;
|
|
321
420
|
} else {
|
|
322
421
|
mesh.userData.isEdge = false;
|
|
323
422
|
}
|
|
324
|
-
|
|
325
423
|
this.registerObjectWithHandle(mesh, mesh.userData.handle);
|
|
326
|
-
|
|
327
424
|
mesh.position.copy(node.position);
|
|
328
|
-
|
|
329
425
|
if (!geometry.attributes.normal) {
|
|
330
426
|
geometry.computeVertexNormals();
|
|
331
427
|
}
|
|
332
|
-
|
|
333
428
|
if (material.aoMap && geometry.attributes.uv) {
|
|
334
429
|
geometry.setAttribute("uv2", geometry.attributes.uv);
|
|
335
430
|
}
|
|
@@ -339,17 +434,17 @@ export class DynamicGltfLoader {
|
|
|
339
434
|
this.scene.add(mesh);
|
|
340
435
|
}
|
|
341
436
|
node.object = mesh;
|
|
342
|
-
|
|
343
437
|
this.totalLoadedObjects++;
|
|
344
438
|
mesh.visible = this.totalLoadedObjects < this.graphicsObjectLimit;
|
|
345
439
|
}
|
|
346
|
-
|
|
347
440
|
node.loaded = true;
|
|
348
441
|
node.loading = false;
|
|
349
|
-
|
|
350
442
|
const geometrySize = this.estimateGeometrySize(node.object);
|
|
351
443
|
this.geometryCache.set(node.object.uuid, geometrySize);
|
|
352
444
|
this.currentMemoryUsage += geometrySize;
|
|
445
|
+
if (onLoadFinishCb) {
|
|
446
|
+
onLoadFinishCb();
|
|
447
|
+
}
|
|
353
448
|
} catch (error) {
|
|
354
449
|
if (error.name !== "AbortError") {
|
|
355
450
|
console.error(`Error loading node ${nodeId}:`, error);
|
|
@@ -474,7 +569,7 @@ export class DynamicGltfLoader {
|
|
|
474
569
|
return volumeB - volumeA;
|
|
475
570
|
});
|
|
476
571
|
|
|
477
|
-
if (!ignoreEdges) {
|
|
572
|
+
if (!ignoreEdges && this.visibleEdges) {
|
|
478
573
|
this.nodesToLoad.push(...this.edgeNodes);
|
|
479
574
|
}
|
|
480
575
|
|
|
@@ -601,33 +696,13 @@ export class DynamicGltfLoader {
|
|
|
601
696
|
async processNodes() {
|
|
602
697
|
const nodesToLoad = this.nodesToLoad;
|
|
603
698
|
let loadedCount = 0;
|
|
699
|
+
let lastLoadedCount = 0;
|
|
604
700
|
const totalNodes = nodesToLoad.length;
|
|
605
701
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
for (const nodeId of batch) {
|
|
612
|
-
if (this.abortController.signal.aborted) {
|
|
613
|
-
throw new DOMException("Loading aborted", "AbortError");
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
const estimatedSize = await this.estimateNodeSize(nodeId);
|
|
617
|
-
|
|
618
|
-
if (this.currentMemoryUsage + estimatedSize > this.memoryLimit) {
|
|
619
|
-
console.log(`Memory limit reached after loading ${loadedCount} nodes`);
|
|
620
|
-
this.dispatchEvent("geometryerror", { message: "Memory limit reached" });
|
|
621
|
-
this.dispatchEvent("update");
|
|
622
|
-
return loadedCount;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
batchPromises.push(this.loadNode(nodeId));
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
await Promise.all(batchPromises);
|
|
629
|
-
loadedCount += batch.length;
|
|
630
|
-
|
|
702
|
+
const loadProgress = async () => {
|
|
703
|
+
loadedCount++;
|
|
704
|
+
if (loadedCount - lastLoadedCount > 1000) {
|
|
705
|
+
lastLoadedCount = loadedCount;
|
|
631
706
|
this.updateMemoryIndicator();
|
|
632
707
|
this.dispatchEvent("geometryprogress", {
|
|
633
708
|
percentage: Math.round((loadedCount / totalNodes) * 100),
|
|
@@ -645,6 +720,34 @@ export class DynamicGltfLoader {
|
|
|
645
720
|
setTimeout(resolve, 0);
|
|
646
721
|
});
|
|
647
722
|
}
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
try {
|
|
726
|
+
const loadOperations = [];
|
|
727
|
+
for (const nodeId of nodesToLoad) {
|
|
728
|
+
if (this.abortController.signal.aborted) {
|
|
729
|
+
throw new DOMException("Loading aborted", "AbortError");
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
const estimatedSize = await this.estimateNodeSize(nodeId);
|
|
733
|
+
|
|
734
|
+
if (this.currentMemoryUsage + estimatedSize > this.memoryLimit) {
|
|
735
|
+
console.log(`Memory limit reached after loading ${loadedCount} nodes`);
|
|
736
|
+
this.dispatchEvent("geometryerror", {
|
|
737
|
+
message: "Memory limit reached",
|
|
738
|
+
});
|
|
739
|
+
this.dispatchEvent("update");
|
|
740
|
+
return loadedCount;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
loadOperations.push(this.loadNode(nodeId, loadProgress));
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
for (const structure of this.structures) {
|
|
747
|
+
loadOperations.push(structure.flushBufferRequests());
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
await Promise.all(loadOperations);
|
|
648
751
|
|
|
649
752
|
this.dispatchEvent("geometryend", {
|
|
650
753
|
totalLoaded: loadedCount,
|
|
@@ -1625,4 +1728,23 @@ export class DynamicGltfLoader {
|
|
|
1625
1728
|
}
|
|
1626
1729
|
});
|
|
1627
1730
|
}
|
|
1731
|
+
|
|
1732
|
+
// Возвращает bounding box для конкретной структуры
|
|
1733
|
+
getStructureGeometryExtent(structureId) {
|
|
1734
|
+
const extent = new Box3();
|
|
1735
|
+
for (const [nodeId, node] of this.nodes.entries()) {
|
|
1736
|
+
if (!node.geometryExtents) continue;
|
|
1737
|
+
if (!nodeId.startsWith(structureId + "_")) continue;
|
|
1738
|
+
if (node.object && this.hiddenHandles && this.hiddenHandles.has(node.object.userData.handle)) continue;
|
|
1739
|
+
const transformedBox = node.geometryExtents.clone();
|
|
1740
|
+
if (node.group && node.group.matrix) {
|
|
1741
|
+
transformedBox.applyMatrix4(node.group.matrix);
|
|
1742
|
+
if (node.group.parent && node.group.parent.matrix) {
|
|
1743
|
+
transformedBox.applyMatrix4(node.group.parent.matrix);
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
extent.union(transformedBox);
|
|
1747
|
+
}
|
|
1748
|
+
return extent;
|
|
1749
|
+
}
|
|
1628
1750
|
}
|
|
@@ -62,10 +62,8 @@ export class DynamicModelImpl extends ModelImpl {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
override hideObjects(objects: Object3D | Object3D[]): this {
|
|
65
|
-
this.
|
|
66
|
-
|
|
67
|
-
.forEach((handle) => this.gltfLoader.hiddenHandles.add(handle));
|
|
68
|
-
this.gltfLoader.syncHiddenObjects();
|
|
65
|
+
const handles = this.getHandlesByObjects(objects);
|
|
66
|
+
this.gltfLoader.hideObjects(handles);
|
|
69
67
|
return this;
|
|
70
68
|
}
|
|
71
69
|
|
|
@@ -76,26 +74,23 @@ export class DynamicModelImpl extends ModelImpl {
|
|
|
76
74
|
}
|
|
77
75
|
|
|
78
76
|
override showObjects(objects: Object3D | Object3D[]): this {
|
|
79
|
-
this.
|
|
80
|
-
|
|
81
|
-
.forEach((handle) => this.gltfLoader.hiddenHandles.delete(handle));
|
|
82
|
-
this.gltfLoader.syncHiddenObjects();
|
|
77
|
+
const handles = this.getHandlesByObjects(objects);
|
|
78
|
+
this.gltfLoader.showObjects(handles);
|
|
83
79
|
return this;
|
|
84
80
|
}
|
|
85
81
|
|
|
86
82
|
override showAllObjects(): this {
|
|
87
|
-
this.gltfLoader.
|
|
88
|
-
this.gltfLoader.syncHiddenObjects();
|
|
83
|
+
this.gltfLoader.showAllHiddenObjects();
|
|
89
84
|
return this;
|
|
90
85
|
}
|
|
91
86
|
|
|
92
87
|
override showOriginalObjects(objects: Object3D | Object3D[]): this {
|
|
93
|
-
this.
|
|
88
|
+
this.gltfLoader.showOriginalObjects(objects);
|
|
94
89
|
return this;
|
|
95
90
|
}
|
|
96
91
|
|
|
97
92
|
override hideOriginalObjects(objects: Object3D | Object3D[]): this {
|
|
98
|
-
this.
|
|
93
|
+
this.gltfLoader.hideOriginalObjects(objects);
|
|
99
94
|
return this;
|
|
100
95
|
}
|
|
101
96
|
}
|