@inweb/viewer-three 26.9.0 → 26.9.2
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/components/AxesHelperComponent.js +8 -6
- package/dist/plugins/components/AxesHelperComponent.js.map +1 -1
- package/dist/plugins/components/AxesHelperComponent.min.js +1 -1
- package/dist/plugins/components/AxesHelperComponent.module.js +7 -5
- package/dist/plugins/components/AxesHelperComponent.module.js.map +1 -1
- package/dist/plugins/loaders/IFCXLoader.js.map +1 -1
- package/dist/plugins/loaders/IFCXLoader.module.js.map +1 -1
- package/dist/plugins/loaders/PotreeLoader.js +160 -0
- package/dist/plugins/loaders/PotreeLoader.js.map +1 -0
- package/dist/plugins/loaders/PotreeLoader.min.js +1 -0
- package/dist/plugins/loaders/PotreeLoader.module.js +68 -0
- package/dist/plugins/loaders/PotreeLoader.module.js.map +1 -0
- package/dist/viewer-three.js +153 -110
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +3 -3
- package/dist/viewer-three.module.js +152 -96
- package/dist/viewer-three.module.js.map +1 -1
- package/lib/Viewer/Viewer.d.ts +3 -2
- package/lib/Viewer/commands/SetDefaultViewPosition.d.ts +2 -2
- package/package.json +6 -5
- package/plugins/components/AxesHelperComponent.ts +10 -6
- package/plugins/loaders/{IFCXCloudLoader.ts → IFCX/IFCXCloudLoader.ts} +1 -1
- package/plugins/loaders/{IFCXFileLoader.ts → IFCX/IFCXFileLoader.ts} +1 -1
- package/plugins/loaders/Potree/PotreeFileLoader.ts +106 -0
- package/plugins/loaders/Potree/PotreeModelImpl.ts +36 -0
- package/plugins/loaders/Potree/index.ts +28 -0
- package/src/Viewer/Viewer.ts +39 -15
- package/src/Viewer/commands/SetDefaultViewPosition.ts +20 -16
- package/src/Viewer/commands/ZoomTo.ts +13 -13
- package/src/Viewer/components/ExtentsComponent.ts +1 -1
- package/src/Viewer/components/LightComponent.ts +8 -6
- package/src/Viewer/components/ResizeCanvasComponent.ts +1 -18
- package/src/Viewer/draggers/OrbitDragger.ts +9 -0
- package/src/Viewer/draggers/WalkDragger.ts +1 -0
- package/src/Viewer/helpers/WCSHelper.ts +3 -3
- 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/plugins/loaders/{IFCXLoader.ts → IFCX/index.ts} +0 -0
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
BufferAttribute,
|
|
24
24
|
LineBasicMaterial,
|
|
25
25
|
} from "three";
|
|
26
|
-
import {
|
|
26
|
+
import { GL_CONSTANTS } from "./GltfStructure.js";
|
|
27
27
|
import { mergeGeometries } from "three/examples/jsm/utils/BufferGeometryUtils.js";
|
|
28
28
|
|
|
29
29
|
export class DynamicGltfLoader {
|
|
@@ -94,6 +94,10 @@ export class DynamicGltfLoader {
|
|
|
94
94
|
this.hiddenHandles = new Set();
|
|
95
95
|
this.newOptimizedObjects = new Set();
|
|
96
96
|
this.oldOptimizeObjects = new Set();
|
|
97
|
+
|
|
98
|
+
this.maxConcurrentChunks = 8;
|
|
99
|
+
this.activeChunkLoads = 0;
|
|
100
|
+
this.chunkQueue = [];
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
setVisibleEdges(visible) {
|
|
@@ -503,6 +507,7 @@ export class DynamicGltfLoader {
|
|
|
503
507
|
const structureArray = Array.isArray(structures) ? structures : [structures];
|
|
504
508
|
|
|
505
509
|
for (const structure of structureArray) {
|
|
510
|
+
await structure.initialize(this);
|
|
506
511
|
this.structures.push(structure);
|
|
507
512
|
}
|
|
508
513
|
|
|
@@ -894,13 +899,6 @@ export class DynamicGltfLoader {
|
|
|
894
899
|
this.nodesToLoad = [];
|
|
895
900
|
}
|
|
896
901
|
|
|
897
|
-
async addStructure(loadController) {
|
|
898
|
-
const structure = new GltfStructure();
|
|
899
|
-
await structure.initialize(loadController);
|
|
900
|
-
this.structures.push(structure);
|
|
901
|
-
return structure;
|
|
902
|
-
}
|
|
903
|
-
|
|
904
902
|
removeOptimization() {
|
|
905
903
|
this.originalObjects.forEach((obj) => (obj.visible = true));
|
|
906
904
|
|
|
@@ -932,7 +930,8 @@ export class DynamicGltfLoader {
|
|
|
932
930
|
}
|
|
933
931
|
|
|
934
932
|
clear() {
|
|
935
|
-
|
|
933
|
+
this.chunkQueue = [];
|
|
934
|
+
|
|
936
935
|
this.structures.forEach((structure) => {
|
|
937
936
|
if (structure) {
|
|
938
937
|
structure.clear();
|
|
@@ -973,7 +972,6 @@ export class DynamicGltfLoader {
|
|
|
973
972
|
});
|
|
974
973
|
this.loadedMeshes.clear();
|
|
975
974
|
|
|
976
|
-
// Clear all structure roots and their children
|
|
977
975
|
this.structureRoots.forEach((rootGroup) => {
|
|
978
976
|
if (rootGroup) {
|
|
979
977
|
rootGroup.traverse((child) => {
|
|
@@ -993,7 +991,6 @@ export class DynamicGltfLoader {
|
|
|
993
991
|
});
|
|
994
992
|
this.structureRoots.clear();
|
|
995
993
|
|
|
996
|
-
// Clear all optimized objects
|
|
997
994
|
this.mergedMesh.forEach((mesh) => {
|
|
998
995
|
if (mesh.geometry) mesh.geometry.dispose();
|
|
999
996
|
if (mesh.material) {
|
|
@@ -1746,7 +1743,6 @@ export class DynamicGltfLoader {
|
|
|
1746
1743
|
});
|
|
1747
1744
|
}
|
|
1748
1745
|
|
|
1749
|
-
// Возвращает bounding box для конкретной структуры
|
|
1750
1746
|
getStructureGeometryExtent(structureId) {
|
|
1751
1747
|
const extent = new Box3();
|
|
1752
1748
|
for (const [nodeId, node] of this.nodes.entries()) {
|
|
@@ -1764,4 +1760,33 @@ export class DynamicGltfLoader {
|
|
|
1764
1760
|
}
|
|
1765
1761
|
return extent;
|
|
1766
1762
|
}
|
|
1763
|
+
|
|
1764
|
+
setMaxConcurrentChunks(maxChunks) {
|
|
1765
|
+
if (maxChunks < 1) {
|
|
1766
|
+
console.warn("Max concurrent chunks must be at least 1");
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
this.maxConcurrentChunks = maxChunks;
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
waitForChunkSlot() {
|
|
1773
|
+
if (this.activeChunkLoads < this.maxConcurrentChunks) {
|
|
1774
|
+
this.activeChunkLoads++;
|
|
1775
|
+
return Promise.resolve();
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
return new Promise((resolve) => {
|
|
1779
|
+
this.chunkQueue.push(resolve);
|
|
1780
|
+
});
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
releaseChunkSlot() {
|
|
1784
|
+
this.activeChunkLoads--;
|
|
1785
|
+
|
|
1786
|
+
if (this.chunkQueue.length > 0) {
|
|
1787
|
+
const nextResolve = this.chunkQueue.shift();
|
|
1788
|
+
this.activeChunkLoads++;
|
|
1789
|
+
nextResolve();
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1767
1792
|
}
|
|
@@ -43,11 +43,12 @@ const MAX_GAP = 128 * 1024; // 128 KB
|
|
|
43
43
|
const MAX_CHUNK = 30 * 1024 * 1024; // 100 MB
|
|
44
44
|
|
|
45
45
|
export class GltfStructure {
|
|
46
|
-
constructor(id) {
|
|
46
|
+
constructor(id, loadController) {
|
|
47
47
|
this.id = `${id}`;
|
|
48
48
|
this.json = null;
|
|
49
49
|
this.baseUrl = "";
|
|
50
|
-
this.loadController =
|
|
50
|
+
this.loadController = loadController;
|
|
51
|
+
this.loader = null;
|
|
51
52
|
this.batchDelay = 10;
|
|
52
53
|
this.maxBatchSize = 5 * 1024 * 1024;
|
|
53
54
|
this.maxRangesPerRequest = 512;
|
|
@@ -59,10 +60,10 @@ export class GltfStructure {
|
|
|
59
60
|
this.materialCache = new Map();
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
async initialize(
|
|
63
|
-
this.json = await loadController.loadJson();
|
|
64
|
-
this.baseUrl = await loadController.baseUrl();
|
|
65
|
-
this.
|
|
63
|
+
async initialize(loader) {
|
|
64
|
+
this.json = await this.loadController.loadJson();
|
|
65
|
+
this.baseUrl = await this.loadController.baseUrl();
|
|
66
|
+
this.loader = loader;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
clear() {
|
|
@@ -75,10 +76,12 @@ export class GltfStructure {
|
|
|
75
76
|
this.batchTimeout = null;
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
// Clear materials and textures
|
|
79
79
|
this.disposeMaterials();
|
|
80
80
|
this.textureCache.clear();
|
|
81
81
|
this.materials.clear();
|
|
82
|
+
|
|
83
|
+
this.activeChunkLoads = 0;
|
|
84
|
+
this.chunkQueue = [];
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
getJson() {
|
|
@@ -157,35 +160,32 @@ export class GltfStructure {
|
|
|
157
160
|
finalRanges.push({ start, end, requests });
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
163
|
+
|
|
164
|
+
const promises = finalRanges.map(async (range, index) => {
|
|
165
|
+
await this.loader.waitForChunkSlot();
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
const length = range.end - range.start;
|
|
169
|
+
const buffer = await this.loadController.loadBinaryData([{ offset: range.start, length }]);
|
|
170
|
+
|
|
171
|
+
for (const req of range.requests) {
|
|
172
|
+
const relOffset = req.offset - range.start;
|
|
173
|
+
try {
|
|
174
|
+
req._resolve({ buffer, relOffset, length: req.length });
|
|
175
|
+
} catch (e) {
|
|
176
|
+
req._reject(e);
|
|
177
|
+
}
|
|
172
178
|
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const promises = finalRanges.map(async (range) => {
|
|
178
|
-
const length = range.end - range.start;
|
|
179
|
-
const buffer = await this.loadController.loadBinaryData([{ offset: range.start, length }]);
|
|
180
|
-
for (const req of range.requests) {
|
|
181
|
-
const relOffset = req.offset - range.start;
|
|
182
|
-
try {
|
|
183
|
-
req._resolve({ buffer, relOffset, length: req.length });
|
|
184
|
-
} catch (e) {
|
|
185
|
-
req._reject(e);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
for (const req of range.requests) {
|
|
181
|
+
req._reject(error);
|
|
186
182
|
}
|
|
183
|
+
console.warn(`Failed to load chunk ${index + 1}/${finalRanges.length} (${range.start}-${range.end}):`, error);
|
|
184
|
+
} finally {
|
|
185
|
+
this.loader.releaseChunkSlot();
|
|
187
186
|
}
|
|
188
187
|
});
|
|
188
|
+
|
|
189
189
|
await Promise.all(promises);
|
|
190
190
|
|
|
191
191
|
this.pendingRequests = [];
|
|
@@ -58,6 +58,7 @@ export class GLTFCloudDynamicLoader implements ILoader {
|
|
|
58
58
|
this.gltfLoader = new DynamicGltfLoader(this.viewer.camera, scene, this.viewer.renderer);
|
|
59
59
|
this.gltfLoader.memoryLimit = this.viewer.options.memoryLimit;
|
|
60
60
|
this.gltfLoader.setVisibleEdges(this.viewer.options.edgeModel);
|
|
61
|
+
// this.gltfLoader.setMaxConcurrentChunks(this.viewer.options.maxConcurrentChunks);
|
|
61
62
|
|
|
62
63
|
this.gltfLoader.addEventListener("databasechunk", (data) => {
|
|
63
64
|
const modelImpl = new DynamicModelImpl(scene);
|
|
@@ -126,8 +127,7 @@ export class GLTFCloudDynamicLoader implements ILoader {
|
|
|
126
127
|
baseUrl: () => Promise.resolve(`${model.httpClient.serverUrl}${model.path}/`),
|
|
127
128
|
};
|
|
128
129
|
|
|
129
|
-
const structure = new GltfStructure(model.id);
|
|
130
|
-
await structure.initialize(loadController);
|
|
130
|
+
const structure = new GltfStructure(model.id, loadController);
|
|
131
131
|
|
|
132
132
|
await this.gltfLoader.loadStructure(structure);
|
|
133
133
|
await this.gltfLoader.loadNodes();
|
|
File without changes
|