@inweb/viewer-three 26.7.6 → 26.8.1
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/plugins/loaders/IFCXLoader.js +1827 -881
- package/dist/plugins/loaders/IFCXLoader.js.map +1 -1
- package/dist/plugins/loaders/IFCXLoader.min.js +1 -1
- package/dist/plugins/loaders/IFCXLoader.module.js +477 -154
- package/dist/plugins/loaders/IFCXLoader.module.js.map +1 -1
- package/dist/viewer-three.js +372 -230
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +4 -2
- package/dist/viewer-three.module.js +336 -159
- 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/plugins/loaders/IFCX/IFCXLoader.ts +4 -7
- package/plugins/loaders/IFCX/render.js +686 -181
- package/plugins/loaders/IFCXCloudLoader.ts +1 -1
- package/src/Viewer/commands/SetSelected.ts +1 -0
- package/src/Viewer/commands/index.ts +1 -1
- package/src/Viewer/components/HighlighterComponent.ts +38 -16
- package/src/Viewer/components/LightComponent.ts +17 -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
package/dist/viewer-three.js
CHANGED
|
@@ -59894,6 +59894,7 @@ void main() {
|
|
|
59894
59894
|
selection.clearSelection();
|
|
59895
59895
|
viewer.models.forEach((model) => {
|
|
59896
59896
|
const objects = model.getObjectsByHandles(handles);
|
|
59897
|
+
model.showObjects(objects);
|
|
59897
59898
|
selection.select(objects, model);
|
|
59898
59899
|
});
|
|
59899
59900
|
viewer.update();
|
|
@@ -60074,9 +60075,9 @@ void main() {
|
|
|
60074
60075
|
commands.registerCommand("clearMarkup", clearMarkup);
|
|
60075
60076
|
commands.registerCommand("clearSelected", clearSelected);
|
|
60076
60077
|
commands.registerCommand("clearSlices", clearSlices);
|
|
60078
|
+
commands.registerCommand("collect", collect);
|
|
60077
60079
|
commands.registerCommand("createPreview", createPreview);
|
|
60078
60080
|
commands.registerCommand("explode", explode);
|
|
60079
|
-
commands.registerCommand("collect", collect);
|
|
60080
60081
|
commands.registerCommand("getDefaultViewPositions", getDefaultViewPositions);
|
|
60081
60082
|
commands.registerCommand("getModels", getModels);
|
|
60082
60083
|
commands.registerCommand("getSelected", getSelected);
|
|
@@ -60308,31 +60309,35 @@ void main() {
|
|
|
60308
60309
|
return;
|
|
60309
60310
|
const extentsCenter = this.viewer.extents.getCenter(new Vector3());
|
|
60310
60311
|
const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere()).radius;
|
|
60312
|
+
const front = new Vector3()
|
|
60313
|
+
.copy(this.viewer.camera.up)
|
|
60314
|
+
.cross(new Vector3(1, 0, 0))
|
|
60315
|
+
.negate();
|
|
60311
60316
|
this.directionalLight.position
|
|
60312
|
-
.
|
|
60317
|
+
.copy(this.viewer.camera.up)
|
|
60318
|
+
.applyAxisAngle(front, (-Math.PI * 30) / 180)
|
|
60313
60319
|
.multiplyScalar(extentsSize * 2)
|
|
60314
60320
|
.add(extentsCenter);
|
|
60315
60321
|
this.directionalLight.target.position.copy(extentsCenter);
|
|
60316
|
-
this.frontLight.position
|
|
60322
|
+
this.frontLight.position
|
|
60323
|
+
.copy(front)
|
|
60324
|
+
.multiplyScalar(extentsSize * 2)
|
|
60325
|
+
.add(extentsCenter);
|
|
60317
60326
|
this.frontLight.target.position.copy(extentsCenter);
|
|
60318
|
-
this.hemisphereLight.position
|
|
60327
|
+
this.hemisphereLight.position
|
|
60328
|
+
.copy(front)
|
|
60329
|
+
.multiplyScalar(extentsSize * 3)
|
|
60330
|
+
.add(extentsCenter);
|
|
60319
60331
|
this.viewer.scene.add(this.ambientLight);
|
|
60320
60332
|
this.viewer.scene.add(this.directionalLight);
|
|
60321
60333
|
this.viewer.scene.add(this.frontLight);
|
|
60322
60334
|
this.viewer.scene.add(this.hemisphereLight);
|
|
60323
60335
|
};
|
|
60324
60336
|
this.viewer = viewer;
|
|
60325
|
-
this.ambientLight = new AmbientLight(0xffffff, 1);
|
|
60326
|
-
this.
|
|
60327
|
-
this.directionalLight = new DirectionalLight(0xffffff, 1);
|
|
60328
|
-
this.directionalLight.position.set(0.5, 0, 0.866); // ~60º
|
|
60329
|
-
this.viewer.scene.add(this.directionalLight);
|
|
60337
|
+
this.ambientLight = new AmbientLight(0xffffff, 1.0);
|
|
60338
|
+
this.directionalLight = new DirectionalLight(0xffffff, 1.0);
|
|
60330
60339
|
this.frontLight = new DirectionalLight(0xffffff, 1.25);
|
|
60331
|
-
this.frontLight.position.set(0, 1, 0);
|
|
60332
|
-
this.viewer.scene.add(this.frontLight);
|
|
60333
60340
|
this.hemisphereLight = new HemisphereLight(0xffffff, 0x444444, 1.25);
|
|
60334
|
-
this.hemisphereLight.position.set(0, 0, 1);
|
|
60335
|
-
this.viewer.scene.add(this.hemisphereLight);
|
|
60336
60341
|
this.viewer.addEventListener("databasechunk", this.geometryEnd);
|
|
60337
60342
|
this.viewer.addEventListener("clear", this.geometryEnd);
|
|
60338
60343
|
}
|
|
@@ -61430,19 +61435,25 @@ void main() {
|
|
|
61430
61435
|
class HighlighterComponent {
|
|
61431
61436
|
constructor(viewer) {
|
|
61432
61437
|
this.geometryEnd = () => {
|
|
61433
|
-
const { facesColor, facesTransparancy, edgesColor } = this.viewer.options;
|
|
61434
|
-
this.highlightMaterial = new
|
|
61438
|
+
const { facesColor, facesTransparancy, edgesColor, edgesOverlap, facesOverlap } = this.viewer.options;
|
|
61439
|
+
this.highlightMaterial = new MeshPhongMaterial({
|
|
61435
61440
|
color: new Color(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255),
|
|
61436
61441
|
transparent: true,
|
|
61437
61442
|
opacity: (255 - facesTransparancy) / 255,
|
|
61438
|
-
depthTest:
|
|
61439
|
-
depthWrite:
|
|
61443
|
+
depthTest: !facesOverlap,
|
|
61444
|
+
depthWrite: !facesOverlap,
|
|
61445
|
+
specular: 0x222222,
|
|
61446
|
+
shininess: 10,
|
|
61447
|
+
reflectivity: 0.05,
|
|
61448
|
+
polygonOffset: true,
|
|
61449
|
+
polygonOffsetFactor: 1,
|
|
61450
|
+
polygonOffsetUnits: 1,
|
|
61440
61451
|
});
|
|
61441
61452
|
this.outlineMaterial = new LineMaterial({
|
|
61442
61453
|
color: new Color(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255),
|
|
61443
61454
|
linewidth: 1.5,
|
|
61444
|
-
depthTest:
|
|
61445
|
-
depthWrite:
|
|
61455
|
+
depthTest: !edgesOverlap,
|
|
61456
|
+
depthWrite: !edgesOverlap,
|
|
61446
61457
|
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
61447
61458
|
});
|
|
61448
61459
|
this.highlightLineMaterial = new LineBasicMaterial({
|
|
@@ -61455,18 +61466,27 @@ void main() {
|
|
|
61455
61466
|
linewidth: 5,
|
|
61456
61467
|
transparent: true,
|
|
61457
61468
|
opacity: 0.8,
|
|
61458
|
-
depthTest:
|
|
61459
|
-
depthWrite:
|
|
61469
|
+
depthTest: !edgesOverlap,
|
|
61470
|
+
depthWrite: !edgesOverlap,
|
|
61460
61471
|
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
61461
61472
|
});
|
|
61462
61473
|
};
|
|
61463
61474
|
this.optionsChange = () => {
|
|
61464
|
-
const { facesColor, facesTransparancy, edgesColor } = this.viewer.options;
|
|
61475
|
+
const { facesColor, facesTransparancy, edgesColor, edgesVisibility, edgesOverlap, facesOverlap } = this.viewer.options;
|
|
61465
61476
|
this.highlightMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
61466
61477
|
this.highlightMaterial.opacity = (255 - facesTransparancy) / 255;
|
|
61478
|
+
this.highlightMaterial.depthTest = !facesOverlap;
|
|
61479
|
+
this.highlightMaterial.depthWrite = !facesOverlap;
|
|
61467
61480
|
this.outlineMaterial.color.setRGB(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255);
|
|
61481
|
+
this.outlineMaterial.depthTest = !edgesOverlap;
|
|
61482
|
+
this.outlineMaterial.depthWrite = !edgesOverlap;
|
|
61468
61483
|
this.highlightLineMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
61469
61484
|
this.highlightLineGlowMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
61485
|
+
this.viewer.selected.forEach((selected) => {
|
|
61486
|
+
const wireframe = selected.userData.highlightWireframe;
|
|
61487
|
+
if (wireframe)
|
|
61488
|
+
wireframe.visible = edgesVisibility;
|
|
61489
|
+
});
|
|
61470
61490
|
this.viewer.update();
|
|
61471
61491
|
};
|
|
61472
61492
|
this.viewer = viewer;
|
|
@@ -61491,6 +61511,7 @@ void main() {
|
|
|
61491
61511
|
this.viewer.removeEventListener("resize", this.viewerResize);
|
|
61492
61512
|
}
|
|
61493
61513
|
highlight(objects) {
|
|
61514
|
+
const { edgesVisibility } = this.viewer.options;
|
|
61494
61515
|
if (!Array.isArray(objects))
|
|
61495
61516
|
objects = [objects];
|
|
61496
61517
|
if (!objects.length)
|
|
@@ -61508,21 +61529,23 @@ void main() {
|
|
|
61508
61529
|
wireframe.position.copy(object.position);
|
|
61509
61530
|
wireframe.rotation.copy(object.rotation);
|
|
61510
61531
|
wireframe.scale.copy(object.scale);
|
|
61532
|
+
wireframe.visible = edgesVisibility;
|
|
61511
61533
|
object.parent.add(wireframe);
|
|
61512
|
-
object.userData.
|
|
61534
|
+
object.userData.highlightWireframe = wireframe;
|
|
61513
61535
|
object.userData.originalMaterial = object.material;
|
|
61514
61536
|
object.material = this.highlightLineMaterial;
|
|
61515
61537
|
object.isHighlighted = true;
|
|
61516
61538
|
}
|
|
61517
61539
|
else if (object.isMesh) {
|
|
61518
|
-
const edgesGeometry = new EdgesGeometry(object.geometry,
|
|
61540
|
+
const edgesGeometry = new EdgesGeometry(object.geometry, 60);
|
|
61519
61541
|
const lineGeometry = new LineSegmentsGeometry().fromEdgesGeometry(edgesGeometry);
|
|
61520
61542
|
const wireframe = new Wireframe(lineGeometry, this.outlineMaterial);
|
|
61521
61543
|
wireframe.position.copy(object.position);
|
|
61522
61544
|
wireframe.rotation.copy(object.rotation);
|
|
61523
61545
|
wireframe.scale.copy(object.scale);
|
|
61546
|
+
wireframe.visible = edgesVisibility;
|
|
61524
61547
|
object.parent.add(wireframe);
|
|
61525
|
-
object.userData.
|
|
61548
|
+
object.userData.highlightWireframe = wireframe;
|
|
61526
61549
|
object.userData.originalMaterial = object.material;
|
|
61527
61550
|
object.material = this.highlightMaterial;
|
|
61528
61551
|
object.isHighlighted = true;
|
|
@@ -61539,9 +61562,9 @@ void main() {
|
|
|
61539
61562
|
return;
|
|
61540
61563
|
object.isHighlighted = false;
|
|
61541
61564
|
object.material = object.userData.originalMaterial;
|
|
61542
|
-
object.userData.
|
|
61565
|
+
object.userData.highlightWireframe.removeFromParent();
|
|
61543
61566
|
delete object.userData.originalMaterial;
|
|
61544
|
-
delete object.userData.
|
|
61567
|
+
delete object.userData.highlightWireframe;
|
|
61545
61568
|
});
|
|
61546
61569
|
}
|
|
61547
61570
|
viewerResize(event) {
|
|
@@ -61590,7 +61613,8 @@ void main() {
|
|
|
61590
61613
|
this.viewer.models.forEach((model) => {
|
|
61591
61614
|
const objects = model.getVisibleObjects();
|
|
61592
61615
|
const intersects = this.getPointerIntersects(upPosition, objects);
|
|
61593
|
-
|
|
61616
|
+
if (intersects.length > 0)
|
|
61617
|
+
intersections.push({ ...intersects[0], model });
|
|
61594
61618
|
});
|
|
61595
61619
|
intersections = intersections.sort((a, b) => a.distance - b.distance);
|
|
61596
61620
|
if (!event.shiftKey)
|
|
@@ -61657,7 +61681,6 @@ void main() {
|
|
|
61657
61681
|
objects = [objects];
|
|
61658
61682
|
if (!objects.length)
|
|
61659
61683
|
return;
|
|
61660
|
-
model.showObjects(objects);
|
|
61661
61684
|
model.showOriginalObjects(objects);
|
|
61662
61685
|
this.highlighter.highlight(objects);
|
|
61663
61686
|
objects.forEach((object) => this.viewer.selected.push(object));
|
|
@@ -67313,10 +67336,8 @@ void main() {
|
|
|
67313
67336
|
return objects;
|
|
67314
67337
|
}
|
|
67315
67338
|
hideObjects(objects) {
|
|
67316
|
-
this.
|
|
67317
|
-
|
|
67318
|
-
.forEach((handle) => this.gltfLoader.hiddenHandles.add(handle));
|
|
67319
|
-
this.gltfLoader.syncHiddenObjects();
|
|
67339
|
+
const handles = this.getHandlesByObjects(objects);
|
|
67340
|
+
this.gltfLoader.hideObjects(handles);
|
|
67320
67341
|
return this;
|
|
67321
67342
|
}
|
|
67322
67343
|
isolateObjects(objects) {
|
|
@@ -67325,23 +67346,20 @@ void main() {
|
|
|
67325
67346
|
return this;
|
|
67326
67347
|
}
|
|
67327
67348
|
showObjects(objects) {
|
|
67328
|
-
this.
|
|
67329
|
-
|
|
67330
|
-
.forEach((handle) => this.gltfLoader.hiddenHandles.delete(handle));
|
|
67331
|
-
this.gltfLoader.syncHiddenObjects();
|
|
67349
|
+
const handles = this.getHandlesByObjects(objects);
|
|
67350
|
+
this.gltfLoader.showObjects(handles);
|
|
67332
67351
|
return this;
|
|
67333
67352
|
}
|
|
67334
67353
|
showAllObjects() {
|
|
67335
|
-
this.gltfLoader.
|
|
67336
|
-
this.gltfLoader.syncHiddenObjects();
|
|
67354
|
+
this.gltfLoader.showAllHiddenObjects();
|
|
67337
67355
|
return this;
|
|
67338
67356
|
}
|
|
67339
67357
|
showOriginalObjects(objects) {
|
|
67340
|
-
this.
|
|
67358
|
+
this.gltfLoader.showOriginalObjects(objects);
|
|
67341
67359
|
return this;
|
|
67342
67360
|
}
|
|
67343
67361
|
hideOriginalObjects(objects) {
|
|
67344
|
-
this.
|
|
67362
|
+
this.gltfLoader.hideOriginalObjects(objects);
|
|
67345
67363
|
return this;
|
|
67346
67364
|
}
|
|
67347
67365
|
}
|
|
@@ -67364,24 +67382,20 @@ void main() {
|
|
|
67364
67382
|
TRIANGLE_STRIP: 5,
|
|
67365
67383
|
TRIANGLE_FAN: 6};
|
|
67366
67384
|
|
|
67385
|
+
const MAX_GAP = 128 * 1024; // 128 KB
|
|
67386
|
+
const MAX_CHUNK = 30 * 1024 * 1024; // 100 MB
|
|
67387
|
+
|
|
67367
67388
|
class GltfStructure {
|
|
67368
67389
|
constructor(id) {
|
|
67369
67390
|
this.id = `${id}`;
|
|
67370
67391
|
this.json = null;
|
|
67371
67392
|
this.baseUrl = "";
|
|
67372
|
-
|
|
67373
|
-
// Binary manager properties
|
|
67374
67393
|
this.loadController = null;
|
|
67375
|
-
// Request batching parameters
|
|
67376
67394
|
this.batchDelay = 10;
|
|
67377
67395
|
this.maxBatchSize = 5 * 1024 * 1024;
|
|
67378
67396
|
this.maxRangesPerRequest = 512;
|
|
67379
|
-
|
|
67380
|
-
// Request queue
|
|
67381
67397
|
this.pendingRequests = [];
|
|
67382
67398
|
this.batchTimeout = null;
|
|
67383
|
-
|
|
67384
|
-
// Material and texture properties
|
|
67385
67399
|
this.textureLoader = new TextureLoader();
|
|
67386
67400
|
this.materials = new Map();
|
|
67387
67401
|
this.textureCache = new Map();
|
|
@@ -67413,57 +67427,110 @@ void main() {
|
|
|
67413
67427
|
return this.json;
|
|
67414
67428
|
}
|
|
67415
67429
|
|
|
67416
|
-
// Schedule a request for processing
|
|
67417
67430
|
scheduleRequest(request) {
|
|
67418
|
-
this.pendingRequests.push(request);
|
|
67419
|
-
|
|
67420
|
-
// Clear existing timeout
|
|
67421
|
-
if (this.batchTimeout) {
|
|
67422
|
-
clearTimeout(this.batchTimeout);
|
|
67423
|
-
}
|
|
67424
|
-
|
|
67425
|
-
// Set new timeout for batch processing
|
|
67426
|
-
this.batchTimeout = setTimeout(() => this.processBatch(), this.batchDelay);
|
|
67427
|
-
|
|
67428
|
-
// Return a promise that will resolve when the data is available
|
|
67429
67431
|
return new Promise((resolve, reject) => {
|
|
67430
|
-
|
|
67431
|
-
|
|
67432
|
+
this.pendingRequests.push({
|
|
67433
|
+
...request,
|
|
67434
|
+
_resolve: resolve,
|
|
67435
|
+
_reject: reject,
|
|
67436
|
+
});
|
|
67432
67437
|
});
|
|
67433
67438
|
}
|
|
67434
67439
|
|
|
67435
|
-
async
|
|
67436
|
-
if (this.pendingRequests.length === 0) return;
|
|
67437
|
-
|
|
67438
|
-
// Take current batch of requests and clear timeout
|
|
67439
|
-
const currentBatch = [...this.pendingRequests];
|
|
67440
|
+
async flushBufferRequests() {
|
|
67441
|
+
if (!this.pendingRequests || this.pendingRequests.length === 0) return;
|
|
67442
|
+
const requests = [...this.pendingRequests];
|
|
67440
67443
|
this.pendingRequests = [];
|
|
67441
67444
|
|
|
67442
|
-
|
|
67443
|
-
|
|
67444
|
-
|
|
67445
|
+
requests.sort((a, b) => a.offset - b.offset);
|
|
67446
|
+
const mergedRanges = [];
|
|
67447
|
+
let current = {
|
|
67448
|
+
start: requests[0].offset,
|
|
67449
|
+
end: requests[0].offset + requests[0].length,
|
|
67450
|
+
requests: [requests[0]],
|
|
67451
|
+
};
|
|
67452
|
+
for (let i = 1; i < requests.length; i++) {
|
|
67453
|
+
const req = requests[i];
|
|
67454
|
+
const gap = req.offset - current.end;
|
|
67455
|
+
const newEnd = Math.max(current.end, req.offset + req.length);
|
|
67456
|
+
const projectedSize = newEnd - current.start;
|
|
67457
|
+
if (gap <= MAX_GAP && projectedSize <= MAX_CHUNK) {
|
|
67458
|
+
current.end = newEnd;
|
|
67459
|
+
current.requests.push(req);
|
|
67460
|
+
} else {
|
|
67461
|
+
mergedRanges.push(current);
|
|
67462
|
+
current = {
|
|
67463
|
+
start: req.offset,
|
|
67464
|
+
end: req.offset + req.length,
|
|
67465
|
+
requests: [req],
|
|
67466
|
+
};
|
|
67467
|
+
}
|
|
67445
67468
|
}
|
|
67446
|
-
|
|
67447
|
-
|
|
67448
|
-
|
|
67449
|
-
|
|
67450
|
-
|
|
67451
|
-
|
|
67452
|
-
let
|
|
67453
|
-
|
|
67454
|
-
|
|
67455
|
-
|
|
67456
|
-
|
|
67469
|
+
mergedRanges.push(current);
|
|
67470
|
+
const finalRanges = [];
|
|
67471
|
+
for (const range of mergedRanges) {
|
|
67472
|
+
let { start, end, requests } = range;
|
|
67473
|
+
while (end - start > MAX_CHUNK) {
|
|
67474
|
+
let splitIdx = 0;
|
|
67475
|
+
for (let i = 0; i < requests.length; i++) {
|
|
67476
|
+
if (requests[i].offset + requests[i].length - start > MAX_CHUNK) {
|
|
67477
|
+
break;
|
|
67478
|
+
}
|
|
67479
|
+
splitIdx = i;
|
|
67480
|
+
}
|
|
67481
|
+
const chunkRequests = requests.slice(0, splitIdx + 1);
|
|
67482
|
+
const chunkEnd =
|
|
67483
|
+
chunkRequests[chunkRequests.length - 1].offset + chunkRequests[chunkRequests.length - 1].length;
|
|
67484
|
+
finalRanges.push({
|
|
67485
|
+
start,
|
|
67486
|
+
end: chunkEnd,
|
|
67487
|
+
requests: chunkRequests,
|
|
67457
67488
|
});
|
|
67489
|
+
requests = requests.slice(splitIdx + 1);
|
|
67490
|
+
if (requests.length > 0) {
|
|
67491
|
+
start = requests[0].offset;
|
|
67492
|
+
end = requests[0].offset + requests[0].length;
|
|
67493
|
+
for (let i = 1; i < requests.length; i++) {
|
|
67494
|
+
end = Math.max(end, requests[i].offset + requests[i].length);
|
|
67495
|
+
}
|
|
67496
|
+
}
|
|
67497
|
+
}
|
|
67498
|
+
if (requests.length > 0) {
|
|
67499
|
+
finalRanges.push({ start, end, requests });
|
|
67458
67500
|
}
|
|
67459
|
-
} catch (error) {
|
|
67460
|
-
console.error("Error processing batch:", error);
|
|
67461
|
-
currentBatch.forEach((request) => request.reject(error));
|
|
67462
67501
|
}
|
|
67463
|
-
|
|
67464
|
-
|
|
67465
|
-
|
|
67502
|
+
/*
|
|
67503
|
+
for (const range of finalRanges) {
|
|
67504
|
+
const length = range.end - range.start;
|
|
67505
|
+
const buffer = await this.loadController.loadBinaryData([
|
|
67506
|
+
{ offset: range.start, length: length }
|
|
67507
|
+
]);
|
|
67508
|
+
for (const req of range.requests) {
|
|
67509
|
+
const relOffset = req.offset - range.start;
|
|
67510
|
+
try {
|
|
67511
|
+
req._resolve({ buffer, relOffset, length: req.length });
|
|
67512
|
+
} catch (e) {
|
|
67513
|
+
req._reject(e);
|
|
67514
|
+
}
|
|
67515
|
+
}
|
|
67466
67516
|
}
|
|
67517
|
+
*/
|
|
67518
|
+
|
|
67519
|
+
const promises = finalRanges.map(async (range) => {
|
|
67520
|
+
const length = range.end - range.start;
|
|
67521
|
+
const buffer = await this.loadController.loadBinaryData([{ offset: range.start, length }]);
|
|
67522
|
+
for (const req of range.requests) {
|
|
67523
|
+
const relOffset = req.offset - range.start;
|
|
67524
|
+
try {
|
|
67525
|
+
req._resolve({ buffer, relOffset, length: req.length });
|
|
67526
|
+
} catch (e) {
|
|
67527
|
+
req._reject(e);
|
|
67528
|
+
}
|
|
67529
|
+
}
|
|
67530
|
+
});
|
|
67531
|
+
await Promise.all(promises);
|
|
67532
|
+
|
|
67533
|
+
this.pendingRequests = [];
|
|
67467
67534
|
}
|
|
67468
67535
|
|
|
67469
67536
|
getBufferView(byteOffset, byteLength, componentType) {
|
|
@@ -67476,12 +67543,10 @@ void main() {
|
|
|
67476
67543
|
|
|
67477
67544
|
createTypedArray(buffer, offset, length, componentType) {
|
|
67478
67545
|
try {
|
|
67479
|
-
// Validate parameters
|
|
67480
67546
|
if (!buffer || !(buffer instanceof ArrayBuffer)) {
|
|
67481
67547
|
throw new Error("Invalid buffer");
|
|
67482
67548
|
}
|
|
67483
67549
|
|
|
67484
|
-
// Calculate element size for given type
|
|
67485
67550
|
let elementSize;
|
|
67486
67551
|
switch (componentType) {
|
|
67487
67552
|
case 5120:
|
|
@@ -67500,18 +67565,15 @@ void main() {
|
|
|
67500
67565
|
throw new Error(`Unsupported component type: ${componentType}`);
|
|
67501
67566
|
}
|
|
67502
67567
|
|
|
67503
|
-
// Check if requested length is correct
|
|
67504
67568
|
const numElements = length / elementSize;
|
|
67505
67569
|
if (!Number.isInteger(numElements)) {
|
|
67506
67570
|
throw new Error(`Invalid length ${length} for component type ${componentType}`);
|
|
67507
67571
|
}
|
|
67508
67572
|
|
|
67509
|
-
// Check if buffer is large enough
|
|
67510
67573
|
if (length > buffer.byteLength) {
|
|
67511
67574
|
throw new Error(`Buffer too small: need ${length} bytes, but buffer is ${buffer.byteLength} bytes`);
|
|
67512
67575
|
}
|
|
67513
67576
|
|
|
67514
|
-
// Create appropriate typed array
|
|
67515
67577
|
const ArrayType = GL_COMPONENT_TYPES[componentType];
|
|
67516
67578
|
return new ArrayType(buffer, offset, numElements);
|
|
67517
67579
|
} catch (error) {
|
|
@@ -67608,7 +67670,6 @@ void main() {
|
|
|
67608
67670
|
const image = this.json.images[imageIndex];
|
|
67609
67671
|
|
|
67610
67672
|
if (image.uri) {
|
|
67611
|
-
// Handle base64 or URL
|
|
67612
67673
|
if (image.uri.startsWith("data:")) {
|
|
67613
67674
|
return await this.textureLoader.loadAsync(image.uri);
|
|
67614
67675
|
} else {
|
|
@@ -67616,23 +67677,17 @@ void main() {
|
|
|
67616
67677
|
return await this.textureLoader.loadAsync(fullUrl);
|
|
67617
67678
|
}
|
|
67618
67679
|
} else if (image.bufferView !== undefined) {
|
|
67619
|
-
// Handle embedded binary data
|
|
67620
67680
|
const bufferView = this.json.bufferViews[image.bufferView];
|
|
67621
|
-
const array = await this.getBufferView(
|
|
67622
|
-
bufferView.byteOffset || 0,
|
|
67623
|
-
bufferView.byteLength,
|
|
67624
|
-
5121 // UNSIGNED_BYTE
|
|
67625
|
-
);
|
|
67681
|
+
const array = await this.getBufferView(bufferView.byteOffset || 0, bufferView.byteLength, 5121);
|
|
67626
67682
|
const blob = new Blob([array], { type: image.mimeType });
|
|
67627
67683
|
const url = URL.createObjectURL(blob);
|
|
67628
67684
|
const texture = await this.textureLoader.loadAsync(url);
|
|
67629
67685
|
URL.revokeObjectURL(url);
|
|
67630
|
-
texture.flipY = false;
|
|
67686
|
+
texture.flipY = false;
|
|
67631
67687
|
return texture;
|
|
67632
67688
|
}
|
|
67633
67689
|
};
|
|
67634
67690
|
|
|
67635
|
-
// Load all textures
|
|
67636
67691
|
const texturePromises = [];
|
|
67637
67692
|
for (let i = 0; i < this.json.textures.length; i++) {
|
|
67638
67693
|
texturePromises.push(
|
|
@@ -67642,82 +67697,56 @@ void main() {
|
|
|
67642
67697
|
await Promise.all(texturePromises);
|
|
67643
67698
|
}
|
|
67644
67699
|
|
|
67645
|
-
loadMaterials() {
|
|
67700
|
+
async loadMaterials() {
|
|
67646
67701
|
if (!this.json.materials) return this.materials;
|
|
67647
67702
|
|
|
67648
67703
|
for (let i = 0; i < this.json.materials.length; i++) {
|
|
67649
67704
|
const materialDef = this.json.materials[i];
|
|
67650
|
-
const material = this.createMaterial(materialDef);
|
|
67705
|
+
const material = await this.createMaterial(materialDef);
|
|
67706
|
+
material.name = materialDef.name;
|
|
67651
67707
|
this.materials.set(i, material);
|
|
67652
67708
|
}
|
|
67653
67709
|
return this.materials;
|
|
67654
67710
|
}
|
|
67655
67711
|
|
|
67656
67712
|
createMaterial(materialDef) {
|
|
67657
|
-
const
|
|
67713
|
+
const params = {};
|
|
67658
67714
|
|
|
67659
|
-
// Base color
|
|
67660
67715
|
if (materialDef.pbrMetallicRoughness) {
|
|
67661
67716
|
const pbr = materialDef.pbrMetallicRoughness;
|
|
67662
|
-
|
|
67663
67717
|
if (pbr.baseColorFactor) {
|
|
67664
|
-
|
|
67665
|
-
|
|
67718
|
+
params.color = new Color().fromArray(pbr.baseColorFactor);
|
|
67719
|
+
params.opacity = pbr.baseColorFactor[3];
|
|
67720
|
+
if (params.opacity < 1.0) params.transparent = true;
|
|
67666
67721
|
}
|
|
67667
|
-
|
|
67668
67722
|
if (pbr.baseColorTexture) {
|
|
67669
|
-
|
|
67670
|
-
}
|
|
67671
|
-
|
|
67672
|
-
// Metallic and roughness
|
|
67673
|
-
if (pbr.metallicFactor !== undefined) {
|
|
67674
|
-
material.metalness = pbr.metallicFactor;
|
|
67675
|
-
}
|
|
67676
|
-
if (pbr.roughnessFactor !== undefined) {
|
|
67677
|
-
material.roughness = pbr.roughnessFactor;
|
|
67678
|
-
}
|
|
67679
|
-
if (pbr.metallicRoughnessTexture) {
|
|
67680
|
-
material.metalnessMap = this.textureCache.get(pbr.metallicRoughnessTexture.index);
|
|
67681
|
-
material.roughnessMap = material.metalnessMap;
|
|
67723
|
+
params.map = this.textureCache.get(pbr.baseColorTexture.index);
|
|
67682
67724
|
}
|
|
67683
67725
|
}
|
|
67684
67726
|
|
|
67685
|
-
|
|
67686
|
-
|
|
67687
|
-
|
|
67688
|
-
|
|
67689
|
-
|
|
67690
|
-
|
|
67691
|
-
}
|
|
67727
|
+
params.specular = 0x222222;
|
|
67728
|
+
params.shininess = 10;
|
|
67729
|
+
params.reflectivity = 0.05;
|
|
67730
|
+
params.polygonOffset = true;
|
|
67731
|
+
params.polygonOffsetFactor = 1;
|
|
67732
|
+
params.polygonOffsetUnits = 1;
|
|
67692
67733
|
|
|
67693
|
-
// Emissive
|
|
67694
67734
|
if (materialDef.emissiveFactor) {
|
|
67695
|
-
|
|
67696
|
-
}
|
|
67697
|
-
if (materialDef.emissiveTexture) {
|
|
67698
|
-
material.emissiveMap = this.textureCache.get(materialDef.emissiveTexture.index);
|
|
67735
|
+
params.emissive = new Color().fromArray(materialDef.emissiveFactor);
|
|
67699
67736
|
}
|
|
67700
67737
|
|
|
67701
|
-
|
|
67702
|
-
|
|
67703
|
-
material.aoMap = this.textureCache.get(materialDef.occlusionTexture.index);
|
|
67704
|
-
if (materialDef.occlusionTexture.strength !== undefined) {
|
|
67705
|
-
material.aoMapIntensity = materialDef.occlusionTexture.strength;
|
|
67706
|
-
}
|
|
67738
|
+
if (materialDef.normalTexture) {
|
|
67739
|
+
params.normalMap = this.textureCache.get(materialDef.normalTexture.index);
|
|
67707
67740
|
}
|
|
67708
67741
|
|
|
67709
|
-
// Alpha mode
|
|
67710
67742
|
if (materialDef.alphaMode === "BLEND") {
|
|
67711
|
-
|
|
67712
|
-
} else if (materialDef.alphaMode === "MASK") {
|
|
67713
|
-
material.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5;
|
|
67743
|
+
params.transparent = true;
|
|
67714
67744
|
}
|
|
67715
67745
|
|
|
67716
|
-
|
|
67717
|
-
|
|
67718
|
-
|
|
67719
|
-
material
|
|
67720
|
-
|
|
67746
|
+
if (materialDef.doubleSided) {
|
|
67747
|
+
params.side = DoubleSide;
|
|
67748
|
+
}
|
|
67749
|
+
const material = new MeshPhongMaterial(params);
|
|
67721
67750
|
return material;
|
|
67722
67751
|
}
|
|
67723
67752
|
|
|
@@ -67750,12 +67779,8 @@ void main() {
|
|
|
67750
67779
|
if (!meshDef || !meshDef.primitives) return 0;
|
|
67751
67780
|
|
|
67752
67781
|
let totalSize = 0;
|
|
67753
|
-
|
|
67754
|
-
// Estimate size for each primitive
|
|
67755
67782
|
for (const primitive of meshDef.primitives) {
|
|
67756
|
-
// Check for attributes
|
|
67757
67783
|
if (primitive.attributes) {
|
|
67758
|
-
// Calculate attributes size
|
|
67759
67784
|
for (const [, accessorIndex] of Object.entries(primitive.attributes)) {
|
|
67760
67785
|
if (accessorIndex === undefined) continue;
|
|
67761
67786
|
|
|
@@ -67768,7 +67793,6 @@ void main() {
|
|
|
67768
67793
|
}
|
|
67769
67794
|
}
|
|
67770
67795
|
|
|
67771
|
-
// Calculate indices size if present
|
|
67772
67796
|
if (primitive.indices !== undefined) {
|
|
67773
67797
|
const accessor = this.json.accessors[primitive.indices];
|
|
67774
67798
|
if (accessor) {
|
|
@@ -67841,7 +67865,9 @@ void main() {
|
|
|
67841
67865
|
this.mergedPoints = new Set();
|
|
67842
67866
|
|
|
67843
67867
|
this.isolatedObjects = [];
|
|
67844
|
-
|
|
67868
|
+
//!!window.WebGL2RenderingContext && this.renderer.getContext() instanceof WebGL2RenderingContext
|
|
67869
|
+
this.useVAO = false;
|
|
67870
|
+
this.visibleEdges = true;
|
|
67845
67871
|
|
|
67846
67872
|
this.handleToOptimizedObjects = new Map();
|
|
67847
67873
|
|
|
@@ -67850,6 +67876,10 @@ void main() {
|
|
|
67850
67876
|
this.oldOptimizeObjects = new Set();
|
|
67851
67877
|
}
|
|
67852
67878
|
|
|
67879
|
+
setVisibleEdges(visible) {
|
|
67880
|
+
this.visibleEdges = visible;
|
|
67881
|
+
}
|
|
67882
|
+
|
|
67853
67883
|
getAvailableMemory() {
|
|
67854
67884
|
let memoryLimit = 6 * 1024 * 1024 * 1024;
|
|
67855
67885
|
try {
|
|
@@ -67870,7 +67900,7 @@ void main() {
|
|
|
67870
67900
|
console.warn("Error detecting available memory:", error);
|
|
67871
67901
|
}
|
|
67872
67902
|
|
|
67873
|
-
return memoryLimit;
|
|
67903
|
+
return memoryLimit / 3;
|
|
67874
67904
|
}
|
|
67875
67905
|
|
|
67876
67906
|
getAbortController() {
|
|
@@ -67975,7 +68005,7 @@ void main() {
|
|
|
67975
68005
|
console.log(`Final memory usage: ${Math.round(currentMemoryUsage / (1024 * 1024))}MB`);
|
|
67976
68006
|
}
|
|
67977
68007
|
|
|
67978
|
-
async loadNode(nodeId) {
|
|
68008
|
+
async loadNode(nodeId, onLoadFinishCb) {
|
|
67979
68009
|
const node = this.nodes.get(nodeId);
|
|
67980
68010
|
if (!node || node.loaded || node.loading) return;
|
|
67981
68011
|
|
|
@@ -67983,38 +68013,138 @@ void main() {
|
|
|
67983
68013
|
const meshDef = node.structure.getJson().meshes[node.meshIndex];
|
|
67984
68014
|
|
|
67985
68015
|
try {
|
|
67986
|
-
|
|
67987
|
-
|
|
67988
|
-
|
|
67989
|
-
const
|
|
67990
|
-
|
|
67991
|
-
|
|
68016
|
+
const bufferRequests = [];
|
|
68017
|
+
const primitiveReqMap = new Map();
|
|
68018
|
+
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
68019
|
+
const primitive = meshDef.primitives[primIdx];
|
|
68020
|
+
const reqs = [];
|
|
68021
|
+
|
|
68022
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
68023
|
+
const accessorIndex = primitive.attributes.POSITION;
|
|
68024
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
68025
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
68026
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
68027
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68028
|
+
const count = accessor.count;
|
|
68029
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
68030
|
+
reqs.push({
|
|
68031
|
+
offset: byteOffset,
|
|
68032
|
+
length: byteLength,
|
|
68033
|
+
componentType: accessor.componentType,
|
|
68034
|
+
accessorIndex,
|
|
68035
|
+
type: "position",
|
|
68036
|
+
primIdx,
|
|
68037
|
+
});
|
|
68038
|
+
}
|
|
67992
68039
|
|
|
67993
68040
|
if (primitive.attributes.NORMAL !== undefined) {
|
|
67994
|
-
|
|
68041
|
+
const accessorIndex = primitive.attributes.NORMAL;
|
|
68042
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
68043
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
68044
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
68045
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68046
|
+
const count = accessor.count;
|
|
68047
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
68048
|
+
reqs.push({
|
|
68049
|
+
offset: byteOffset,
|
|
68050
|
+
length: byteLength,
|
|
68051
|
+
componentType: accessor.componentType,
|
|
68052
|
+
accessorIndex,
|
|
68053
|
+
type: "normal",
|
|
68054
|
+
primIdx,
|
|
68055
|
+
});
|
|
67995
68056
|
}
|
|
67996
68057
|
|
|
67997
68058
|
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
67998
|
-
|
|
68059
|
+
const accessorIndex = primitive.attributes.TEXCOORD_0;
|
|
68060
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
68061
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
68062
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
68063
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68064
|
+
const count = accessor.count;
|
|
68065
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
68066
|
+
reqs.push({
|
|
68067
|
+
offset: byteOffset,
|
|
68068
|
+
length: byteLength,
|
|
68069
|
+
componentType: accessor.componentType,
|
|
68070
|
+
accessorIndex,
|
|
68071
|
+
type: "uv",
|
|
68072
|
+
primIdx,
|
|
68073
|
+
});
|
|
67999
68074
|
}
|
|
68000
68075
|
|
|
68001
|
-
|
|
68002
|
-
|
|
68003
|
-
|
|
68004
|
-
|
|
68005
|
-
|
|
68006
|
-
|
|
68076
|
+
if (primitive.indices !== undefined) {
|
|
68077
|
+
const accessorIndex = primitive.indices;
|
|
68078
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
68079
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
68080
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
68081
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68082
|
+
const count = accessor.count;
|
|
68083
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
68084
|
+
reqs.push({
|
|
68085
|
+
offset: byteOffset,
|
|
68086
|
+
length: byteLength,
|
|
68087
|
+
componentType: accessor.componentType,
|
|
68088
|
+
accessorIndex,
|
|
68089
|
+
type: "index",
|
|
68090
|
+
primIdx,
|
|
68091
|
+
});
|
|
68092
|
+
}
|
|
68093
|
+
primitiveReqMap.set(primIdx, reqs);
|
|
68094
|
+
bufferRequests.push(...reqs);
|
|
68095
|
+
}
|
|
68007
68096
|
|
|
68008
|
-
|
|
68009
|
-
|
|
68010
|
-
|
|
68097
|
+
if (bufferRequests.length === 0) {
|
|
68098
|
+
node.loaded = true;
|
|
68099
|
+
node.loading = false;
|
|
68100
|
+
return;
|
|
68101
|
+
}
|
|
68102
|
+
bufferRequests.sort((a, b) => a.offset - b.offset);
|
|
68103
|
+
const minOffset = bufferRequests[0].offset;
|
|
68104
|
+
const maxOffset = Math.max(...bufferRequests.map((r) => r.offset + r.length));
|
|
68105
|
+
const totalLength = maxOffset - minOffset;
|
|
68106
|
+
|
|
68107
|
+
const { buffer, relOffset: baseRelOffset } = await node.structure.scheduleRequest({
|
|
68108
|
+
offset: minOffset,
|
|
68109
|
+
length: totalLength,
|
|
68110
|
+
componentType: null,
|
|
68111
|
+
});
|
|
68011
68112
|
|
|
68012
|
-
|
|
68013
|
-
|
|
68014
|
-
|
|
68113
|
+
for (const req of bufferRequests) {
|
|
68114
|
+
const relOffset = req.offset - minOffset;
|
|
68115
|
+
req.data = node.structure.createTypedArray(buffer, baseRelOffset + relOffset, req.length, req.componentType);
|
|
68116
|
+
}
|
|
68117
|
+
|
|
68118
|
+
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
68119
|
+
const primitive = meshDef.primitives[primIdx];
|
|
68120
|
+
const geometry = new BufferGeometry();
|
|
68121
|
+
const reqs = primitiveReqMap.get(primIdx);
|
|
68122
|
+
|
|
68123
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
68124
|
+
const req = reqs.find((r) => r.type === "position" && r.accessorIndex === primitive.attributes.POSITION);
|
|
68125
|
+
const accessor = node.structure.json.accessors[primitive.attributes.POSITION];
|
|
68126
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68127
|
+
geometry.setAttribute("position", new BufferAttribute(req.data, components));
|
|
68128
|
+
}
|
|
68129
|
+
|
|
68130
|
+
if (primitive.attributes.NORMAL !== undefined) {
|
|
68131
|
+
const req = reqs.find((r) => r.type === "normal" && r.accessorIndex === primitive.attributes.NORMAL);
|
|
68132
|
+
const accessor = node.structure.json.accessors[primitive.attributes.NORMAL];
|
|
68133
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68134
|
+
geometry.setAttribute("normal", new BufferAttribute(req.data, components));
|
|
68015
68135
|
}
|
|
68016
68136
|
|
|
68017
|
-
|
|
68137
|
+
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
68138
|
+
const req = reqs.find((r) => r.type === "uv" && r.accessorIndex === primitive.attributes.TEXCOORD_0);
|
|
68139
|
+
const accessor = node.structure.json.accessors[primitive.attributes.TEXCOORD_0];
|
|
68140
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68141
|
+
geometry.setAttribute("uv", new BufferAttribute(req.data, components));
|
|
68142
|
+
}
|
|
68143
|
+
|
|
68144
|
+
if (primitive.indices !== undefined) {
|
|
68145
|
+
const req = reqs.find((r) => r.type === "index" && r.accessorIndex === primitive.indices);
|
|
68146
|
+
geometry.setIndex(new BufferAttribute(req.data, 1));
|
|
68147
|
+
}
|
|
68018
68148
|
|
|
68019
68149
|
let material;
|
|
68020
68150
|
if (primitive.material !== undefined) {
|
|
@@ -68029,8 +68159,7 @@ void main() {
|
|
|
68029
68159
|
Material.prototype.copy.call(pointsMaterial, material);
|
|
68030
68160
|
pointsMaterial.color.copy(material.color);
|
|
68031
68161
|
pointsMaterial.map = material.map;
|
|
68032
|
-
pointsMaterial.sizeAttenuation = false;
|
|
68033
|
-
|
|
68162
|
+
pointsMaterial.sizeAttenuation = false;
|
|
68034
68163
|
mesh = new Points(geometry, pointsMaterial);
|
|
68035
68164
|
} else if (
|
|
68036
68165
|
primitive.mode === GL_CONSTANTS.TRIANGLES ||
|
|
@@ -68039,7 +68168,6 @@ void main() {
|
|
|
68039
68168
|
primitive.mode === undefined
|
|
68040
68169
|
) {
|
|
68041
68170
|
mesh = new Mesh(geometry, material);
|
|
68042
|
-
|
|
68043
68171
|
if (primitive.mode === GL_CONSTANTS.TRIANGLE_STRIP) {
|
|
68044
68172
|
mesh.drawMode = TriangleStripDrawMode;
|
|
68045
68173
|
} else if (primitive.mode === GL_CONSTANTS.TRIANGLE_FAN) {
|
|
@@ -68052,39 +68180,30 @@ void main() {
|
|
|
68052
68180
|
} else if (primitive.mode === GL_CONSTANTS.LINE_LOOP) {
|
|
68053
68181
|
mesh = new LineLoop(geometry, material);
|
|
68054
68182
|
}
|
|
68055
|
-
|
|
68056
68183
|
if (node.extras) {
|
|
68057
68184
|
mesh.userData = { ...mesh.userData, ...node.extras };
|
|
68058
68185
|
}
|
|
68059
|
-
|
|
68060
68186
|
if (meshDef.extras) {
|
|
68061
68187
|
mesh.userData = { ...mesh.userData, ...meshDef.extras };
|
|
68062
68188
|
}
|
|
68063
|
-
|
|
68064
68189
|
if (primitive.extras) {
|
|
68065
68190
|
mesh.userData = { ...mesh.userData, ...primitive.extras };
|
|
68066
68191
|
}
|
|
68067
|
-
|
|
68068
68192
|
if (node.handle) {
|
|
68069
68193
|
mesh.userData.handle = node.handle;
|
|
68070
68194
|
} else {
|
|
68071
68195
|
mesh.userData.handle = `${node.structure.id}_${mesh.userData.handle}`;
|
|
68072
68196
|
}
|
|
68073
|
-
|
|
68074
68197
|
if (mesh.material.name === "edges") {
|
|
68075
68198
|
mesh.userData.isEdge = true;
|
|
68076
68199
|
} else {
|
|
68077
68200
|
mesh.userData.isEdge = false;
|
|
68078
68201
|
}
|
|
68079
|
-
|
|
68080
68202
|
this.registerObjectWithHandle(mesh, mesh.userData.handle);
|
|
68081
|
-
|
|
68082
68203
|
mesh.position.copy(node.position);
|
|
68083
|
-
|
|
68084
68204
|
if (!geometry.attributes.normal) {
|
|
68085
68205
|
geometry.computeVertexNormals();
|
|
68086
68206
|
}
|
|
68087
|
-
|
|
68088
68207
|
if (material.aoMap && geometry.attributes.uv) {
|
|
68089
68208
|
geometry.setAttribute("uv2", geometry.attributes.uv);
|
|
68090
68209
|
}
|
|
@@ -68094,17 +68213,17 @@ void main() {
|
|
|
68094
68213
|
this.scene.add(mesh);
|
|
68095
68214
|
}
|
|
68096
68215
|
node.object = mesh;
|
|
68097
|
-
|
|
68098
68216
|
this.totalLoadedObjects++;
|
|
68099
68217
|
mesh.visible = this.totalLoadedObjects < this.graphicsObjectLimit;
|
|
68100
68218
|
}
|
|
68101
|
-
|
|
68102
68219
|
node.loaded = true;
|
|
68103
68220
|
node.loading = false;
|
|
68104
|
-
|
|
68105
68221
|
const geometrySize = this.estimateGeometrySize(node.object);
|
|
68106
68222
|
this.geometryCache.set(node.object.uuid, geometrySize);
|
|
68107
68223
|
this.currentMemoryUsage += geometrySize;
|
|
68224
|
+
if (onLoadFinishCb) {
|
|
68225
|
+
onLoadFinishCb();
|
|
68226
|
+
}
|
|
68108
68227
|
} catch (error) {
|
|
68109
68228
|
if (error.name !== "AbortError") {
|
|
68110
68229
|
console.error(`Error loading node ${nodeId}:`, error);
|
|
@@ -68229,7 +68348,7 @@ void main() {
|
|
|
68229
68348
|
return volumeB - volumeA;
|
|
68230
68349
|
});
|
|
68231
68350
|
|
|
68232
|
-
if (!ignoreEdges) {
|
|
68351
|
+
if (!ignoreEdges && this.visibleEdges) {
|
|
68233
68352
|
this.nodesToLoad.push(...this.edgeNodes);
|
|
68234
68353
|
}
|
|
68235
68354
|
|
|
@@ -68356,33 +68475,13 @@ void main() {
|
|
|
68356
68475
|
async processNodes() {
|
|
68357
68476
|
const nodesToLoad = this.nodesToLoad;
|
|
68358
68477
|
let loadedCount = 0;
|
|
68478
|
+
let lastLoadedCount = 0;
|
|
68359
68479
|
const totalNodes = nodesToLoad.length;
|
|
68360
68480
|
|
|
68361
|
-
|
|
68362
|
-
|
|
68363
|
-
|
|
68364
|
-
|
|
68365
|
-
|
|
68366
|
-
for (const nodeId of batch) {
|
|
68367
|
-
if (this.abortController.signal.aborted) {
|
|
68368
|
-
throw new DOMException("Loading aborted", "AbortError");
|
|
68369
|
-
}
|
|
68370
|
-
|
|
68371
|
-
const estimatedSize = await this.estimateNodeSize(nodeId);
|
|
68372
|
-
|
|
68373
|
-
if (this.currentMemoryUsage + estimatedSize > this.memoryLimit) {
|
|
68374
|
-
console.log(`Memory limit reached after loading ${loadedCount} nodes`);
|
|
68375
|
-
this.dispatchEvent("geometryerror", { message: "Memory limit reached" });
|
|
68376
|
-
this.dispatchEvent("update");
|
|
68377
|
-
return loadedCount;
|
|
68378
|
-
}
|
|
68379
|
-
|
|
68380
|
-
batchPromises.push(this.loadNode(nodeId));
|
|
68381
|
-
}
|
|
68382
|
-
|
|
68383
|
-
await Promise.all(batchPromises);
|
|
68384
|
-
loadedCount += batch.length;
|
|
68385
|
-
|
|
68481
|
+
const loadProgress = async () => {
|
|
68482
|
+
loadedCount++;
|
|
68483
|
+
if (loadedCount - lastLoadedCount > 1000) {
|
|
68484
|
+
lastLoadedCount = loadedCount;
|
|
68386
68485
|
this.updateMemoryIndicator();
|
|
68387
68486
|
this.dispatchEvent("geometryprogress", {
|
|
68388
68487
|
percentage: Math.round((loadedCount / totalNodes) * 100),
|
|
@@ -68400,6 +68499,34 @@ void main() {
|
|
|
68400
68499
|
setTimeout(resolve, 0);
|
|
68401
68500
|
});
|
|
68402
68501
|
}
|
|
68502
|
+
};
|
|
68503
|
+
|
|
68504
|
+
try {
|
|
68505
|
+
const loadOperations = [];
|
|
68506
|
+
for (const nodeId of nodesToLoad) {
|
|
68507
|
+
if (this.abortController.signal.aborted) {
|
|
68508
|
+
throw new DOMException("Loading aborted", "AbortError");
|
|
68509
|
+
}
|
|
68510
|
+
|
|
68511
|
+
const estimatedSize = await this.estimateNodeSize(nodeId);
|
|
68512
|
+
|
|
68513
|
+
if (this.currentMemoryUsage + estimatedSize > this.memoryLimit) {
|
|
68514
|
+
console.log(`Memory limit reached after loading ${loadedCount} nodes`);
|
|
68515
|
+
this.dispatchEvent("geometryerror", {
|
|
68516
|
+
message: "Memory limit reached",
|
|
68517
|
+
});
|
|
68518
|
+
this.dispatchEvent("update");
|
|
68519
|
+
return loadedCount;
|
|
68520
|
+
}
|
|
68521
|
+
|
|
68522
|
+
loadOperations.push(this.loadNode(nodeId, loadProgress));
|
|
68523
|
+
}
|
|
68524
|
+
|
|
68525
|
+
for (const structure of this.structures) {
|
|
68526
|
+
loadOperations.push(structure.flushBufferRequests());
|
|
68527
|
+
}
|
|
68528
|
+
|
|
68529
|
+
await Promise.all(loadOperations);
|
|
68403
68530
|
|
|
68404
68531
|
this.dispatchEvent("geometryend", {
|
|
68405
68532
|
totalLoaded: loadedCount,
|
|
@@ -69380,6 +69507,25 @@ void main() {
|
|
|
69380
69507
|
}
|
|
69381
69508
|
});
|
|
69382
69509
|
}
|
|
69510
|
+
|
|
69511
|
+
// Возвращает bounding box для конкретной структуры
|
|
69512
|
+
getStructureGeometryExtent(structureId) {
|
|
69513
|
+
const extent = new Box3();
|
|
69514
|
+
for (const [nodeId, node] of this.nodes.entries()) {
|
|
69515
|
+
if (!node.geometryExtents) continue;
|
|
69516
|
+
if (!nodeId.startsWith(structureId + "_")) continue;
|
|
69517
|
+
if (node.object && this.hiddenHandles && this.hiddenHandles.has(node.object.userData.handle)) continue;
|
|
69518
|
+
const transformedBox = node.geometryExtents.clone();
|
|
69519
|
+
if (node.group && node.group.matrix) {
|
|
69520
|
+
transformedBox.applyMatrix4(node.group.matrix);
|
|
69521
|
+
if (node.group.parent && node.group.parent.matrix) {
|
|
69522
|
+
transformedBox.applyMatrix4(node.group.parent.matrix);
|
|
69523
|
+
}
|
|
69524
|
+
}
|
|
69525
|
+
extent.union(transformedBox);
|
|
69526
|
+
}
|
|
69527
|
+
return extent;
|
|
69528
|
+
}
|
|
69383
69529
|
}
|
|
69384
69530
|
|
|
69385
69531
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -69408,7 +69554,6 @@ void main() {
|
|
|
69408
69554
|
constructor(viewer) {
|
|
69409
69555
|
this.requestId = 0;
|
|
69410
69556
|
this.viewer = viewer;
|
|
69411
|
-
this.scene = new Group$1();
|
|
69412
69557
|
}
|
|
69413
69558
|
dispose() {
|
|
69414
69559
|
if (this.gltfLoader)
|
|
@@ -69422,27 +69567,25 @@ void main() {
|
|
|
69422
69567
|
/.gltf$/i.test(file.database));
|
|
69423
69568
|
}
|
|
69424
69569
|
async load(model, format, params) {
|
|
69425
|
-
|
|
69570
|
+
const scene = new Group$1();
|
|
69571
|
+
this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
|
|
69426
69572
|
this.gltfLoader.memoryLimit = this.viewer.options.memoryLimit;
|
|
69427
69573
|
this.gltfLoader.addEventListener("databasechunk", (data) => {
|
|
69428
|
-
const modelImpl = new DynamicModelImpl(
|
|
69574
|
+
const modelImpl = new DynamicModelImpl(scene);
|
|
69429
69575
|
modelImpl.loader = this;
|
|
69430
69576
|
modelImpl.gltfLoader = this.gltfLoader;
|
|
69431
69577
|
modelImpl.viewer = this.viewer;
|
|
69432
|
-
this.viewer.scene.add(
|
|
69578
|
+
this.viewer.scene.add(scene);
|
|
69433
69579
|
this.viewer.models.push(modelImpl);
|
|
69434
69580
|
this.viewer.syncOptions();
|
|
69435
69581
|
this.viewer.syncOverlay();
|
|
69436
69582
|
this.viewer.update();
|
|
69437
|
-
this.viewer.emitEvent({ type: "databasechunk", data, file: model.file, model });
|
|
69583
|
+
this.viewer.emitEvent({ type: "databasechunk", data: scene, file: model.file, model });
|
|
69438
69584
|
});
|
|
69439
69585
|
this.gltfLoader.addEventListener("geometryprogress", (data) => {
|
|
69440
69586
|
const progress = data.loaded / data.total;
|
|
69441
69587
|
this.viewer.emitEvent({ type: "geometryprogress", data: progress, file: model.file, model });
|
|
69442
69588
|
});
|
|
69443
|
-
this.gltfLoader.addEventListener("geometrymemory", (data) => {
|
|
69444
|
-
this.viewer.emit({ type: "geometryprogress", data });
|
|
69445
|
-
});
|
|
69446
69589
|
this.gltfLoader.addEventListener("geometryerror", (data) => {
|
|
69447
69590
|
this.viewer.emitEvent({ type: "geometryerror", data, file: model.file, model });
|
|
69448
69591
|
});
|
|
@@ -69476,9 +69619,8 @@ void main() {
|
|
|
69476
69619
|
return this;
|
|
69477
69620
|
}
|
|
69478
69621
|
cancel() {
|
|
69479
|
-
if (this.gltfLoader)
|
|
69622
|
+
if (this.gltfLoader)
|
|
69480
69623
|
this.gltfLoader.abortLoading();
|
|
69481
|
-
}
|
|
69482
69624
|
}
|
|
69483
69625
|
}
|
|
69484
69626
|
|
|
@@ -69516,7 +69658,7 @@ void main() {
|
|
|
69516
69658
|
*
|
|
69517
69659
|
* The loader should do:
|
|
69518
69660
|
*
|
|
69519
|
-
* - Load
|
|
69661
|
+
* - Load raw data from file and convert it to the `Three.js` scene.
|
|
69520
69662
|
* - Add scene to the viewer `scene`.
|
|
69521
69663
|
* - Create `ModelImpl` for the scene and to the viewer `models` list.
|
|
69522
69664
|
* - Synchronize viewer options and overlay.
|