@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.
Files changed (39) hide show
  1. package/dist/plugins/components/AxesHelperComponent.js +8 -6
  2. package/dist/plugins/components/AxesHelperComponent.js.map +1 -1
  3. package/dist/plugins/components/AxesHelperComponent.min.js +1 -1
  4. package/dist/plugins/components/AxesHelperComponent.module.js +7 -5
  5. package/dist/plugins/components/AxesHelperComponent.module.js.map +1 -1
  6. package/dist/plugins/loaders/IFCXLoader.js.map +1 -1
  7. package/dist/plugins/loaders/IFCXLoader.module.js.map +1 -1
  8. package/dist/plugins/loaders/PotreeLoader.js +160 -0
  9. package/dist/plugins/loaders/PotreeLoader.js.map +1 -0
  10. package/dist/plugins/loaders/PotreeLoader.min.js +1 -0
  11. package/dist/plugins/loaders/PotreeLoader.module.js +68 -0
  12. package/dist/plugins/loaders/PotreeLoader.module.js.map +1 -0
  13. package/dist/viewer-three.js +153 -110
  14. package/dist/viewer-three.js.map +1 -1
  15. package/dist/viewer-three.min.js +3 -3
  16. package/dist/viewer-three.module.js +152 -96
  17. package/dist/viewer-three.module.js.map +1 -1
  18. package/lib/Viewer/Viewer.d.ts +3 -2
  19. package/lib/Viewer/commands/SetDefaultViewPosition.d.ts +2 -2
  20. package/package.json +6 -5
  21. package/plugins/components/AxesHelperComponent.ts +10 -6
  22. package/plugins/loaders/{IFCXCloudLoader.ts → IFCX/IFCXCloudLoader.ts} +1 -1
  23. package/plugins/loaders/{IFCXFileLoader.ts → IFCX/IFCXFileLoader.ts} +1 -1
  24. package/plugins/loaders/Potree/PotreeFileLoader.ts +106 -0
  25. package/plugins/loaders/Potree/PotreeModelImpl.ts +36 -0
  26. package/plugins/loaders/Potree/index.ts +28 -0
  27. package/src/Viewer/Viewer.ts +39 -15
  28. package/src/Viewer/commands/SetDefaultViewPosition.ts +20 -16
  29. package/src/Viewer/commands/ZoomTo.ts +13 -13
  30. package/src/Viewer/components/ExtentsComponent.ts +1 -1
  31. package/src/Viewer/components/LightComponent.ts +8 -6
  32. package/src/Viewer/components/ResizeCanvasComponent.ts +1 -18
  33. package/src/Viewer/draggers/OrbitDragger.ts +9 -0
  34. package/src/Viewer/draggers/WalkDragger.ts +1 -0
  35. package/src/Viewer/helpers/WCSHelper.ts +3 -3
  36. package/src/Viewer/loaders/DynamicGltfLoader/DynamicGltfLoader.js +37 -12
  37. package/src/Viewer/loaders/DynamicGltfLoader/GltfStructure.js +32 -32
  38. package/src/Viewer/loaders/GLTFCloudDynamicLoader.ts +2 -2
  39. /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 { GltfStructure, GL_CONSTANTS } from "./GltfStructure.js";
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
- // Clear all structures
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 = null;
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(loadController) {
63
- this.json = await loadController.loadJson();
64
- this.baseUrl = await loadController.baseUrl();
65
- this.loadController = loadController;
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
- for (const range of finalRanges) {
162
- const length = range.end - range.start;
163
- const buffer = await this.loadController.loadBinaryData([
164
- { offset: range.start, length: length }
165
- ]);
166
- for (const req of range.requests) {
167
- const relOffset = req.offset - range.start;
168
- try {
169
- req._resolve({ buffer, relOffset, length: req.length });
170
- } catch (e) {
171
- req._reject(e);
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();