@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
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);
|
|
@@ -60197,7 +60198,6 @@ void main() {
|
|
|
60197
60198
|
});
|
|
60198
60199
|
if (sceneCamera) {
|
|
60199
60200
|
this.viewer.camera = sceneCamera.clone();
|
|
60200
|
-
this.viewer.camera.up.set(0, 0, 1);
|
|
60201
60201
|
this.viewer.camera.scale.set(1, 1, 1); // <- Visualize fix
|
|
60202
60202
|
}
|
|
60203
60203
|
const camera = this.viewer.camera;
|
|
@@ -60310,30 +60310,29 @@ void main() {
|
|
|
60310
60310
|
const extentsCenter = this.viewer.extents.getCenter(new Vector3());
|
|
60311
60311
|
const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere()).radius;
|
|
60312
60312
|
this.directionalLight.position
|
|
60313
|
-
.set(0.5, 0, 0
|
|
60313
|
+
.set(0.5, 0.866, 0) // ~60º
|
|
60314
60314
|
.multiplyScalar(extentsSize * 2)
|
|
60315
60315
|
.add(extentsCenter);
|
|
60316
60316
|
this.directionalLight.target.position.copy(extentsCenter);
|
|
60317
|
-
this.frontLight.position
|
|
60317
|
+
this.frontLight.position
|
|
60318
|
+
.set(0, 0, 1)
|
|
60319
|
+
.multiplyScalar(extentsSize * 2)
|
|
60320
|
+
.add(extentsCenter);
|
|
60318
60321
|
this.frontLight.target.position.copy(extentsCenter);
|
|
60319
|
-
this.hemisphereLight.position
|
|
60322
|
+
this.hemisphereLight.position
|
|
60323
|
+
.set(0, 0, 1)
|
|
60324
|
+
.multiplyScalar(extentsSize * 3)
|
|
60325
|
+
.add(extentsCenter);
|
|
60320
60326
|
this.viewer.scene.add(this.ambientLight);
|
|
60321
60327
|
this.viewer.scene.add(this.directionalLight);
|
|
60322
60328
|
this.viewer.scene.add(this.frontLight);
|
|
60323
60329
|
this.viewer.scene.add(this.hemisphereLight);
|
|
60324
60330
|
};
|
|
60325
60331
|
this.viewer = viewer;
|
|
60326
|
-
this.ambientLight = new AmbientLight(0xffffff, 1);
|
|
60327
|
-
this.
|
|
60328
|
-
this.directionalLight = new DirectionalLight(0xffffff, 1);
|
|
60329
|
-
this.directionalLight.position.set(0.5, 0, 0.866); // ~60º
|
|
60330
|
-
this.viewer.scene.add(this.directionalLight);
|
|
60332
|
+
this.ambientLight = new AmbientLight(0xffffff, 1.0);
|
|
60333
|
+
this.directionalLight = new DirectionalLight(0xffffff, 1.0);
|
|
60331
60334
|
this.frontLight = new DirectionalLight(0xffffff, 1.25);
|
|
60332
|
-
this.frontLight.position.set(0, 1, 0);
|
|
60333
|
-
this.viewer.scene.add(this.frontLight);
|
|
60334
60335
|
this.hemisphereLight = new HemisphereLight(0xffffff, 0x444444, 1.25);
|
|
60335
|
-
this.hemisphereLight.position.set(0, 0, 1);
|
|
60336
|
-
this.viewer.scene.add(this.hemisphereLight);
|
|
60337
60336
|
this.viewer.addEventListener("databasechunk", this.geometryEnd);
|
|
60338
60337
|
this.viewer.addEventListener("clear", this.geometryEnd);
|
|
60339
60338
|
}
|
|
@@ -61431,19 +61430,25 @@ void main() {
|
|
|
61431
61430
|
class HighlighterComponent {
|
|
61432
61431
|
constructor(viewer) {
|
|
61433
61432
|
this.geometryEnd = () => {
|
|
61434
|
-
const { facesColor, facesTransparancy, edgesColor } = this.viewer.options;
|
|
61435
|
-
this.highlightMaterial = new
|
|
61433
|
+
const { facesColor, facesTransparancy, edgesColor, edgesOverlap, facesOverlap } = this.viewer.options;
|
|
61434
|
+
this.highlightMaterial = new MeshPhongMaterial({
|
|
61436
61435
|
color: new Color(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255),
|
|
61437
61436
|
transparent: true,
|
|
61438
61437
|
opacity: (255 - facesTransparancy) / 255,
|
|
61439
|
-
depthTest:
|
|
61440
|
-
depthWrite:
|
|
61438
|
+
depthTest: !facesOverlap,
|
|
61439
|
+
depthWrite: !facesOverlap,
|
|
61440
|
+
specular: 0x222222,
|
|
61441
|
+
shininess: 10,
|
|
61442
|
+
reflectivity: 0.05,
|
|
61443
|
+
polygonOffset: true,
|
|
61444
|
+
polygonOffsetFactor: 1,
|
|
61445
|
+
polygonOffsetUnits: 1,
|
|
61441
61446
|
});
|
|
61442
61447
|
this.outlineMaterial = new LineMaterial({
|
|
61443
61448
|
color: new Color(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255),
|
|
61444
61449
|
linewidth: 1.5,
|
|
61445
|
-
depthTest:
|
|
61446
|
-
depthWrite:
|
|
61450
|
+
depthTest: !edgesOverlap,
|
|
61451
|
+
depthWrite: !edgesOverlap,
|
|
61447
61452
|
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
61448
61453
|
});
|
|
61449
61454
|
this.highlightLineMaterial = new LineBasicMaterial({
|
|
@@ -61456,18 +61461,27 @@ void main() {
|
|
|
61456
61461
|
linewidth: 5,
|
|
61457
61462
|
transparent: true,
|
|
61458
61463
|
opacity: 0.8,
|
|
61459
|
-
depthTest:
|
|
61460
|
-
depthWrite:
|
|
61464
|
+
depthTest: !edgesOverlap,
|
|
61465
|
+
depthWrite: !edgesOverlap,
|
|
61461
61466
|
resolution: new Vector2(window.innerWidth, window.innerHeight),
|
|
61462
61467
|
});
|
|
61463
61468
|
};
|
|
61464
61469
|
this.optionsChange = () => {
|
|
61465
|
-
const { facesColor, facesTransparancy, edgesColor } = this.viewer.options;
|
|
61470
|
+
const { facesColor, facesTransparancy, edgesColor, edgesVisibility, edgesOverlap, facesOverlap } = this.viewer.options;
|
|
61466
61471
|
this.highlightMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
61467
61472
|
this.highlightMaterial.opacity = (255 - facesTransparancy) / 255;
|
|
61473
|
+
this.highlightMaterial.depthTest = !facesOverlap;
|
|
61474
|
+
this.highlightMaterial.depthWrite = !facesOverlap;
|
|
61468
61475
|
this.outlineMaterial.color.setRGB(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255);
|
|
61476
|
+
this.outlineMaterial.depthTest = !edgesOverlap;
|
|
61477
|
+
this.outlineMaterial.depthWrite = !edgesOverlap;
|
|
61469
61478
|
this.highlightLineMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
61470
61479
|
this.highlightLineGlowMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
|
|
61480
|
+
this.viewer.selected.forEach((selected) => {
|
|
61481
|
+
const wireframe = selected.userData.highlightWireframe;
|
|
61482
|
+
if (wireframe)
|
|
61483
|
+
wireframe.visible = edgesVisibility;
|
|
61484
|
+
});
|
|
61471
61485
|
this.viewer.update();
|
|
61472
61486
|
};
|
|
61473
61487
|
this.viewer = viewer;
|
|
@@ -61492,6 +61506,7 @@ void main() {
|
|
|
61492
61506
|
this.viewer.removeEventListener("resize", this.viewerResize);
|
|
61493
61507
|
}
|
|
61494
61508
|
highlight(objects) {
|
|
61509
|
+
const { edgesVisibility } = this.viewer.options;
|
|
61495
61510
|
if (!Array.isArray(objects))
|
|
61496
61511
|
objects = [objects];
|
|
61497
61512
|
if (!objects.length)
|
|
@@ -61509,21 +61524,23 @@ void main() {
|
|
|
61509
61524
|
wireframe.position.copy(object.position);
|
|
61510
61525
|
wireframe.rotation.copy(object.rotation);
|
|
61511
61526
|
wireframe.scale.copy(object.scale);
|
|
61527
|
+
wireframe.visible = edgesVisibility;
|
|
61512
61528
|
object.parent.add(wireframe);
|
|
61513
|
-
object.userData.
|
|
61529
|
+
object.userData.highlightWireframe = wireframe;
|
|
61514
61530
|
object.userData.originalMaterial = object.material;
|
|
61515
61531
|
object.material = this.highlightLineMaterial;
|
|
61516
61532
|
object.isHighlighted = true;
|
|
61517
61533
|
}
|
|
61518
61534
|
else if (object.isMesh) {
|
|
61519
|
-
const edgesGeometry = new EdgesGeometry(object.geometry,
|
|
61535
|
+
const edgesGeometry = new EdgesGeometry(object.geometry, 60);
|
|
61520
61536
|
const lineGeometry = new LineSegmentsGeometry().fromEdgesGeometry(edgesGeometry);
|
|
61521
61537
|
const wireframe = new Wireframe(lineGeometry, this.outlineMaterial);
|
|
61522
61538
|
wireframe.position.copy(object.position);
|
|
61523
61539
|
wireframe.rotation.copy(object.rotation);
|
|
61524
61540
|
wireframe.scale.copy(object.scale);
|
|
61541
|
+
wireframe.visible = edgesVisibility;
|
|
61525
61542
|
object.parent.add(wireframe);
|
|
61526
|
-
object.userData.
|
|
61543
|
+
object.userData.highlightWireframe = wireframe;
|
|
61527
61544
|
object.userData.originalMaterial = object.material;
|
|
61528
61545
|
object.material = this.highlightMaterial;
|
|
61529
61546
|
object.isHighlighted = true;
|
|
@@ -61540,9 +61557,9 @@ void main() {
|
|
|
61540
61557
|
return;
|
|
61541
61558
|
object.isHighlighted = false;
|
|
61542
61559
|
object.material = object.userData.originalMaterial;
|
|
61543
|
-
object.userData.
|
|
61560
|
+
object.userData.highlightWireframe.removeFromParent();
|
|
61544
61561
|
delete object.userData.originalMaterial;
|
|
61545
|
-
delete object.userData.
|
|
61562
|
+
delete object.userData.highlightWireframe;
|
|
61546
61563
|
});
|
|
61547
61564
|
}
|
|
61548
61565
|
viewerResize(event) {
|
|
@@ -61591,7 +61608,8 @@ void main() {
|
|
|
61591
61608
|
this.viewer.models.forEach((model) => {
|
|
61592
61609
|
const objects = model.getVisibleObjects();
|
|
61593
61610
|
const intersects = this.getPointerIntersects(upPosition, objects);
|
|
61594
|
-
|
|
61611
|
+
if (intersects.length > 0)
|
|
61612
|
+
intersections.push({ ...intersects[0], model });
|
|
61595
61613
|
});
|
|
61596
61614
|
intersections = intersections.sort((a, b) => a.distance - b.distance);
|
|
61597
61615
|
if (!event.shiftKey)
|
|
@@ -61658,7 +61676,6 @@ void main() {
|
|
|
61658
61676
|
objects = [objects];
|
|
61659
61677
|
if (!objects.length)
|
|
61660
61678
|
return;
|
|
61661
|
-
model.showObjects(objects);
|
|
61662
61679
|
model.showOriginalObjects(objects);
|
|
61663
61680
|
this.highlighter.highlight(objects);
|
|
61664
61681
|
objects.forEach((object) => this.viewer.selected.push(object));
|
|
@@ -67314,10 +67331,8 @@ void main() {
|
|
|
67314
67331
|
return objects;
|
|
67315
67332
|
}
|
|
67316
67333
|
hideObjects(objects) {
|
|
67317
|
-
this.
|
|
67318
|
-
|
|
67319
|
-
.forEach((handle) => this.gltfLoader.hiddenHandles.add(handle));
|
|
67320
|
-
this.gltfLoader.syncHiddenObjects();
|
|
67334
|
+
const handles = this.getHandlesByObjects(objects);
|
|
67335
|
+
this.gltfLoader.hideObjects(handles);
|
|
67321
67336
|
return this;
|
|
67322
67337
|
}
|
|
67323
67338
|
isolateObjects(objects) {
|
|
@@ -67326,23 +67341,20 @@ void main() {
|
|
|
67326
67341
|
return this;
|
|
67327
67342
|
}
|
|
67328
67343
|
showObjects(objects) {
|
|
67329
|
-
this.
|
|
67330
|
-
|
|
67331
|
-
.forEach((handle) => this.gltfLoader.hiddenHandles.delete(handle));
|
|
67332
|
-
this.gltfLoader.syncHiddenObjects();
|
|
67344
|
+
const handles = this.getHandlesByObjects(objects);
|
|
67345
|
+
this.gltfLoader.showObjects(handles);
|
|
67333
67346
|
return this;
|
|
67334
67347
|
}
|
|
67335
67348
|
showAllObjects() {
|
|
67336
|
-
this.gltfLoader.
|
|
67337
|
-
this.gltfLoader.syncHiddenObjects();
|
|
67349
|
+
this.gltfLoader.showAllHiddenObjects();
|
|
67338
67350
|
return this;
|
|
67339
67351
|
}
|
|
67340
67352
|
showOriginalObjects(objects) {
|
|
67341
|
-
this.
|
|
67353
|
+
this.gltfLoader.showOriginalObjects(objects);
|
|
67342
67354
|
return this;
|
|
67343
67355
|
}
|
|
67344
67356
|
hideOriginalObjects(objects) {
|
|
67345
|
-
this.
|
|
67357
|
+
this.gltfLoader.hideOriginalObjects(objects);
|
|
67346
67358
|
return this;
|
|
67347
67359
|
}
|
|
67348
67360
|
}
|
|
@@ -67365,24 +67377,20 @@ void main() {
|
|
|
67365
67377
|
TRIANGLE_STRIP: 5,
|
|
67366
67378
|
TRIANGLE_FAN: 6};
|
|
67367
67379
|
|
|
67380
|
+
const MAX_GAP = 128 * 1024; // 128 KB
|
|
67381
|
+
const MAX_CHUNK = 30 * 1024 * 1024; // 100 MB
|
|
67382
|
+
|
|
67368
67383
|
class GltfStructure {
|
|
67369
67384
|
constructor(id) {
|
|
67370
67385
|
this.id = `${id}`;
|
|
67371
67386
|
this.json = null;
|
|
67372
67387
|
this.baseUrl = "";
|
|
67373
|
-
|
|
67374
|
-
// Binary manager properties
|
|
67375
67388
|
this.loadController = null;
|
|
67376
|
-
// Request batching parameters
|
|
67377
67389
|
this.batchDelay = 10;
|
|
67378
67390
|
this.maxBatchSize = 5 * 1024 * 1024;
|
|
67379
67391
|
this.maxRangesPerRequest = 512;
|
|
67380
|
-
|
|
67381
|
-
// Request queue
|
|
67382
67392
|
this.pendingRequests = [];
|
|
67383
67393
|
this.batchTimeout = null;
|
|
67384
|
-
|
|
67385
|
-
// Material and texture properties
|
|
67386
67394
|
this.textureLoader = new TextureLoader();
|
|
67387
67395
|
this.materials = new Map();
|
|
67388
67396
|
this.textureCache = new Map();
|
|
@@ -67414,57 +67422,110 @@ void main() {
|
|
|
67414
67422
|
return this.json;
|
|
67415
67423
|
}
|
|
67416
67424
|
|
|
67417
|
-
// Schedule a request for processing
|
|
67418
67425
|
scheduleRequest(request) {
|
|
67419
|
-
this.pendingRequests.push(request);
|
|
67420
|
-
|
|
67421
|
-
// Clear existing timeout
|
|
67422
|
-
if (this.batchTimeout) {
|
|
67423
|
-
clearTimeout(this.batchTimeout);
|
|
67424
|
-
}
|
|
67425
|
-
|
|
67426
|
-
// Set new timeout for batch processing
|
|
67427
|
-
this.batchTimeout = setTimeout(() => this.processBatch(), this.batchDelay);
|
|
67428
|
-
|
|
67429
|
-
// Return a promise that will resolve when the data is available
|
|
67430
67426
|
return new Promise((resolve, reject) => {
|
|
67431
|
-
|
|
67432
|
-
|
|
67427
|
+
this.pendingRequests.push({
|
|
67428
|
+
...request,
|
|
67429
|
+
_resolve: resolve,
|
|
67430
|
+
_reject: reject,
|
|
67431
|
+
});
|
|
67433
67432
|
});
|
|
67434
67433
|
}
|
|
67435
67434
|
|
|
67436
|
-
async
|
|
67437
|
-
if (this.pendingRequests.length === 0) return;
|
|
67438
|
-
|
|
67439
|
-
// Take current batch of requests and clear timeout
|
|
67440
|
-
const currentBatch = [...this.pendingRequests];
|
|
67435
|
+
async flushBufferRequests() {
|
|
67436
|
+
if (!this.pendingRequests || this.pendingRequests.length === 0) return;
|
|
67437
|
+
const requests = [...this.pendingRequests];
|
|
67441
67438
|
this.pendingRequests = [];
|
|
67442
67439
|
|
|
67443
|
-
|
|
67444
|
-
|
|
67445
|
-
|
|
67440
|
+
requests.sort((a, b) => a.offset - b.offset);
|
|
67441
|
+
const mergedRanges = [];
|
|
67442
|
+
let current = {
|
|
67443
|
+
start: requests[0].offset,
|
|
67444
|
+
end: requests[0].offset + requests[0].length,
|
|
67445
|
+
requests: [requests[0]],
|
|
67446
|
+
};
|
|
67447
|
+
for (let i = 1; i < requests.length; i++) {
|
|
67448
|
+
const req = requests[i];
|
|
67449
|
+
const gap = req.offset - current.end;
|
|
67450
|
+
const newEnd = Math.max(current.end, req.offset + req.length);
|
|
67451
|
+
const projectedSize = newEnd - current.start;
|
|
67452
|
+
if (gap <= MAX_GAP && projectedSize <= MAX_CHUNK) {
|
|
67453
|
+
current.end = newEnd;
|
|
67454
|
+
current.requests.push(req);
|
|
67455
|
+
} else {
|
|
67456
|
+
mergedRanges.push(current);
|
|
67457
|
+
current = {
|
|
67458
|
+
start: req.offset,
|
|
67459
|
+
end: req.offset + req.length,
|
|
67460
|
+
requests: [req],
|
|
67461
|
+
};
|
|
67462
|
+
}
|
|
67446
67463
|
}
|
|
67447
|
-
|
|
67448
|
-
|
|
67449
|
-
|
|
67450
|
-
|
|
67451
|
-
|
|
67452
|
-
|
|
67453
|
-
let
|
|
67454
|
-
|
|
67455
|
-
|
|
67456
|
-
|
|
67457
|
-
|
|
67464
|
+
mergedRanges.push(current);
|
|
67465
|
+
const finalRanges = [];
|
|
67466
|
+
for (const range of mergedRanges) {
|
|
67467
|
+
let { start, end, requests } = range;
|
|
67468
|
+
while (end - start > MAX_CHUNK) {
|
|
67469
|
+
let splitIdx = 0;
|
|
67470
|
+
for (let i = 0; i < requests.length; i++) {
|
|
67471
|
+
if (requests[i].offset + requests[i].length - start > MAX_CHUNK) {
|
|
67472
|
+
break;
|
|
67473
|
+
}
|
|
67474
|
+
splitIdx = i;
|
|
67475
|
+
}
|
|
67476
|
+
const chunkRequests = requests.slice(0, splitIdx + 1);
|
|
67477
|
+
const chunkEnd =
|
|
67478
|
+
chunkRequests[chunkRequests.length - 1].offset + chunkRequests[chunkRequests.length - 1].length;
|
|
67479
|
+
finalRanges.push({
|
|
67480
|
+
start,
|
|
67481
|
+
end: chunkEnd,
|
|
67482
|
+
requests: chunkRequests,
|
|
67458
67483
|
});
|
|
67484
|
+
requests = requests.slice(splitIdx + 1);
|
|
67485
|
+
if (requests.length > 0) {
|
|
67486
|
+
start = requests[0].offset;
|
|
67487
|
+
end = requests[0].offset + requests[0].length;
|
|
67488
|
+
for (let i = 1; i < requests.length; i++) {
|
|
67489
|
+
end = Math.max(end, requests[i].offset + requests[i].length);
|
|
67490
|
+
}
|
|
67491
|
+
}
|
|
67492
|
+
}
|
|
67493
|
+
if (requests.length > 0) {
|
|
67494
|
+
finalRanges.push({ start, end, requests });
|
|
67459
67495
|
}
|
|
67460
|
-
} catch (error) {
|
|
67461
|
-
console.error("Error processing batch:", error);
|
|
67462
|
-
currentBatch.forEach((request) => request.reject(error));
|
|
67463
67496
|
}
|
|
67464
|
-
|
|
67465
|
-
|
|
67466
|
-
|
|
67497
|
+
/*
|
|
67498
|
+
for (const range of finalRanges) {
|
|
67499
|
+
const length = range.end - range.start;
|
|
67500
|
+
const buffer = await this.loadController.loadBinaryData([
|
|
67501
|
+
{ offset: range.start, length: length }
|
|
67502
|
+
]);
|
|
67503
|
+
for (const req of range.requests) {
|
|
67504
|
+
const relOffset = req.offset - range.start;
|
|
67505
|
+
try {
|
|
67506
|
+
req._resolve({ buffer, relOffset, length: req.length });
|
|
67507
|
+
} catch (e) {
|
|
67508
|
+
req._reject(e);
|
|
67509
|
+
}
|
|
67510
|
+
}
|
|
67467
67511
|
}
|
|
67512
|
+
*/
|
|
67513
|
+
|
|
67514
|
+
const promises = finalRanges.map(async (range) => {
|
|
67515
|
+
const length = range.end - range.start;
|
|
67516
|
+
const buffer = await this.loadController.loadBinaryData([{ offset: range.start, length }]);
|
|
67517
|
+
for (const req of range.requests) {
|
|
67518
|
+
const relOffset = req.offset - range.start;
|
|
67519
|
+
try {
|
|
67520
|
+
req._resolve({ buffer, relOffset, length: req.length });
|
|
67521
|
+
} catch (e) {
|
|
67522
|
+
req._reject(e);
|
|
67523
|
+
}
|
|
67524
|
+
}
|
|
67525
|
+
});
|
|
67526
|
+
await Promise.all(promises);
|
|
67527
|
+
|
|
67528
|
+
this.pendingRequests = [];
|
|
67468
67529
|
}
|
|
67469
67530
|
|
|
67470
67531
|
getBufferView(byteOffset, byteLength, componentType) {
|
|
@@ -67477,12 +67538,10 @@ void main() {
|
|
|
67477
67538
|
|
|
67478
67539
|
createTypedArray(buffer, offset, length, componentType) {
|
|
67479
67540
|
try {
|
|
67480
|
-
// Validate parameters
|
|
67481
67541
|
if (!buffer || !(buffer instanceof ArrayBuffer)) {
|
|
67482
67542
|
throw new Error("Invalid buffer");
|
|
67483
67543
|
}
|
|
67484
67544
|
|
|
67485
|
-
// Calculate element size for given type
|
|
67486
67545
|
let elementSize;
|
|
67487
67546
|
switch (componentType) {
|
|
67488
67547
|
case 5120:
|
|
@@ -67501,18 +67560,15 @@ void main() {
|
|
|
67501
67560
|
throw new Error(`Unsupported component type: ${componentType}`);
|
|
67502
67561
|
}
|
|
67503
67562
|
|
|
67504
|
-
// Check if requested length is correct
|
|
67505
67563
|
const numElements = length / elementSize;
|
|
67506
67564
|
if (!Number.isInteger(numElements)) {
|
|
67507
67565
|
throw new Error(`Invalid length ${length} for component type ${componentType}`);
|
|
67508
67566
|
}
|
|
67509
67567
|
|
|
67510
|
-
// Check if buffer is large enough
|
|
67511
67568
|
if (length > buffer.byteLength) {
|
|
67512
67569
|
throw new Error(`Buffer too small: need ${length} bytes, but buffer is ${buffer.byteLength} bytes`);
|
|
67513
67570
|
}
|
|
67514
67571
|
|
|
67515
|
-
// Create appropriate typed array
|
|
67516
67572
|
const ArrayType = GL_COMPONENT_TYPES[componentType];
|
|
67517
67573
|
return new ArrayType(buffer, offset, numElements);
|
|
67518
67574
|
} catch (error) {
|
|
@@ -67609,7 +67665,6 @@ void main() {
|
|
|
67609
67665
|
const image = this.json.images[imageIndex];
|
|
67610
67666
|
|
|
67611
67667
|
if (image.uri) {
|
|
67612
|
-
// Handle base64 or URL
|
|
67613
67668
|
if (image.uri.startsWith("data:")) {
|
|
67614
67669
|
return await this.textureLoader.loadAsync(image.uri);
|
|
67615
67670
|
} else {
|
|
@@ -67617,23 +67672,17 @@ void main() {
|
|
|
67617
67672
|
return await this.textureLoader.loadAsync(fullUrl);
|
|
67618
67673
|
}
|
|
67619
67674
|
} else if (image.bufferView !== undefined) {
|
|
67620
|
-
// Handle embedded binary data
|
|
67621
67675
|
const bufferView = this.json.bufferViews[image.bufferView];
|
|
67622
|
-
const array = await this.getBufferView(
|
|
67623
|
-
bufferView.byteOffset || 0,
|
|
67624
|
-
bufferView.byteLength,
|
|
67625
|
-
5121 // UNSIGNED_BYTE
|
|
67626
|
-
);
|
|
67676
|
+
const array = await this.getBufferView(bufferView.byteOffset || 0, bufferView.byteLength, 5121);
|
|
67627
67677
|
const blob = new Blob([array], { type: image.mimeType });
|
|
67628
67678
|
const url = URL.createObjectURL(blob);
|
|
67629
67679
|
const texture = await this.textureLoader.loadAsync(url);
|
|
67630
67680
|
URL.revokeObjectURL(url);
|
|
67631
|
-
texture.flipY = false;
|
|
67681
|
+
texture.flipY = false;
|
|
67632
67682
|
return texture;
|
|
67633
67683
|
}
|
|
67634
67684
|
};
|
|
67635
67685
|
|
|
67636
|
-
// Load all textures
|
|
67637
67686
|
const texturePromises = [];
|
|
67638
67687
|
for (let i = 0; i < this.json.textures.length; i++) {
|
|
67639
67688
|
texturePromises.push(
|
|
@@ -67643,82 +67692,56 @@ void main() {
|
|
|
67643
67692
|
await Promise.all(texturePromises);
|
|
67644
67693
|
}
|
|
67645
67694
|
|
|
67646
|
-
loadMaterials() {
|
|
67695
|
+
async loadMaterials() {
|
|
67647
67696
|
if (!this.json.materials) return this.materials;
|
|
67648
67697
|
|
|
67649
67698
|
for (let i = 0; i < this.json.materials.length; i++) {
|
|
67650
67699
|
const materialDef = this.json.materials[i];
|
|
67651
|
-
const material = this.createMaterial(materialDef);
|
|
67700
|
+
const material = await this.createMaterial(materialDef);
|
|
67701
|
+
material.name = materialDef.name;
|
|
67652
67702
|
this.materials.set(i, material);
|
|
67653
67703
|
}
|
|
67654
67704
|
return this.materials;
|
|
67655
67705
|
}
|
|
67656
67706
|
|
|
67657
67707
|
createMaterial(materialDef) {
|
|
67658
|
-
const
|
|
67708
|
+
const params = {};
|
|
67659
67709
|
|
|
67660
|
-
// Base color
|
|
67661
67710
|
if (materialDef.pbrMetallicRoughness) {
|
|
67662
67711
|
const pbr = materialDef.pbrMetallicRoughness;
|
|
67663
|
-
|
|
67664
67712
|
if (pbr.baseColorFactor) {
|
|
67665
|
-
|
|
67666
|
-
|
|
67713
|
+
params.color = new Color().fromArray(pbr.baseColorFactor);
|
|
67714
|
+
params.opacity = pbr.baseColorFactor[3];
|
|
67715
|
+
if (params.opacity < 1.0) params.transparent = true;
|
|
67667
67716
|
}
|
|
67668
|
-
|
|
67669
67717
|
if (pbr.baseColorTexture) {
|
|
67670
|
-
|
|
67671
|
-
}
|
|
67672
|
-
|
|
67673
|
-
// Metallic and roughness
|
|
67674
|
-
if (pbr.metallicFactor !== undefined) {
|
|
67675
|
-
material.metalness = pbr.metallicFactor;
|
|
67676
|
-
}
|
|
67677
|
-
if (pbr.roughnessFactor !== undefined) {
|
|
67678
|
-
material.roughness = pbr.roughnessFactor;
|
|
67679
|
-
}
|
|
67680
|
-
if (pbr.metallicRoughnessTexture) {
|
|
67681
|
-
material.metalnessMap = this.textureCache.get(pbr.metallicRoughnessTexture.index);
|
|
67682
|
-
material.roughnessMap = material.metalnessMap;
|
|
67718
|
+
params.map = this.textureCache.get(pbr.baseColorTexture.index);
|
|
67683
67719
|
}
|
|
67684
67720
|
}
|
|
67685
67721
|
|
|
67686
|
-
|
|
67687
|
-
|
|
67688
|
-
|
|
67689
|
-
|
|
67690
|
-
|
|
67691
|
-
|
|
67692
|
-
}
|
|
67722
|
+
params.specular = 0x222222;
|
|
67723
|
+
params.shininess = 10;
|
|
67724
|
+
params.reflectivity = 0.05;
|
|
67725
|
+
params.polygonOffset = true;
|
|
67726
|
+
params.polygonOffsetFactor = 1;
|
|
67727
|
+
params.polygonOffsetUnits = 1;
|
|
67693
67728
|
|
|
67694
|
-
// Emissive
|
|
67695
67729
|
if (materialDef.emissiveFactor) {
|
|
67696
|
-
|
|
67697
|
-
}
|
|
67698
|
-
if (materialDef.emissiveTexture) {
|
|
67699
|
-
material.emissiveMap = this.textureCache.get(materialDef.emissiveTexture.index);
|
|
67730
|
+
params.emissive = new Color().fromArray(materialDef.emissiveFactor);
|
|
67700
67731
|
}
|
|
67701
67732
|
|
|
67702
|
-
|
|
67703
|
-
|
|
67704
|
-
material.aoMap = this.textureCache.get(materialDef.occlusionTexture.index);
|
|
67705
|
-
if (materialDef.occlusionTexture.strength !== undefined) {
|
|
67706
|
-
material.aoMapIntensity = materialDef.occlusionTexture.strength;
|
|
67707
|
-
}
|
|
67733
|
+
if (materialDef.normalTexture) {
|
|
67734
|
+
params.normalMap = this.textureCache.get(materialDef.normalTexture.index);
|
|
67708
67735
|
}
|
|
67709
67736
|
|
|
67710
|
-
// Alpha mode
|
|
67711
67737
|
if (materialDef.alphaMode === "BLEND") {
|
|
67712
|
-
|
|
67713
|
-
} else if (materialDef.alphaMode === "MASK") {
|
|
67714
|
-
material.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5;
|
|
67738
|
+
params.transparent = true;
|
|
67715
67739
|
}
|
|
67716
67740
|
|
|
67717
|
-
|
|
67718
|
-
|
|
67719
|
-
|
|
67720
|
-
material
|
|
67721
|
-
|
|
67741
|
+
if (materialDef.doubleSided) {
|
|
67742
|
+
params.side = DoubleSide;
|
|
67743
|
+
}
|
|
67744
|
+
const material = new MeshPhongMaterial(params);
|
|
67722
67745
|
return material;
|
|
67723
67746
|
}
|
|
67724
67747
|
|
|
@@ -67751,12 +67774,8 @@ void main() {
|
|
|
67751
67774
|
if (!meshDef || !meshDef.primitives) return 0;
|
|
67752
67775
|
|
|
67753
67776
|
let totalSize = 0;
|
|
67754
|
-
|
|
67755
|
-
// Estimate size for each primitive
|
|
67756
67777
|
for (const primitive of meshDef.primitives) {
|
|
67757
|
-
// Check for attributes
|
|
67758
67778
|
if (primitive.attributes) {
|
|
67759
|
-
// Calculate attributes size
|
|
67760
67779
|
for (const [, accessorIndex] of Object.entries(primitive.attributes)) {
|
|
67761
67780
|
if (accessorIndex === undefined) continue;
|
|
67762
67781
|
|
|
@@ -67769,7 +67788,6 @@ void main() {
|
|
|
67769
67788
|
}
|
|
67770
67789
|
}
|
|
67771
67790
|
|
|
67772
|
-
// Calculate indices size if present
|
|
67773
67791
|
if (primitive.indices !== undefined) {
|
|
67774
67792
|
const accessor = this.json.accessors[primitive.indices];
|
|
67775
67793
|
if (accessor) {
|
|
@@ -67842,7 +67860,9 @@ void main() {
|
|
|
67842
67860
|
this.mergedPoints = new Set();
|
|
67843
67861
|
|
|
67844
67862
|
this.isolatedObjects = [];
|
|
67845
|
-
|
|
67863
|
+
//!!window.WebGL2RenderingContext && this.renderer.getContext() instanceof WebGL2RenderingContext
|
|
67864
|
+
this.useVAO = false;
|
|
67865
|
+
this.visibleEdges = true;
|
|
67846
67866
|
|
|
67847
67867
|
this.handleToOptimizedObjects = new Map();
|
|
67848
67868
|
|
|
@@ -67851,6 +67871,10 @@ void main() {
|
|
|
67851
67871
|
this.oldOptimizeObjects = new Set();
|
|
67852
67872
|
}
|
|
67853
67873
|
|
|
67874
|
+
setVisibleEdges(visible) {
|
|
67875
|
+
this.visibleEdges = visible;
|
|
67876
|
+
}
|
|
67877
|
+
|
|
67854
67878
|
getAvailableMemory() {
|
|
67855
67879
|
let memoryLimit = 6 * 1024 * 1024 * 1024;
|
|
67856
67880
|
try {
|
|
@@ -67871,7 +67895,7 @@ void main() {
|
|
|
67871
67895
|
console.warn("Error detecting available memory:", error);
|
|
67872
67896
|
}
|
|
67873
67897
|
|
|
67874
|
-
return memoryLimit;
|
|
67898
|
+
return memoryLimit / 3;
|
|
67875
67899
|
}
|
|
67876
67900
|
|
|
67877
67901
|
getAbortController() {
|
|
@@ -67976,7 +68000,7 @@ void main() {
|
|
|
67976
68000
|
console.log(`Final memory usage: ${Math.round(currentMemoryUsage / (1024 * 1024))}MB`);
|
|
67977
68001
|
}
|
|
67978
68002
|
|
|
67979
|
-
async loadNode(nodeId) {
|
|
68003
|
+
async loadNode(nodeId, onLoadFinishCb) {
|
|
67980
68004
|
const node = this.nodes.get(nodeId);
|
|
67981
68005
|
if (!node || node.loaded || node.loading) return;
|
|
67982
68006
|
|
|
@@ -67984,38 +68008,138 @@ void main() {
|
|
|
67984
68008
|
const meshDef = node.structure.getJson().meshes[node.meshIndex];
|
|
67985
68009
|
|
|
67986
68010
|
try {
|
|
67987
|
-
|
|
67988
|
-
|
|
67989
|
-
|
|
67990
|
-
const
|
|
67991
|
-
|
|
67992
|
-
|
|
68011
|
+
const bufferRequests = [];
|
|
68012
|
+
const primitiveReqMap = new Map();
|
|
68013
|
+
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
68014
|
+
const primitive = meshDef.primitives[primIdx];
|
|
68015
|
+
const reqs = [];
|
|
68016
|
+
|
|
68017
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
68018
|
+
const accessorIndex = primitive.attributes.POSITION;
|
|
68019
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
68020
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
68021
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
68022
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68023
|
+
const count = accessor.count;
|
|
68024
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
68025
|
+
reqs.push({
|
|
68026
|
+
offset: byteOffset,
|
|
68027
|
+
length: byteLength,
|
|
68028
|
+
componentType: accessor.componentType,
|
|
68029
|
+
accessorIndex,
|
|
68030
|
+
type: "position",
|
|
68031
|
+
primIdx,
|
|
68032
|
+
});
|
|
68033
|
+
}
|
|
67993
68034
|
|
|
67994
68035
|
if (primitive.attributes.NORMAL !== undefined) {
|
|
67995
|
-
|
|
68036
|
+
const accessorIndex = primitive.attributes.NORMAL;
|
|
68037
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
68038
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
68039
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
68040
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68041
|
+
const count = accessor.count;
|
|
68042
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
68043
|
+
reqs.push({
|
|
68044
|
+
offset: byteOffset,
|
|
68045
|
+
length: byteLength,
|
|
68046
|
+
componentType: accessor.componentType,
|
|
68047
|
+
accessorIndex,
|
|
68048
|
+
type: "normal",
|
|
68049
|
+
primIdx,
|
|
68050
|
+
});
|
|
67996
68051
|
}
|
|
67997
68052
|
|
|
67998
68053
|
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
67999
|
-
|
|
68054
|
+
const accessorIndex = primitive.attributes.TEXCOORD_0;
|
|
68055
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
68056
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
68057
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
68058
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68059
|
+
const count = accessor.count;
|
|
68060
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
68061
|
+
reqs.push({
|
|
68062
|
+
offset: byteOffset,
|
|
68063
|
+
length: byteLength,
|
|
68064
|
+
componentType: accessor.componentType,
|
|
68065
|
+
accessorIndex,
|
|
68066
|
+
type: "uv",
|
|
68067
|
+
primIdx,
|
|
68068
|
+
});
|
|
68069
|
+
}
|
|
68070
|
+
|
|
68071
|
+
if (primitive.indices !== undefined) {
|
|
68072
|
+
const accessorIndex = primitive.indices;
|
|
68073
|
+
const accessor = node.structure.json.accessors[accessorIndex];
|
|
68074
|
+
const bufferView = node.structure.json.bufferViews[accessor.bufferView];
|
|
68075
|
+
const byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0);
|
|
68076
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68077
|
+
const count = accessor.count;
|
|
68078
|
+
const byteLength = count * components * node.structure.getComponentSize(accessor.componentType);
|
|
68079
|
+
reqs.push({
|
|
68080
|
+
offset: byteOffset,
|
|
68081
|
+
length: byteLength,
|
|
68082
|
+
componentType: accessor.componentType,
|
|
68083
|
+
accessorIndex,
|
|
68084
|
+
type: "index",
|
|
68085
|
+
primIdx,
|
|
68086
|
+
});
|
|
68000
68087
|
}
|
|
68088
|
+
primitiveReqMap.set(primIdx, reqs);
|
|
68089
|
+
bufferRequests.push(...reqs);
|
|
68090
|
+
}
|
|
68001
68091
|
|
|
68002
|
-
|
|
68003
|
-
|
|
68004
|
-
|
|
68005
|
-
|
|
68006
|
-
|
|
68007
|
-
|
|
68092
|
+
if (bufferRequests.length === 0) {
|
|
68093
|
+
node.loaded = true;
|
|
68094
|
+
node.loading = false;
|
|
68095
|
+
return;
|
|
68096
|
+
}
|
|
68097
|
+
bufferRequests.sort((a, b) => a.offset - b.offset);
|
|
68098
|
+
const minOffset = bufferRequests[0].offset;
|
|
68099
|
+
const maxOffset = Math.max(...bufferRequests.map((r) => r.offset + r.length));
|
|
68100
|
+
const totalLength = maxOffset - minOffset;
|
|
68101
|
+
|
|
68102
|
+
const { buffer, relOffset: baseRelOffset } = await node.structure.scheduleRequest({
|
|
68103
|
+
offset: minOffset,
|
|
68104
|
+
length: totalLength,
|
|
68105
|
+
componentType: null,
|
|
68106
|
+
});
|
|
68008
68107
|
|
|
68009
|
-
|
|
68010
|
-
|
|
68011
|
-
|
|
68108
|
+
for (const req of bufferRequests) {
|
|
68109
|
+
const relOffset = req.offset - minOffset;
|
|
68110
|
+
req.data = node.structure.createTypedArray(buffer, baseRelOffset + relOffset, req.length, req.componentType);
|
|
68111
|
+
}
|
|
68012
68112
|
|
|
68013
|
-
|
|
68014
|
-
|
|
68015
|
-
|
|
68113
|
+
for (let primIdx = 0; primIdx < meshDef.primitives.length; primIdx++) {
|
|
68114
|
+
const primitive = meshDef.primitives[primIdx];
|
|
68115
|
+
const geometry = new BufferGeometry();
|
|
68116
|
+
const reqs = primitiveReqMap.get(primIdx);
|
|
68117
|
+
|
|
68118
|
+
if (primitive.attributes.POSITION !== undefined) {
|
|
68119
|
+
const req = reqs.find((r) => r.type === "position" && r.accessorIndex === primitive.attributes.POSITION);
|
|
68120
|
+
const accessor = node.structure.json.accessors[primitive.attributes.POSITION];
|
|
68121
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68122
|
+
geometry.setAttribute("position", new BufferAttribute(req.data, components));
|
|
68016
68123
|
}
|
|
68017
68124
|
|
|
68018
|
-
|
|
68125
|
+
if (primitive.attributes.NORMAL !== undefined) {
|
|
68126
|
+
const req = reqs.find((r) => r.type === "normal" && r.accessorIndex === primitive.attributes.NORMAL);
|
|
68127
|
+
const accessor = node.structure.json.accessors[primitive.attributes.NORMAL];
|
|
68128
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68129
|
+
geometry.setAttribute("normal", new BufferAttribute(req.data, components));
|
|
68130
|
+
}
|
|
68131
|
+
|
|
68132
|
+
if (primitive.attributes.TEXCOORD_0 !== undefined) {
|
|
68133
|
+
const req = reqs.find((r) => r.type === "uv" && r.accessorIndex === primitive.attributes.TEXCOORD_0);
|
|
68134
|
+
const accessor = node.structure.json.accessors[primitive.attributes.TEXCOORD_0];
|
|
68135
|
+
const components = node.structure.getNumComponents(accessor.type);
|
|
68136
|
+
geometry.setAttribute("uv", new BufferAttribute(req.data, components));
|
|
68137
|
+
}
|
|
68138
|
+
|
|
68139
|
+
if (primitive.indices !== undefined) {
|
|
68140
|
+
const req = reqs.find((r) => r.type === "index" && r.accessorIndex === primitive.indices);
|
|
68141
|
+
geometry.setIndex(new BufferAttribute(req.data, 1));
|
|
68142
|
+
}
|
|
68019
68143
|
|
|
68020
68144
|
let material;
|
|
68021
68145
|
if (primitive.material !== undefined) {
|
|
@@ -68030,8 +68154,7 @@ void main() {
|
|
|
68030
68154
|
Material.prototype.copy.call(pointsMaterial, material);
|
|
68031
68155
|
pointsMaterial.color.copy(material.color);
|
|
68032
68156
|
pointsMaterial.map = material.map;
|
|
68033
|
-
pointsMaterial.sizeAttenuation = false;
|
|
68034
|
-
|
|
68157
|
+
pointsMaterial.sizeAttenuation = false;
|
|
68035
68158
|
mesh = new Points(geometry, pointsMaterial);
|
|
68036
68159
|
} else if (
|
|
68037
68160
|
primitive.mode === GL_CONSTANTS.TRIANGLES ||
|
|
@@ -68040,7 +68163,6 @@ void main() {
|
|
|
68040
68163
|
primitive.mode === undefined
|
|
68041
68164
|
) {
|
|
68042
68165
|
mesh = new Mesh(geometry, material);
|
|
68043
|
-
|
|
68044
68166
|
if (primitive.mode === GL_CONSTANTS.TRIANGLE_STRIP) {
|
|
68045
68167
|
mesh.drawMode = TriangleStripDrawMode;
|
|
68046
68168
|
} else if (primitive.mode === GL_CONSTANTS.TRIANGLE_FAN) {
|
|
@@ -68053,39 +68175,30 @@ void main() {
|
|
|
68053
68175
|
} else if (primitive.mode === GL_CONSTANTS.LINE_LOOP) {
|
|
68054
68176
|
mesh = new LineLoop(geometry, material);
|
|
68055
68177
|
}
|
|
68056
|
-
|
|
68057
68178
|
if (node.extras) {
|
|
68058
68179
|
mesh.userData = { ...mesh.userData, ...node.extras };
|
|
68059
68180
|
}
|
|
68060
|
-
|
|
68061
68181
|
if (meshDef.extras) {
|
|
68062
68182
|
mesh.userData = { ...mesh.userData, ...meshDef.extras };
|
|
68063
68183
|
}
|
|
68064
|
-
|
|
68065
68184
|
if (primitive.extras) {
|
|
68066
68185
|
mesh.userData = { ...mesh.userData, ...primitive.extras };
|
|
68067
68186
|
}
|
|
68068
|
-
|
|
68069
68187
|
if (node.handle) {
|
|
68070
68188
|
mesh.userData.handle = node.handle;
|
|
68071
68189
|
} else {
|
|
68072
68190
|
mesh.userData.handle = `${node.structure.id}_${mesh.userData.handle}`;
|
|
68073
68191
|
}
|
|
68074
|
-
|
|
68075
68192
|
if (mesh.material.name === "edges") {
|
|
68076
68193
|
mesh.userData.isEdge = true;
|
|
68077
68194
|
} else {
|
|
68078
68195
|
mesh.userData.isEdge = false;
|
|
68079
68196
|
}
|
|
68080
|
-
|
|
68081
68197
|
this.registerObjectWithHandle(mesh, mesh.userData.handle);
|
|
68082
|
-
|
|
68083
68198
|
mesh.position.copy(node.position);
|
|
68084
|
-
|
|
68085
68199
|
if (!geometry.attributes.normal) {
|
|
68086
68200
|
geometry.computeVertexNormals();
|
|
68087
68201
|
}
|
|
68088
|
-
|
|
68089
68202
|
if (material.aoMap && geometry.attributes.uv) {
|
|
68090
68203
|
geometry.setAttribute("uv2", geometry.attributes.uv);
|
|
68091
68204
|
}
|
|
@@ -68095,17 +68208,17 @@ void main() {
|
|
|
68095
68208
|
this.scene.add(mesh);
|
|
68096
68209
|
}
|
|
68097
68210
|
node.object = mesh;
|
|
68098
|
-
|
|
68099
68211
|
this.totalLoadedObjects++;
|
|
68100
68212
|
mesh.visible = this.totalLoadedObjects < this.graphicsObjectLimit;
|
|
68101
68213
|
}
|
|
68102
|
-
|
|
68103
68214
|
node.loaded = true;
|
|
68104
68215
|
node.loading = false;
|
|
68105
|
-
|
|
68106
68216
|
const geometrySize = this.estimateGeometrySize(node.object);
|
|
68107
68217
|
this.geometryCache.set(node.object.uuid, geometrySize);
|
|
68108
68218
|
this.currentMemoryUsage += geometrySize;
|
|
68219
|
+
if (onLoadFinishCb) {
|
|
68220
|
+
onLoadFinishCb();
|
|
68221
|
+
}
|
|
68109
68222
|
} catch (error) {
|
|
68110
68223
|
if (error.name !== "AbortError") {
|
|
68111
68224
|
console.error(`Error loading node ${nodeId}:`, error);
|
|
@@ -68230,7 +68343,7 @@ void main() {
|
|
|
68230
68343
|
return volumeB - volumeA;
|
|
68231
68344
|
});
|
|
68232
68345
|
|
|
68233
|
-
if (!ignoreEdges) {
|
|
68346
|
+
if (!ignoreEdges && this.visibleEdges) {
|
|
68234
68347
|
this.nodesToLoad.push(...this.edgeNodes);
|
|
68235
68348
|
}
|
|
68236
68349
|
|
|
@@ -68357,33 +68470,13 @@ void main() {
|
|
|
68357
68470
|
async processNodes() {
|
|
68358
68471
|
const nodesToLoad = this.nodesToLoad;
|
|
68359
68472
|
let loadedCount = 0;
|
|
68473
|
+
let lastLoadedCount = 0;
|
|
68360
68474
|
const totalNodes = nodesToLoad.length;
|
|
68361
68475
|
|
|
68362
|
-
|
|
68363
|
-
|
|
68364
|
-
|
|
68365
|
-
|
|
68366
|
-
|
|
68367
|
-
for (const nodeId of batch) {
|
|
68368
|
-
if (this.abortController.signal.aborted) {
|
|
68369
|
-
throw new DOMException("Loading aborted", "AbortError");
|
|
68370
|
-
}
|
|
68371
|
-
|
|
68372
|
-
const estimatedSize = await this.estimateNodeSize(nodeId);
|
|
68373
|
-
|
|
68374
|
-
if (this.currentMemoryUsage + estimatedSize > this.memoryLimit) {
|
|
68375
|
-
console.log(`Memory limit reached after loading ${loadedCount} nodes`);
|
|
68376
|
-
this.dispatchEvent("geometryerror", { message: "Memory limit reached" });
|
|
68377
|
-
this.dispatchEvent("update");
|
|
68378
|
-
return loadedCount;
|
|
68379
|
-
}
|
|
68380
|
-
|
|
68381
|
-
batchPromises.push(this.loadNode(nodeId));
|
|
68382
|
-
}
|
|
68383
|
-
|
|
68384
|
-
await Promise.all(batchPromises);
|
|
68385
|
-
loadedCount += batch.length;
|
|
68386
|
-
|
|
68476
|
+
const loadProgress = async () => {
|
|
68477
|
+
loadedCount++;
|
|
68478
|
+
if (loadedCount - lastLoadedCount > 1000) {
|
|
68479
|
+
lastLoadedCount = loadedCount;
|
|
68387
68480
|
this.updateMemoryIndicator();
|
|
68388
68481
|
this.dispatchEvent("geometryprogress", {
|
|
68389
68482
|
percentage: Math.round((loadedCount / totalNodes) * 100),
|
|
@@ -68401,6 +68494,34 @@ void main() {
|
|
|
68401
68494
|
setTimeout(resolve, 0);
|
|
68402
68495
|
});
|
|
68403
68496
|
}
|
|
68497
|
+
};
|
|
68498
|
+
|
|
68499
|
+
try {
|
|
68500
|
+
const loadOperations = [];
|
|
68501
|
+
for (const nodeId of nodesToLoad) {
|
|
68502
|
+
if (this.abortController.signal.aborted) {
|
|
68503
|
+
throw new DOMException("Loading aborted", "AbortError");
|
|
68504
|
+
}
|
|
68505
|
+
|
|
68506
|
+
const estimatedSize = await this.estimateNodeSize(nodeId);
|
|
68507
|
+
|
|
68508
|
+
if (this.currentMemoryUsage + estimatedSize > this.memoryLimit) {
|
|
68509
|
+
console.log(`Memory limit reached after loading ${loadedCount} nodes`);
|
|
68510
|
+
this.dispatchEvent("geometryerror", {
|
|
68511
|
+
message: "Memory limit reached",
|
|
68512
|
+
});
|
|
68513
|
+
this.dispatchEvent("update");
|
|
68514
|
+
return loadedCount;
|
|
68515
|
+
}
|
|
68516
|
+
|
|
68517
|
+
loadOperations.push(this.loadNode(nodeId, loadProgress));
|
|
68518
|
+
}
|
|
68519
|
+
|
|
68520
|
+
for (const structure of this.structures) {
|
|
68521
|
+
loadOperations.push(structure.flushBufferRequests());
|
|
68522
|
+
}
|
|
68523
|
+
|
|
68524
|
+
await Promise.all(loadOperations);
|
|
68404
68525
|
|
|
68405
68526
|
this.dispatchEvent("geometryend", {
|
|
68406
68527
|
totalLoaded: loadedCount,
|
|
@@ -69381,6 +69502,25 @@ void main() {
|
|
|
69381
69502
|
}
|
|
69382
69503
|
});
|
|
69383
69504
|
}
|
|
69505
|
+
|
|
69506
|
+
// Возвращает bounding box для конкретной структуры
|
|
69507
|
+
getStructureGeometryExtent(structureId) {
|
|
69508
|
+
const extent = new Box3();
|
|
69509
|
+
for (const [nodeId, node] of this.nodes.entries()) {
|
|
69510
|
+
if (!node.geometryExtents) continue;
|
|
69511
|
+
if (!nodeId.startsWith(structureId + "_")) continue;
|
|
69512
|
+
if (node.object && this.hiddenHandles && this.hiddenHandles.has(node.object.userData.handle)) continue;
|
|
69513
|
+
const transformedBox = node.geometryExtents.clone();
|
|
69514
|
+
if (node.group && node.group.matrix) {
|
|
69515
|
+
transformedBox.applyMatrix4(node.group.matrix);
|
|
69516
|
+
if (node.group.parent && node.group.parent.matrix) {
|
|
69517
|
+
transformedBox.applyMatrix4(node.group.parent.matrix);
|
|
69518
|
+
}
|
|
69519
|
+
}
|
|
69520
|
+
extent.union(transformedBox);
|
|
69521
|
+
}
|
|
69522
|
+
return extent;
|
|
69523
|
+
}
|
|
69384
69524
|
}
|
|
69385
69525
|
|
|
69386
69526
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -69409,7 +69549,6 @@ void main() {
|
|
|
69409
69549
|
constructor(viewer) {
|
|
69410
69550
|
this.requestId = 0;
|
|
69411
69551
|
this.viewer = viewer;
|
|
69412
|
-
this.scene = new Group$1();
|
|
69413
69552
|
}
|
|
69414
69553
|
dispose() {
|
|
69415
69554
|
if (this.gltfLoader)
|
|
@@ -69423,27 +69562,25 @@ void main() {
|
|
|
69423
69562
|
/.gltf$/i.test(file.database));
|
|
69424
69563
|
}
|
|
69425
69564
|
async load(model, format, params) {
|
|
69426
|
-
|
|
69565
|
+
const scene = new Group$1();
|
|
69566
|
+
this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
|
|
69427
69567
|
this.gltfLoader.memoryLimit = this.viewer.options.memoryLimit;
|
|
69428
69568
|
this.gltfLoader.addEventListener("databasechunk", (data) => {
|
|
69429
|
-
const modelImpl = new DynamicModelImpl(
|
|
69569
|
+
const modelImpl = new DynamicModelImpl(scene);
|
|
69430
69570
|
modelImpl.loader = this;
|
|
69431
69571
|
modelImpl.gltfLoader = this.gltfLoader;
|
|
69432
69572
|
modelImpl.viewer = this.viewer;
|
|
69433
|
-
this.viewer.scene.add(
|
|
69573
|
+
this.viewer.scene.add(scene);
|
|
69434
69574
|
this.viewer.models.push(modelImpl);
|
|
69435
69575
|
this.viewer.syncOptions();
|
|
69436
69576
|
this.viewer.syncOverlay();
|
|
69437
69577
|
this.viewer.update();
|
|
69438
|
-
this.viewer.emitEvent({ type: "databasechunk", data, file: model.file, model });
|
|
69578
|
+
this.viewer.emitEvent({ type: "databasechunk", data: scene, file: model.file, model });
|
|
69439
69579
|
});
|
|
69440
69580
|
this.gltfLoader.addEventListener("geometryprogress", (data) => {
|
|
69441
69581
|
const progress = data.loaded / data.total;
|
|
69442
69582
|
this.viewer.emitEvent({ type: "geometryprogress", data: progress, file: model.file, model });
|
|
69443
69583
|
});
|
|
69444
|
-
this.gltfLoader.addEventListener("geometrymemory", (data) => {
|
|
69445
|
-
this.viewer.emit({ type: "geometryprogress", data });
|
|
69446
|
-
});
|
|
69447
69584
|
this.gltfLoader.addEventListener("geometryerror", (data) => {
|
|
69448
69585
|
this.viewer.emitEvent({ type: "geometryerror", data, file: model.file, model });
|
|
69449
69586
|
});
|
|
@@ -69477,9 +69614,8 @@ void main() {
|
|
|
69477
69614
|
return this;
|
|
69478
69615
|
}
|
|
69479
69616
|
cancel() {
|
|
69480
|
-
if (this.gltfLoader)
|
|
69617
|
+
if (this.gltfLoader)
|
|
69481
69618
|
this.gltfLoader.abortLoading();
|
|
69482
|
-
}
|
|
69483
69619
|
}
|
|
69484
69620
|
}
|
|
69485
69621
|
|
|
@@ -69517,7 +69653,7 @@ void main() {
|
|
|
69517
69653
|
*
|
|
69518
69654
|
* The loader should do:
|
|
69519
69655
|
*
|
|
69520
|
-
* - Load
|
|
69656
|
+
* - Load raw data from file and convert it to the `Three.js` scene.
|
|
69521
69657
|
* - Add scene to the viewer `scene`.
|
|
69522
69658
|
* - Create `ModelImpl` for the scene and to the viewer `models` list.
|
|
69523
69659
|
* - Synchronize viewer options and overlay.
|
|
@@ -81628,7 +81764,7 @@ void main() {
|
|
|
81628
81764
|
const attrs = e.target.attrs;
|
|
81629
81765
|
if (attrs.rotation !== this._ref.rotation()) this._ref.rotation(attrs.rotation);
|
|
81630
81766
|
}));
|
|
81631
|
-
this._ref.on("transformend", (
|
|
81767
|
+
this._ref.on("transformend", (() => {
|
|
81632
81768
|
const absoluteTransform = this._ref.getAbsoluteTransform();
|
|
81633
81769
|
const wcsPoints = [];
|
|
81634
81770
|
const points = this._ref.points();
|
|
@@ -81650,7 +81786,7 @@ void main() {
|
|
|
81650
81786
|
}
|
|
81651
81787
|
this._ref.setAttr("wcsPoints", wcsPoints);
|
|
81652
81788
|
}));
|
|
81653
|
-
this._ref.on("dragend", (
|
|
81789
|
+
this._ref.on("dragend", (() => {
|
|
81654
81790
|
const absoluteTransform = this._ref.getAbsoluteTransform();
|
|
81655
81791
|
const wcsPoints = [];
|
|
81656
81792
|
const points = this._ref.points();
|
|
@@ -81840,7 +81976,7 @@ void main() {
|
|
|
81840
81976
|
});
|
|
81841
81977
|
this._ref.setAttr("wcsStart", this._worldTransformer.screenToWorld(position));
|
|
81842
81978
|
}));
|
|
81843
|
-
this._ref.on("dragend", (
|
|
81979
|
+
this._ref.on("dragend", (() => {
|
|
81844
81980
|
const absoluteTransform = this._ref.getStage().getAbsoluteTransform();
|
|
81845
81981
|
const position = absoluteTransform.point({
|
|
81846
81982
|
x: this._ref.x(),
|
|
@@ -82028,7 +82164,7 @@ void main() {
|
|
|
82028
82164
|
y: position.y + this._ref.height()
|
|
82029
82165
|
}));
|
|
82030
82166
|
}));
|
|
82031
|
-
this._ref.on("dragend", (
|
|
82167
|
+
this._ref.on("dragend", (() => {
|
|
82032
82168
|
const absoluteTransform = this._ref.getStage().getAbsoluteTransform();
|
|
82033
82169
|
const position = absoluteTransform.point({
|
|
82034
82170
|
x: this._ref.x(),
|
|
@@ -82253,7 +82389,7 @@ void main() {
|
|
|
82253
82389
|
y: 1
|
|
82254
82390
|
});
|
|
82255
82391
|
}));
|
|
82256
|
-
this._ref.on("transformend", (
|
|
82392
|
+
this._ref.on("transformend", (() => {
|
|
82257
82393
|
const absoluteTransform = this._ref.getStage().getAbsoluteTransform();
|
|
82258
82394
|
const position = absoluteTransform.point({
|
|
82259
82395
|
x: this._ref.x(),
|
|
@@ -82271,7 +82407,7 @@ void main() {
|
|
|
82271
82407
|
});
|
|
82272
82408
|
this._ref.setAttr("wcsRadiusY", this._worldTransformer.screenToWorld(radiusY));
|
|
82273
82409
|
}));
|
|
82274
|
-
this._ref.on("dragend", (
|
|
82410
|
+
this._ref.on("dragend", (() => {
|
|
82275
82411
|
const absoluteTransform = this._ref.getStage().getAbsoluteTransform();
|
|
82276
82412
|
const position = absoluteTransform.point({
|
|
82277
82413
|
x: this._ref.x(),
|
|
@@ -82685,7 +82821,7 @@ void main() {
|
|
|
82685
82821
|
y: 1
|
|
82686
82822
|
});
|
|
82687
82823
|
}));
|
|
82688
|
-
this._ref.on("transformend", (
|
|
82824
|
+
this._ref.on("transformend", (() => {
|
|
82689
82825
|
const absoluteTransform = this._ref.getStage().getAbsoluteTransform();
|
|
82690
82826
|
const position = absoluteTransform.point({
|
|
82691
82827
|
x: this._ref.x(),
|
|
@@ -82697,7 +82833,7 @@ void main() {
|
|
|
82697
82833
|
y: position.y + this._ref.height()
|
|
82698
82834
|
}));
|
|
82699
82835
|
}));
|
|
82700
|
-
this._ref.on("dragend", (
|
|
82836
|
+
this._ref.on("dragend", (() => {
|
|
82701
82837
|
const absoluteTransform = this._ref.getStage().getAbsoluteTransform();
|
|
82702
82838
|
const position = absoluteTransform.point({
|
|
82703
82839
|
x: this._ref.x(),
|
|
@@ -82986,7 +83122,7 @@ void main() {
|
|
|
82986
83122
|
y: position.y + this._ref.height()
|
|
82987
83123
|
}));
|
|
82988
83124
|
}));
|
|
82989
|
-
this._ref.on("dragend", (
|
|
83125
|
+
this._ref.on("dragend", (() => {
|
|
82990
83126
|
const absoluteTransform = this._ref.getStage().getAbsoluteTransform();
|
|
82991
83127
|
const position = absoluteTransform.point({
|
|
82992
83128
|
x: this._ref.x(),
|
|
@@ -83188,12 +83324,12 @@ void main() {
|
|
|
83188
83324
|
markupObject.updateScreenCoordinates();
|
|
83189
83325
|
}));
|
|
83190
83326
|
};
|
|
83191
|
-
this.pan =
|
|
83327
|
+
this.pan = () => {
|
|
83192
83328
|
this.getObjects().forEach((markupObject => {
|
|
83193
83329
|
markupObject.updateScreenCoordinates();
|
|
83194
83330
|
}));
|
|
83195
83331
|
};
|
|
83196
|
-
this.zoomAt =
|
|
83332
|
+
this.zoomAt = () => {
|
|
83197
83333
|
this.getObjects().forEach((markupObject => {
|
|
83198
83334
|
markupObject.updateScreenCoordinates();
|
|
83199
83335
|
}));
|
|
@@ -83456,7 +83592,7 @@ void main() {
|
|
|
83456
83592
|
lastLine = this.addLine([ pos.x, pos.y, pos.x, pos.y ]);
|
|
83457
83593
|
}
|
|
83458
83594
|
}));
|
|
83459
|
-
stage.on("mouseup touchend", (
|
|
83595
|
+
stage.on("mouseup touchend", (() => {
|
|
83460
83596
|
if (!this._markupIsActive) return;
|
|
83461
83597
|
if (isPaint) {
|
|
83462
83598
|
const pos = this.getRelativePointerPosition(stage);
|
|
@@ -83498,7 +83634,7 @@ void main() {
|
|
|
83498
83634
|
lastObj = undefined;
|
|
83499
83635
|
isPaint = false;
|
|
83500
83636
|
}));
|
|
83501
|
-
stage.on("mousemove touchmove", (
|
|
83637
|
+
stage.on("mousemove touchmove", (() => {
|
|
83502
83638
|
if (!this._markupIsActive) return;
|
|
83503
83639
|
if (!isPaint) {
|
|
83504
83640
|
return;
|
|
@@ -83878,7 +84014,7 @@ void main() {
|
|
|
83878
84014
|
y: this._imageInputPos.y
|
|
83879
84015
|
}, null, base64.toString(), 0, 0);
|
|
83880
84016
|
};
|
|
83881
|
-
this._imageInputRef.oncancel =
|
|
84017
|
+
this._imageInputRef.oncancel = () => {
|
|
83882
84018
|
this.removeImageInput();
|
|
83883
84019
|
};
|
|
83884
84020
|
document.body.appendChild(this._imageInputRef);
|
|
@@ -84065,13 +84201,17 @@ void main() {
|
|
|
84065
84201
|
this.addEventListener("optionschange", (event) => this.syncOptions(event.data));
|
|
84066
84202
|
this.scene = new Scene();
|
|
84067
84203
|
this.helpers = new Scene();
|
|
84204
|
+
this.target = new Vector3();
|
|
84068
84205
|
const pixelRatio = window.devicePixelRatio;
|
|
84069
84206
|
const rect = canvas.parentElement.getBoundingClientRect();
|
|
84070
84207
|
const width = rect.width || 1;
|
|
84071
84208
|
const height = rect.height || 1;
|
|
84072
84209
|
const aspect = width / height;
|
|
84073
84210
|
this.camera = new PerspectiveCamera(45, aspect, 0.01, 1000);
|
|
84074
|
-
this.camera.up.set(0,
|
|
84211
|
+
this.camera.up.set(0, 1, 0);
|
|
84212
|
+
this.camera.position.set(0, 0, 1);
|
|
84213
|
+
this.camera.lookAt(this.target);
|
|
84214
|
+
this.camera.updateProjectionMatrix();
|
|
84075
84215
|
this.renderer = new WebGLRenderer({
|
|
84076
84216
|
canvas,
|
|
84077
84217
|
antialias: true,
|