@inweb/viewer-three 26.8.2 → 26.9.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/viewer-three.js +112 -87
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +3 -3
- package/dist/viewer-three.module.js +103 -69
- package/dist/viewer-three.module.js.map +1 -1
- package/lib/Viewer/commands/SetDefaultViewPosition.d.ts +2 -2
- package/package.json +5 -5
- package/src/Viewer/Viewer.ts +5 -11
- package/src/Viewer/commands/SetDefaultViewPosition.ts +20 -16
- package/src/Viewer/commands/ZoomTo.ts +13 -13
- package/src/Viewer/components/LightComponent.ts +8 -6
- package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +37 -12
- package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +32 -32
- package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +2 -2
- package/lib/Viewer/model/IModelImpl.d.ts +0 -27
- package/lib/Viewer/model/ModelImpl.d.ts +0 -27
- package/lib/Viewer/model/index.d.ts +0 -2
- package/src/Viewer/model/IModelImpl.ts +0 -67
- package/src/Viewer/model/ModelImpl.ts +0 -214
- package/src/Viewer/model/index.ts +0 -25
|
@@ -1547,32 +1547,28 @@ function collect(viewer) {
|
|
|
1547
1547
|
|
|
1548
1548
|
function zoomTo(viewer, box) {
|
|
1549
1549
|
if (box.isEmpty()) return;
|
|
1550
|
-
const
|
|
1551
|
-
const
|
|
1550
|
+
const boxCenter = box.getCenter(new Vector3);
|
|
1551
|
+
const boxSize = box.getBoundingSphere(new Sphere).radius;
|
|
1552
1552
|
const rendererSize = viewer.renderer.getSize(new Vector2);
|
|
1553
1553
|
const aspect = rendererSize.x / rendererSize.y;
|
|
1554
1554
|
const camera = viewer.camera;
|
|
1555
1555
|
if (camera.isPerspectiveCamera) {
|
|
1556
|
-
const offset = new Vector3(0, 0, 1);
|
|
1557
|
-
offset.
|
|
1558
|
-
offset.multiplyScalar(sphere.radius / Math.tan(MathUtils.DEG2RAD * camera.fov * .5));
|
|
1559
|
-
camera.position.copy(center).add(offset);
|
|
1556
|
+
const offset = new Vector3(0, 0, 1).applyQuaternion(camera.quaternion).multiplyScalar(boxSize / Math.tan(MathUtils.DEG2RAD * camera.fov * .5));
|
|
1557
|
+
camera.position.copy(offset).add(boxCenter);
|
|
1560
1558
|
camera.updateMatrixWorld();
|
|
1561
1559
|
}
|
|
1562
1560
|
if (camera.isOrthographicCamera) {
|
|
1563
|
-
camera.top =
|
|
1564
|
-
camera.bottom = -
|
|
1561
|
+
camera.top = boxSize;
|
|
1562
|
+
camera.bottom = -boxSize;
|
|
1565
1563
|
camera.left = camera.bottom * aspect;
|
|
1566
1564
|
camera.right = camera.top * aspect;
|
|
1567
1565
|
camera.zoom = 1;
|
|
1568
1566
|
camera.updateProjectionMatrix();
|
|
1569
|
-
const offset = new Vector3(0, 0, 1);
|
|
1570
|
-
offset.
|
|
1571
|
-
offset.multiplyScalar(viewer.extents.getBoundingSphere(new Sphere).radius * 3);
|
|
1572
|
-
camera.position.copy(center).add(offset);
|
|
1567
|
+
const offset = new Vector3(0, 0, 1).applyQuaternion(camera.quaternion).multiplyScalar(viewer.extents.getBoundingSphere(new Sphere).radius * 3);
|
|
1568
|
+
camera.position.copy(offset).add(boxCenter);
|
|
1573
1569
|
camera.updateMatrixWorld();
|
|
1574
1570
|
}
|
|
1575
|
-
viewer.target.copy(
|
|
1571
|
+
viewer.target.copy(boxCenter);
|
|
1576
1572
|
viewer.update();
|
|
1577
1573
|
viewer.emitEvent({
|
|
1578
1574
|
type: "zoom"
|
|
@@ -1580,28 +1576,31 @@ function zoomTo(viewer, box) {
|
|
|
1580
1576
|
}
|
|
1581
1577
|
|
|
1582
1578
|
const defaultViewPositions = {
|
|
1583
|
-
front: new Vector3(0, 0, 1),
|
|
1584
|
-
back: new Vector3(0, 0,
|
|
1585
|
-
left: new Vector3(
|
|
1586
|
-
right: new Vector3(1, 0, 0),
|
|
1579
|
+
front: new Vector3(0, 0, -1),
|
|
1580
|
+
back: new Vector3(0, 0, 1),
|
|
1581
|
+
left: new Vector3(1, 0, 0),
|
|
1582
|
+
right: new Vector3(-1, 0, 0),
|
|
1587
1583
|
bottom: new Vector3(0, -1, 0),
|
|
1588
1584
|
top: new Vector3(0, 1, 0),
|
|
1589
|
-
|
|
1590
|
-
sw: new Vector3(
|
|
1591
|
-
|
|
1592
|
-
|
|
1585
|
+
se: new Vector3(-1, 1, -1).normalize(),
|
|
1586
|
+
sw: new Vector3(1, 1, -1).normalize(),
|
|
1587
|
+
ne: new Vector3(-1, 1, 1).normalize(),
|
|
1588
|
+
nw: new Vector3(1, 1, 1).normalize()
|
|
1593
1589
|
};
|
|
1594
1590
|
|
|
1595
1591
|
function setDefaultViewPosition(viewer, position) {
|
|
1596
|
-
const
|
|
1597
|
-
const
|
|
1598
|
-
const
|
|
1599
|
-
const
|
|
1592
|
+
const extentsCenter = viewer.extents.getCenter(new Vector3);
|
|
1593
|
+
const extentsSize = viewer.extents.getBoundingSphere(new Sphere).radius * 2;
|
|
1594
|
+
const upY = new Vector3(0, 1, 0);
|
|
1595
|
+
const offsetY = defaultViewPositions[position] || defaultViewPositions["sw"];
|
|
1596
|
+
const up = (new Vector3).copy(viewer.camera.up);
|
|
1597
|
+
const quaternion = (new Quaternion).setFromUnitVectors(upY, up);
|
|
1598
|
+
const offset = (new Vector3).copy(offsetY).applyQuaternion(quaternion);
|
|
1600
1599
|
const camera = viewer.camera;
|
|
1601
|
-
camera.position.copy(
|
|
1602
|
-
camera.lookAt(
|
|
1600
|
+
camera.position.copy(offset).multiplyScalar(extentsSize).add(extentsCenter);
|
|
1601
|
+
camera.lookAt(extentsCenter);
|
|
1603
1602
|
camera.updateMatrixWorld();
|
|
1604
|
-
viewer.target.copy(
|
|
1603
|
+
viewer.target.copy(extentsCenter);
|
|
1605
1604
|
viewer.update();
|
|
1606
1605
|
viewer.emit({
|
|
1607
1606
|
type: "viewposition",
|
|
@@ -1931,8 +1930,12 @@ class LightComponent {
|
|
|
1931
1930
|
if (this.viewer.extents.isEmpty()) return;
|
|
1932
1931
|
const extentsCenter = this.viewer.extents.getCenter(new Vector3);
|
|
1933
1932
|
const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere).radius;
|
|
1934
|
-
const
|
|
1935
|
-
|
|
1933
|
+
const upY = new Vector3(0, 1, 0);
|
|
1934
|
+
const frontY = new Vector3(0, 0, -1);
|
|
1935
|
+
const up = (new Vector3).copy(this.viewer.camera.up);
|
|
1936
|
+
const quaternion = (new Quaternion).setFromUnitVectors(upY, up);
|
|
1937
|
+
const front = (new Vector3).copy(frontY).applyQuaternion(quaternion).negate();
|
|
1938
|
+
this.directionalLight.position.copy(up).applyAxisAngle(front, -Math.PI * 30 / 180).multiplyScalar(extentsSize * 2).add(extentsCenter);
|
|
1936
1939
|
this.directionalLight.target.position.copy(extentsCenter);
|
|
1937
1940
|
this.frontLight.position.copy(front).multiplyScalar(extentsSize * 2).add(extentsCenter);
|
|
1938
1941
|
this.frontLight.target.position.copy(extentsCenter);
|
|
@@ -2722,11 +2725,12 @@ const MAX_GAP = 128 * 1024;
|
|
|
2722
2725
|
const MAX_CHUNK = 30 * 1024 * 1024;
|
|
2723
2726
|
|
|
2724
2727
|
class GltfStructure {
|
|
2725
|
-
constructor(id) {
|
|
2728
|
+
constructor(id, loadController) {
|
|
2726
2729
|
this.id = `${id}`;
|
|
2727
2730
|
this.json = null;
|
|
2728
2731
|
this.baseUrl = "";
|
|
2729
|
-
this.loadController =
|
|
2732
|
+
this.loadController = loadController;
|
|
2733
|
+
this.loader = null;
|
|
2730
2734
|
this.batchDelay = 10;
|
|
2731
2735
|
this.maxBatchSize = 5 * 1024 * 1024;
|
|
2732
2736
|
this.maxRangesPerRequest = 512;
|
|
@@ -2737,10 +2741,10 @@ class GltfStructure {
|
|
|
2737
2741
|
this.textureCache = new Map;
|
|
2738
2742
|
this.materialCache = new Map;
|
|
2739
2743
|
}
|
|
2740
|
-
async initialize(
|
|
2741
|
-
this.json = await loadController.loadJson();
|
|
2742
|
-
this.baseUrl = await loadController.baseUrl();
|
|
2743
|
-
this.
|
|
2744
|
+
async initialize(loader) {
|
|
2745
|
+
this.json = await this.loadController.loadJson();
|
|
2746
|
+
this.baseUrl = await this.loadController.baseUrl();
|
|
2747
|
+
this.loader = loader;
|
|
2744
2748
|
}
|
|
2745
2749
|
clear() {
|
|
2746
2750
|
this.json = null;
|
|
@@ -2754,6 +2758,8 @@ class GltfStructure {
|
|
|
2754
2758
|
this.disposeMaterials();
|
|
2755
2759
|
this.textureCache.clear();
|
|
2756
2760
|
this.materials.clear();
|
|
2761
|
+
this.activeChunkLoads = 0;
|
|
2762
|
+
this.chunkQueue = [];
|
|
2757
2763
|
}
|
|
2758
2764
|
getJson() {
|
|
2759
2765
|
return this.json;
|
|
@@ -2831,23 +2837,33 @@ class GltfStructure {
|
|
|
2831
2837
|
});
|
|
2832
2838
|
}
|
|
2833
2839
|
}
|
|
2834
|
-
const promises = finalRanges.map((async range => {
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
req.
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2840
|
+
const promises = finalRanges.map((async (range, index) => {
|
|
2841
|
+
await this.loader.waitForChunkSlot();
|
|
2842
|
+
try {
|
|
2843
|
+
const length = range.end - range.start;
|
|
2844
|
+
const buffer = await this.loadController.loadBinaryData([ {
|
|
2845
|
+
offset: range.start,
|
|
2846
|
+
length: length
|
|
2847
|
+
} ]);
|
|
2848
|
+
for (const req of range.requests) {
|
|
2849
|
+
const relOffset = req.offset - range.start;
|
|
2850
|
+
try {
|
|
2851
|
+
req._resolve({
|
|
2852
|
+
buffer: buffer,
|
|
2853
|
+
relOffset: relOffset,
|
|
2854
|
+
length: req.length
|
|
2855
|
+
});
|
|
2856
|
+
} catch (e) {
|
|
2857
|
+
req._reject(e);
|
|
2858
|
+
}
|
|
2850
2859
|
}
|
|
2860
|
+
} catch (error) {
|
|
2861
|
+
for (const req of range.requests) {
|
|
2862
|
+
req._reject(error);
|
|
2863
|
+
}
|
|
2864
|
+
console.warn(`Failed to load chunk ${index + 1}/${finalRanges.length} (${range.start}-${range.end}):`, error);
|
|
2865
|
+
} finally {
|
|
2866
|
+
this.loader.releaseChunkSlot();
|
|
2851
2867
|
}
|
|
2852
2868
|
}));
|
|
2853
2869
|
await Promise.all(promises);
|
|
@@ -3207,6 +3223,9 @@ class DynamicGltfLoader {
|
|
|
3207
3223
|
this.hiddenHandles = new Set;
|
|
3208
3224
|
this.newOptimizedObjects = new Set;
|
|
3209
3225
|
this.oldOptimizeObjects = new Set;
|
|
3226
|
+
this.maxConcurrentChunks = 8;
|
|
3227
|
+
this.activeChunkLoads = 0;
|
|
3228
|
+
this.chunkQueue = [];
|
|
3210
3229
|
}
|
|
3211
3230
|
setVisibleEdges(visible) {
|
|
3212
3231
|
this.visibleEdges = visible;
|
|
@@ -3564,6 +3583,7 @@ class DynamicGltfLoader {
|
|
|
3564
3583
|
this.clear();
|
|
3565
3584
|
const structureArray = Array.isArray(structures) ? structures : [ structures ];
|
|
3566
3585
|
for (const structure of structureArray) {
|
|
3586
|
+
await structure.initialize(this);
|
|
3567
3587
|
this.structures.push(structure);
|
|
3568
3588
|
}
|
|
3569
3589
|
for (const structure of this.structures) {
|
|
@@ -3875,12 +3895,6 @@ class DynamicGltfLoader {
|
|
|
3875
3895
|
clearNodesToLoad() {
|
|
3876
3896
|
this.nodesToLoad = [];
|
|
3877
3897
|
}
|
|
3878
|
-
async addStructure(loadController) {
|
|
3879
|
-
const structure = new GltfStructure;
|
|
3880
|
-
await structure.initialize(loadController);
|
|
3881
|
-
this.structures.push(structure);
|
|
3882
|
-
return structure;
|
|
3883
|
-
}
|
|
3884
3898
|
removeOptimization() {
|
|
3885
3899
|
this.originalObjects.forEach((obj => obj.visible = true));
|
|
3886
3900
|
const disposeMerged = obj => {
|
|
@@ -3909,6 +3923,7 @@ class DynamicGltfLoader {
|
|
|
3909
3923
|
this.originalObjectsToSelection.clear();
|
|
3910
3924
|
}
|
|
3911
3925
|
clear() {
|
|
3926
|
+
this.chunkQueue = [];
|
|
3912
3927
|
this.structures.forEach((structure => {
|
|
3913
3928
|
if (structure) {
|
|
3914
3929
|
structure.clear();
|
|
@@ -4596,6 +4611,30 @@ class DynamicGltfLoader {
|
|
|
4596
4611
|
}
|
|
4597
4612
|
return extent;
|
|
4598
4613
|
}
|
|
4614
|
+
setMaxConcurrentChunks(maxChunks) {
|
|
4615
|
+
if (maxChunks < 1) {
|
|
4616
|
+
console.warn("Max concurrent chunks must be at least 1");
|
|
4617
|
+
return;
|
|
4618
|
+
}
|
|
4619
|
+
this.maxConcurrentChunks = maxChunks;
|
|
4620
|
+
}
|
|
4621
|
+
waitForChunkSlot() {
|
|
4622
|
+
if (this.activeChunkLoads < this.maxConcurrentChunks) {
|
|
4623
|
+
this.activeChunkLoads++;
|
|
4624
|
+
return Promise.resolve();
|
|
4625
|
+
}
|
|
4626
|
+
return new Promise((resolve => {
|
|
4627
|
+
this.chunkQueue.push(resolve);
|
|
4628
|
+
}));
|
|
4629
|
+
}
|
|
4630
|
+
releaseChunkSlot() {
|
|
4631
|
+
this.activeChunkLoads--;
|
|
4632
|
+
if (this.chunkQueue.length > 0) {
|
|
4633
|
+
const nextResolve = this.chunkQueue.shift();
|
|
4634
|
+
this.activeChunkLoads++;
|
|
4635
|
+
nextResolve();
|
|
4636
|
+
}
|
|
4637
|
+
}
|
|
4599
4638
|
}
|
|
4600
4639
|
|
|
4601
4640
|
class GLTFCloudDynamicLoader {
|
|
@@ -4676,8 +4715,7 @@ class GLTFCloudDynamicLoader {
|
|
|
4676
4715
|
},
|
|
4677
4716
|
baseUrl: () => Promise.resolve(`${model.httpClient.serverUrl}${model.path}/`)
|
|
4678
4717
|
};
|
|
4679
|
-
const structure = new GltfStructure(model.id);
|
|
4680
|
-
await structure.initialize(loadController);
|
|
4718
|
+
const structure = new GltfStructure(model.id, loadController);
|
|
4681
4719
|
await this.gltfLoader.loadStructure(structure);
|
|
4682
4720
|
await this.gltfLoader.loadNodes();
|
|
4683
4721
|
return this;
|
|
@@ -4842,13 +4880,13 @@ class Viewer extends EventEmitter2 {
|
|
|
4842
4880
|
this.addEventListener("optionschange", (event => this.syncOptions(event.data)));
|
|
4843
4881
|
this.scene = new Scene;
|
|
4844
4882
|
this.helpers = new Helpers;
|
|
4845
|
-
this.target = new Vector3;
|
|
4883
|
+
this.target = new Vector3(0, 0, 0);
|
|
4846
4884
|
const pixelRatio = window.devicePixelRatio;
|
|
4847
4885
|
const rect = canvas.parentElement.getBoundingClientRect();
|
|
4848
4886
|
const width = rect.width || 1;
|
|
4849
4887
|
const height = rect.height || 1;
|
|
4850
4888
|
const aspect = width / height;
|
|
4851
|
-
this.camera = new PerspectiveCamera(45, aspect, .
|
|
4889
|
+
this.camera = new PerspectiveCamera(45, aspect, .001, 1e3);
|
|
4852
4890
|
this.camera.up.set(0, 1, 0);
|
|
4853
4891
|
this.camera.position.set(0, 0, 1);
|
|
4854
4892
|
this.camera.lookAt(this.target);
|
|
@@ -5059,10 +5097,6 @@ class Viewer extends EventEmitter2 {
|
|
|
5059
5097
|
this.models = [];
|
|
5060
5098
|
this.scene.clear();
|
|
5061
5099
|
this.helpers.clear();
|
|
5062
|
-
this.models.forEach((model => model.dispose()));
|
|
5063
|
-
this.models = [];
|
|
5064
|
-
this.helpers.clear();
|
|
5065
|
-
this.scene.clear();
|
|
5066
5100
|
this.syncOptions();
|
|
5067
5101
|
this.syncOverlay();
|
|
5068
5102
|
this.update(true);
|
|
@@ -5221,7 +5255,7 @@ class Viewer extends EventEmitter2 {
|
|
|
5221
5255
|
camera.left = camera.bottom * aspect;
|
|
5222
5256
|
camera.right = camera.top * aspect;
|
|
5223
5257
|
camera.near = 0;
|
|
5224
|
-
camera.far = extentsSize *
|
|
5258
|
+
camera.far = extentsSize * 1e3;
|
|
5225
5259
|
camera.zoom = orthogonal_camera.view_to_world_scale;
|
|
5226
5260
|
camera.updateProjectionMatrix();
|
|
5227
5261
|
camera.up.copy(getVector3FromPoint3d(orthogonal_camera.up_vector));
|
|
@@ -5242,8 +5276,8 @@ class Viewer extends EventEmitter2 {
|
|
|
5242
5276
|
const camera = new PerspectiveCamera;
|
|
5243
5277
|
camera.fov = perspective_camera.field_of_view;
|
|
5244
5278
|
camera.aspect = aspect;
|
|
5245
|
-
camera.near = extentsSize /
|
|
5246
|
-
camera.far = extentsSize *
|
|
5279
|
+
camera.near = extentsSize / 1e3;
|
|
5280
|
+
camera.far = extentsSize * 1e3;
|
|
5247
5281
|
camera.updateProjectionMatrix();
|
|
5248
5282
|
camera.up.copy(getVector3FromPoint3d(perspective_camera.up_vector));
|
|
5249
5283
|
camera.position.copy(getVector3FromPoint3d(perspective_camera.view_point));
|