itowns 2.45.1-next.0 → 2.45.1-next.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.
Files changed (185) hide show
  1. package/dist/455.js +2 -0
  2. package/dist/455.js.map +1 -0
  3. package/dist/debug.js +3 -0
  4. package/dist/debug.js.LICENSE.txt +13 -0
  5. package/dist/debug.js.map +1 -0
  6. package/dist/itowns.js +3 -0
  7. package/dist/itowns.js.LICENSE.txt +5 -0
  8. package/dist/itowns.js.map +1 -0
  9. package/dist/itowns_lasparser.js +2 -0
  10. package/dist/itowns_lasparser.js.map +1 -0
  11. package/dist/itowns_lasworker.js +2 -0
  12. package/dist/itowns_lasworker.js.map +1 -0
  13. package/dist/itowns_potree2worker.js +2 -0
  14. package/dist/itowns_potree2worker.js.map +1 -0
  15. package/dist/itowns_widgets.js +2 -0
  16. package/dist/itowns_widgets.js.map +1 -0
  17. package/lib/Controls/FirstPersonControls.js +308 -0
  18. package/lib/Controls/FlyControls.js +175 -0
  19. package/lib/Controls/GlobeControls.js +1178 -0
  20. package/lib/Controls/PlanarControls.js +1025 -0
  21. package/lib/Controls/StateControl.js +432 -0
  22. package/lib/Controls/StreetControls.js +392 -0
  23. package/lib/Converter/Feature2Mesh.js +612 -0
  24. package/lib/Converter/Feature2Texture.js +174 -0
  25. package/lib/Converter/convertToTile.js +70 -0
  26. package/lib/Converter/textureConverter.js +43 -0
  27. package/lib/Core/3DTiles/C3DTBatchTable.js +131 -0
  28. package/lib/Core/3DTiles/C3DTBatchTableHierarchyExtension.js +96 -0
  29. package/lib/Core/3DTiles/C3DTBoundingVolume.js +156 -0
  30. package/lib/Core/3DTiles/C3DTExtensions.js +97 -0
  31. package/lib/Core/3DTiles/C3DTFeature.js +110 -0
  32. package/lib/Core/3DTiles/C3DTilesEnums.js +20 -0
  33. package/lib/Core/3DTiles/C3DTileset.js +99 -0
  34. package/lib/Core/3DTiles/utils/BinaryPropertyAccessor.js +100 -0
  35. package/lib/Core/AnimationPlayer.js +142 -0
  36. package/lib/Core/CopcNode.js +174 -0
  37. package/lib/Core/Deprecated/Undeprecator.js +74 -0
  38. package/lib/Core/EntwinePointTileNode.js +126 -0
  39. package/lib/Core/Feature.js +488 -0
  40. package/lib/Core/Geographic/GeoidGrid.js +108 -0
  41. package/lib/Core/Label.js +222 -0
  42. package/lib/Core/MainLoop.js +209 -0
  43. package/lib/Core/Picking.js +255 -0
  44. package/lib/Core/PointCloudNode.js +42 -0
  45. package/lib/Core/Potree2Node.js +206 -0
  46. package/lib/Core/Potree2PointAttributes.js +139 -0
  47. package/lib/Core/PotreeNode.js +101 -0
  48. package/lib/Core/Prefab/Globe/Atmosphere.js +293 -0
  49. package/lib/Core/Prefab/Globe/GlobeLayer.js +152 -0
  50. package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +110 -0
  51. package/lib/Core/Prefab/Globe/SkyShader.js +78 -0
  52. package/lib/Core/Prefab/GlobeView.js +155 -0
  53. package/lib/Core/Prefab/Planar/PlanarLayer.js +59 -0
  54. package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +71 -0
  55. package/lib/Core/Prefab/PlanarView.js +62 -0
  56. package/lib/Core/Prefab/TileBuilder.js +82 -0
  57. package/lib/Core/Prefab/computeBufferTileGeometry.js +248 -0
  58. package/lib/Core/Scheduler/Cache.js +17 -0
  59. package/lib/Core/Scheduler/CancelledCommandException.js +15 -0
  60. package/lib/Core/Scheduler/Scheduler.js +294 -0
  61. package/lib/Core/Style.js +660 -0
  62. package/lib/Core/StyleOptions.js +486 -0
  63. package/lib/Core/System/Capabilities.js +63 -0
  64. package/lib/Core/Tile/Tile.js +205 -0
  65. package/lib/Core/Tile/TileGrid.js +49 -0
  66. package/lib/Core/TileGeometry.js +124 -0
  67. package/lib/Core/TileMesh.js +108 -0
  68. package/lib/Core/View.js +1115 -0
  69. package/lib/Layer/C3DTilesLayer.js +459 -0
  70. package/lib/Layer/ColorLayer.js +154 -0
  71. package/lib/Layer/CopcLayer.js +63 -0
  72. package/lib/Layer/ElevationLayer.js +139 -0
  73. package/lib/Layer/EntwinePointTileLayer.js +71 -0
  74. package/lib/Layer/FeatureGeometryLayer.js +77 -0
  75. package/lib/Layer/GeoidLayer.js +80 -0
  76. package/lib/Layer/GeometryLayer.js +233 -0
  77. package/lib/Layer/InfoLayer.js +64 -0
  78. package/lib/Layer/LabelLayer.js +469 -0
  79. package/lib/Layer/Layer.js +335 -0
  80. package/lib/Layer/LayerUpdateState.js +89 -0
  81. package/lib/Layer/LayerUpdateStrategy.js +80 -0
  82. package/lib/Layer/OGC3DTilesLayer.js +543 -0
  83. package/lib/Layer/OrientedImageLayer.js +227 -0
  84. package/lib/Layer/PointCloudLayer.js +405 -0
  85. package/lib/Layer/Potree2Layer.js +171 -0
  86. package/lib/Layer/PotreeLayer.js +72 -0
  87. package/lib/Layer/RasterLayer.js +37 -0
  88. package/lib/Layer/ReferencingLayerProperties.js +62 -0
  89. package/lib/Layer/TiledGeometryLayer.js +459 -0
  90. package/lib/Loader/LASLoader.js +193 -0
  91. package/lib/Loader/Potree2BrotliLoader.js +261 -0
  92. package/lib/Loader/Potree2Loader.js +207 -0
  93. package/lib/Main.js +113 -0
  94. package/lib/MainBundle.js +4 -0
  95. package/lib/Parser/B3dmParser.js +174 -0
  96. package/lib/Parser/CameraCalibrationParser.js +94 -0
  97. package/lib/Parser/GDFParser.js +72 -0
  98. package/lib/Parser/GTXParser.js +75 -0
  99. package/lib/Parser/GeoJsonParser.js +212 -0
  100. package/lib/Parser/GpxParser.js +25 -0
  101. package/lib/Parser/ISGParser.js +71 -0
  102. package/lib/Parser/KMLParser.js +25 -0
  103. package/lib/Parser/LASParser.js +137 -0
  104. package/lib/Parser/MapBoxUrlParser.js +83 -0
  105. package/lib/Parser/PntsParser.js +131 -0
  106. package/lib/Parser/Potree2BinParser.js +92 -0
  107. package/lib/Parser/PotreeBinParser.js +106 -0
  108. package/lib/Parser/PotreeCinParser.js +29 -0
  109. package/lib/Parser/ShapefileParser.js +78 -0
  110. package/lib/Parser/VectorTileParser.js +215 -0
  111. package/lib/Parser/XbilParser.js +120 -0
  112. package/lib/Parser/deprecated/LegacyGLTFLoader.js +1386 -0
  113. package/lib/Parser/iGLTFLoader.js +168 -0
  114. package/lib/Process/3dTilesProcessing.js +304 -0
  115. package/lib/Process/FeatureProcessing.js +76 -0
  116. package/lib/Process/LayeredMaterialNodeProcessing.js +229 -0
  117. package/lib/Process/ObjectRemovalHelper.js +97 -0
  118. package/lib/Process/handlerNodeError.js +23 -0
  119. package/lib/Provider/3dTilesProvider.js +149 -0
  120. package/lib/Provider/DataSourceProvider.js +24 -0
  121. package/lib/Provider/Fetcher.js +233 -0
  122. package/lib/Provider/PointCloudProvider.js +45 -0
  123. package/lib/Provider/TileProvider.js +16 -0
  124. package/lib/Provider/URLBuilder.js +116 -0
  125. package/lib/Renderer/Camera.js +281 -0
  126. package/lib/Renderer/Color.js +56 -0
  127. package/lib/Renderer/ColorLayersOrdering.js +115 -0
  128. package/lib/Renderer/CommonMaterial.js +31 -0
  129. package/lib/Renderer/Label2DRenderer.js +192 -0
  130. package/lib/Renderer/LayeredMaterial.js +243 -0
  131. package/lib/Renderer/OBB.js +150 -0
  132. package/lib/Renderer/OrientedImageCamera.js +118 -0
  133. package/lib/Renderer/OrientedImageMaterial.js +167 -0
  134. package/lib/Renderer/PointsMaterial.js +485 -0
  135. package/lib/Renderer/RasterTile.js +243 -0
  136. package/lib/Renderer/RenderMode.js +31 -0
  137. package/lib/Renderer/Shader/ShaderChunk.js +160 -0
  138. package/lib/Renderer/Shader/ShaderUtils.js +47 -0
  139. package/lib/Renderer/SphereHelper.js +17 -0
  140. package/lib/Renderer/WebXR.js +51 -0
  141. package/lib/Renderer/c3DEngine.js +214 -0
  142. package/lib/Source/C3DTilesGoogleSource.js +74 -0
  143. package/lib/Source/C3DTilesIonSource.js +54 -0
  144. package/lib/Source/C3DTilesSource.js +30 -0
  145. package/lib/Source/CopcSource.js +126 -0
  146. package/lib/Source/EntwinePointTileSource.js +72 -0
  147. package/lib/Source/FileSource.js +188 -0
  148. package/lib/Source/OGC3DTilesGoogleSource.js +29 -0
  149. package/lib/Source/OGC3DTilesIonSource.js +34 -0
  150. package/lib/Source/OGC3DTilesSource.js +21 -0
  151. package/lib/Source/OrientedImageSource.js +59 -0
  152. package/lib/Source/Potree2Source.js +167 -0
  153. package/lib/Source/PotreeSource.js +82 -0
  154. package/lib/Source/Source.js +202 -0
  155. package/lib/Source/TMSSource.js +144 -0
  156. package/lib/Source/VectorTilesSource.js +182 -0
  157. package/lib/Source/WFSSource.js +170 -0
  158. package/lib/Source/WMSSource.js +167 -0
  159. package/lib/Source/WMTSSource.js +92 -0
  160. package/lib/ThreeExtended/capabilities/WebGL.js +69 -0
  161. package/lib/ThreeExtended/libs/ktx-parse.module.js +506 -0
  162. package/lib/ThreeExtended/libs/zstddec.module.js +29 -0
  163. package/lib/ThreeExtended/loaders/DDSLoader.js +200 -0
  164. package/lib/ThreeExtended/loaders/DRACOLoader.js +400 -0
  165. package/lib/ThreeExtended/loaders/GLTFLoader.js +2879 -0
  166. package/lib/ThreeExtended/loaders/KTX2Loader.js +709 -0
  167. package/lib/ThreeExtended/math/ColorSpaces.js +59 -0
  168. package/lib/ThreeExtended/utils/BufferGeometryUtils.js +846 -0
  169. package/lib/ThreeExtended/utils/WorkerPool.js +70 -0
  170. package/lib/Utils/CameraUtils.js +554 -0
  171. package/lib/Utils/DEMUtils.js +350 -0
  172. package/lib/Utils/FeaturesUtils.js +156 -0
  173. package/lib/Utils/Gradients.js +16 -0
  174. package/lib/Utils/ThreeUtils.js +115 -0
  175. package/lib/Utils/gui/C3DTilesStyle.js +218 -0
  176. package/lib/Utils/gui/Main.js +7 -0
  177. package/lib/Utils/gui/Minimap.js +152 -0
  178. package/lib/Utils/gui/Navigation.js +245 -0
  179. package/lib/Utils/gui/Scale.js +104 -0
  180. package/lib/Utils/gui/Searchbar.js +234 -0
  181. package/lib/Utils/gui/Widget.js +80 -0
  182. package/lib/Utils/placeObjectOnGround.js +136 -0
  183. package/lib/Worker/LASLoaderWorker.js +19 -0
  184. package/lib/Worker/Potree2Worker.js +21 -0
  185. package/package.json +2 -2
@@ -0,0 +1,229 @@
1
+ import { chooseNextLevelToFetch } from "../Layer/LayerUpdateStrategy.js";
2
+ import LayerUpdateState from "../Layer/LayerUpdateState.js";
3
+ import handlingError from "./handlerNodeError.js";
4
+ function materialCommandQueuePriorityFunction(material) {
5
+ // We know that 'node' is visible because commands can only be
6
+ // issued for visible nodes.
7
+ // TODO: need priorization of displayed nodes
8
+ // Then prefer displayed node over non-displayed one
9
+ return material.visible ? 100 : 10;
10
+ }
11
+ function refinementCommandCancellationFn(cmd) {
12
+ if (!cmd.requester.parent || !cmd.requester.material) {
13
+ return true;
14
+ }
15
+ // Cancel the command if the tile already has a better texture.
16
+ // This is only needed for elevation layers, because we may have several
17
+ // concurrent layers but we can only use one texture.
18
+ if (cmd.layer.isElevationLayer && cmd.requester.material.getElevationLayer() && cmd.targetLevel <= cmd.requester.material.getElevationLayer().level) {
19
+ return true;
20
+ }
21
+
22
+ // Cancel the command if the layer was removed between command scheduling and command execution
23
+ if (!cmd.requester.layerUpdateState[cmd.layer.id] || !cmd.layer.source._featuresCaches[cmd.layer.crs]) {
24
+ return true;
25
+ }
26
+ return !cmd.requester.material.visible;
27
+ }
28
+ function buildCommand(view, layer, extentsSource, extentsDestination, requester) {
29
+ return {
30
+ view,
31
+ layer,
32
+ extentsSource,
33
+ extentsDestination,
34
+ requester,
35
+ priority: materialCommandQueuePriorityFunction(requester.material),
36
+ earlyDropFunction: refinementCommandCancellationFn,
37
+ partialLoading: true
38
+ };
39
+ }
40
+ function computePitchs(textures, extentsDestination) {
41
+ return extentsDestination.map((ext, i) => ext.offsetToParent(textures[i].extent));
42
+ }
43
+ export function updateLayeredMaterialNodeImagery(context, layer, node, parent) {
44
+ const material = node.material;
45
+ if (!parent || !material) {
46
+ return;
47
+ }
48
+ const extentsDestination = node.getExtentsByProjection(layer.crs);
49
+ const zoom = extentsDestination[0].zoom;
50
+ if (zoom > layer.zoom.max || zoom < layer.zoom.min) {
51
+ return;
52
+ }
53
+ let nodeLayer = material.getLayer(layer.id);
54
+
55
+ // Initialisation
56
+ if (node.layerUpdateState[layer.id] === undefined) {
57
+ node.layerUpdateState[layer.id] = new LayerUpdateState();
58
+ if (!layer.source.extentInsideLimit(node.extent, zoom)) {
59
+ // we also need to check that tile's parent doesn't have a texture for this layer,
60
+ // because even if this tile is outside of the layer, it could inherit it's
61
+ // parent texture
62
+ if (!(!layer.noTextureParentOutsideLimit && parent.material && parent.material.getLayer && parent.material.getLayer(layer.id))) {
63
+ node.layerUpdateState[layer.id].noMoreUpdatePossible();
64
+ return;
65
+ } // ok, we're going to inherit our parent's texture
66
+ }
67
+ if (!nodeLayer) {
68
+ // Create new raster node
69
+ nodeLayer = layer.setupRasterNode(node);
70
+
71
+ // Init the node by parent
72
+ const parentLayer = parent.material?.getLayer(layer.id);
73
+ nodeLayer.initFromParent(parentLayer, extentsDestination);
74
+ }
75
+
76
+ // Proposed new process, two separate processes:
77
+ // * FIRST PASS: initNodeXXXFromParent and get out of the function
78
+ // * SECOND PASS: Fetch best texture
79
+
80
+ // The two-step allows you to filter out unnecessary requests
81
+ // Indeed in the second pass, their state (not visible or not displayed) can block them to fetch
82
+ if (nodeLayer.level >= layer.source.zoom.min) {
83
+ context.view.notifyChange(node, false);
84
+ return;
85
+ }
86
+ }
87
+
88
+ // Node is hidden, no need to update it
89
+ if (!material.visible) {
90
+ return;
91
+ }
92
+
93
+ // An update is pending / or impossible -> abort
94
+ if (!layer.visible || !node.layerUpdateState[layer.id].canTryUpdate()) {
95
+ return;
96
+ }
97
+ if (nodeLayer.level >= extentsDestination[0].zoom) {
98
+ // default decision method
99
+ node.layerUpdateState[layer.id].noMoreUpdatePossible();
100
+ return;
101
+ }
102
+
103
+ // is fetching data from this layer disabled?
104
+ if (layer.frozen) {
105
+ return;
106
+ }
107
+ const failureParams = node.layerUpdateState[layer.id].failureParams;
108
+ const destinationLevel = extentsDestination[0].zoom || node.level;
109
+ const targetLevel = chooseNextLevelToFetch(layer.updateStrategy.type, node, destinationLevel, nodeLayer.level, layer, failureParams);
110
+ if (!layer.source.isVectorSource && targetLevel <= nodeLayer.level || targetLevel > destinationLevel) {
111
+ if (failureParams.lowestLevelError != Infinity) {
112
+ // this is the highest level found in case of error.
113
+ node.layerUpdateState[layer.id].noMoreUpdatePossible();
114
+ }
115
+ return;
116
+ } else if (!layer.source.extentInsideLimit(node.extent, targetLevel)) {
117
+ node.layerUpdateState[layer.id].noData({
118
+ targetLevel
119
+ });
120
+ context.view.notifyChange(node, false);
121
+ return;
122
+ }
123
+ const extentsSource = extentsDestination.map(e => e.tiledExtentParent(targetLevel));
124
+ node.layerUpdateState[layer.id].newTry();
125
+ const command = buildCommand(context.view, layer, extentsSource, extentsDestination, node);
126
+ return context.scheduler.execute(command).then(results => {
127
+ // Does nothing if the layer has been removed while command was being or waiting to be executed
128
+ if (!node.layerUpdateState[layer.id]) {
129
+ return;
130
+ }
131
+ const textures = results.map((texture, index) => texture != null ? texture : {
132
+ isTexture: false,
133
+ extent: extentsDestination[index]
134
+ });
135
+ // TODO: Handle error : result is undefined in provider. throw error
136
+ const pitchs = computePitchs(textures, extentsDestination);
137
+ nodeLayer.setTextures(textures, pitchs);
138
+ node.layerUpdateState[layer.id].success();
139
+ }, err => handlingError(err, node, layer, targetLevel, context.view));
140
+ }
141
+ export function updateLayeredMaterialNodeElevation(context, layer, node, parent) {
142
+ const material = node.material;
143
+ if (!parent || !material) {
144
+ return;
145
+ }
146
+
147
+ // TODO: we need either
148
+ // - compound or exclusive layers
149
+ // - support for multiple elevation layers
150
+
151
+ // Elevation is currently handled differently from color layers.
152
+ // This is caused by a LayeredMaterial limitation: only 1 elevation texture
153
+ // can be used (where a tile can have N textures x M layers)
154
+ const extentsDestination = node.getExtentsByProjection(layer.crs);
155
+ const zoom = extentsDestination[0].zoom;
156
+ if (zoom > layer.zoom.max || zoom < layer.zoom.min) {
157
+ return;
158
+ }
159
+ // Init elevation layer, and inherit from parent if possible
160
+ let nodeLayer = material.getElevationLayer();
161
+ if (!nodeLayer) {
162
+ nodeLayer = layer.setupRasterNode(node);
163
+ }
164
+ if (node.layerUpdateState[layer.id] === undefined) {
165
+ node.layerUpdateState[layer.id] = new LayerUpdateState();
166
+ const parentLayer = parent.material?.getLayer(layer.id);
167
+ nodeLayer.initFromParent(parentLayer, extentsDestination);
168
+ if (nodeLayer.level >= layer.source.zoom.min) {
169
+ context.view.notifyChange(node, false);
170
+ return;
171
+ }
172
+ }
173
+
174
+ // Possible conditions to *not* update the elevation texture
175
+ if (layer.frozen || !material.visible || !node.layerUpdateState[layer.id].canTryUpdate()) {
176
+ return;
177
+ }
178
+ const failureParams = node.layerUpdateState[layer.id].failureParams;
179
+ const targetLevel = chooseNextLevelToFetch(layer.updateStrategy.type, node, extentsDestination[0].zoom, nodeLayer.level, layer, failureParams);
180
+ if (targetLevel <= nodeLayer.level || targetLevel > extentsDestination[0].zoom) {
181
+ node.layerUpdateState[layer.id].noMoreUpdatePossible();
182
+ return;
183
+ } else if (!layer.source.extentInsideLimit(node.extent, targetLevel)) {
184
+ node.layerUpdateState[layer.id].noData({
185
+ targetLevel
186
+ });
187
+ context.view.notifyChange(node, false);
188
+ return;
189
+ }
190
+ const extentsSource = extentsDestination.map(e => e.tiledExtentParent(targetLevel));
191
+ node.layerUpdateState[layer.id].newTry();
192
+ const command = buildCommand(context.view, layer, extentsSource, extentsDestination, node);
193
+ return context.scheduler.execute(command).then(results => {
194
+ // Does nothing if the layer has been removed while command was being or waiting to be executed
195
+ if (!node.layerUpdateState[layer.id]) {
196
+ return;
197
+ }
198
+
199
+ // Do not apply the new texture if its level is < than the current
200
+ // one. This is only needed for elevation layers, because we may
201
+ // have several concurrent layers but we can only use one texture.
202
+ if (targetLevel <= nodeLayer.level) {
203
+ node.layerUpdateState[layer.id].noMoreUpdatePossible();
204
+ return;
205
+ }
206
+ const pitchs = computePitchs(results, extentsDestination);
207
+ nodeLayer.setTextures(results, pitchs);
208
+ node.layerUpdateState[layer.id].success();
209
+ }, err => handlingError(err, node, layer, targetLevel, context.view));
210
+ }
211
+ export function removeLayeredMaterialNodeLayer(layerId) {
212
+ /**
213
+ * @param {TileMesh} node - The node to udpate.
214
+ */
215
+ return function (node) {
216
+ if (node.material?.removeLayer) {
217
+ if (node.material.elevationLayerIds.indexOf(layerId) > -1) {
218
+ node.setBBoxZ({
219
+ min: 0,
220
+ max: 0
221
+ });
222
+ }
223
+ node.material.removeLayer(layerId);
224
+ }
225
+ if (node.layerUpdateState && node.layerUpdateState[layerId]) {
226
+ delete node.layerUpdateState[layerId];
227
+ }
228
+ };
229
+ }
@@ -0,0 +1,97 @@
1
+ function disposeSingleMaterialAndTextures(material) {
2
+ material.dispose();
3
+ // dispose textures
4
+ for (const key of Object.keys(material)) {
5
+ const val = material[key];
6
+ if (val && val.isTexture) {
7
+ val.dispose();
8
+ }
9
+ }
10
+ }
11
+ export default {
12
+ /**
13
+ * Cleanup obj to release three.js allocated resources
14
+ * @param {Object3D} obj object to release
15
+ */
16
+ cleanup(obj) {
17
+ obj.layer = null;
18
+
19
+ // THREE.Scene dispose function displays a deprecation message
20
+ if (!obj.isScene && typeof obj.dispose === 'function') {
21
+ obj.dispose();
22
+ } else {
23
+ if (obj.geometry) {
24
+ obj.geometry.dispose();
25
+ // the Object Removal Helper causes inconsistencies
26
+ // when it assigns null to a geometry present in the Cache.
27
+ // Actually, the cache can provide a mesh whose geometry is null.
28
+ // see https://github.com/iTowns/itowns/issues/869
29
+ // obj.geometry = null;
30
+ }
31
+ if (obj.material) {
32
+ if (Array.isArray(obj.material)) {
33
+ for (const material of obj.material) {
34
+ disposeSingleMaterialAndTextures(material);
35
+ }
36
+ } else {
37
+ disposeSingleMaterialAndTextures(obj.material);
38
+ }
39
+ }
40
+ obj.dispatchEvent({
41
+ type: 'dispose'
42
+ });
43
+ }
44
+ },
45
+ /**
46
+ * Remove obj's children belonging to a layer.
47
+ * Neither obj nor its children will be disposed!
48
+ * @param {Layer} layer The layer that objects must belong to. Other object are ignored
49
+ * @param {Object3D} obj The Object3D we want to clean
50
+ * @return {Array} an array of removed Object3D from obj (not including the recursive removals)
51
+ */
52
+ removeChildren(layer, obj) {
53
+ const toRemove = obj.children.filter(c => (c.layer && c.layer.id) === layer.id);
54
+ obj.remove(...toRemove);
55
+ return toRemove;
56
+ },
57
+ /**
58
+ * Remove an obj and all its children belonging to a layer and only cleanup the obj (and not its children).
59
+ * obj will be disposed but its children **won't**!
60
+ * @param {Layer} layer The layer that objects must belong to. Other object are ignored
61
+ * @param {Object3D} obj The Object3D we want to clean
62
+ * @return {Array} an array of removed Object3D from obj (not including the recursive removals)
63
+ */
64
+ removeChildrenAndCleanup(layer, obj) {
65
+ const toRemove = obj.children.filter(c => (c.layer && c.layer.id) === layer.id);
66
+ obj.remove(...toRemove);
67
+ if (obj.layer === layer) {
68
+ this.cleanup(obj);
69
+ }
70
+ return toRemove;
71
+ },
72
+ /**
73
+ * Recursively remove an obj and all its children belonging to a layer.
74
+ * All removed obj will have their geometry/material disposed.
75
+ * @param {Layer} layer The layer that objects must belong to. Other object are ignored
76
+ * @param {Object3D} obj The Object3D we want to clean
77
+ * @return {Array} an array of removed Object3D from obj (not including the recursive removals)
78
+ */
79
+ removeChildrenAndCleanupRecursively(layer, obj) {
80
+ // Objects are filtered by id because the obj hierarchy may also contain labels that have been added as childs
81
+ // of the objects which have their own removal logic
82
+ let toRemove = obj.children.filter(c => c.layer && c.layer.id === layer.id);
83
+ const linked = obj.link && obj.link[layer.id];
84
+ if (linked?.children.length) {
85
+ toRemove = toRemove.concat(linked.children);
86
+ delete obj.link[layer.id];
87
+ }
88
+ for (const c of toRemove) {
89
+ this.removeChildrenAndCleanupRecursively(layer, c);
90
+ }
91
+ obj.remove(...toRemove);
92
+ if (obj.layer && obj.layer.id === layer.id) {
93
+ this.cleanup(obj);
94
+ }
95
+ return toRemove;
96
+ }
97
+ };
@@ -0,0 +1,23 @@
1
+ // max retry loading before changing the status to definitiveError
2
+ const MAX_RETRY = 4;
3
+ export default function handlingError(err, node, layer, targetLevel, view) {
4
+ // Cancel error handling if the layer was removed between command scheduling and its execution
5
+ if (!node.layerUpdateState[layer.id]) {
6
+ return;
7
+ }
8
+ if (err.isCancelledCommandException) {
9
+ node.layerUpdateState[layer.id].success();
10
+ } else if (err instanceof SyntaxError) {
11
+ node.layerUpdateState[layer.id].failure(0, true);
12
+ } else {
13
+ const definitiveError = node.layerUpdateState[layer.id].errorCount > MAX_RETRY;
14
+ node.layerUpdateState[layer.id].failure(Date.now(), definitiveError, {
15
+ targetLevel
16
+ });
17
+ if (!definitiveError) {
18
+ window.setTimeout(() => {
19
+ view.notifyChange(node, false);
20
+ }, node.layerUpdateState[layer.id].secondsUntilNextTry() * 1000);
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,149 @@
1
+ import * as THREE from 'three';
2
+ import B3dmParser from "../Parser/B3dmParser.js";
3
+ import PntsParser from "../Parser/PntsParser.js";
4
+ import Fetcher from "./Fetcher.js";
5
+ import ReferLayerProperties from "../Layer/ReferencingLayerProperties.js";
6
+ import PointsMaterial from "../Renderer/PointsMaterial.js";
7
+ // A bit weird but temporary until we remove this deprecated provider. Mainly to benefit from the enableDracoLoader and enableKtx2Loader
8
+ // methods.
9
+ import { itownsGLTFLoader } from "../Layer/OGC3DTilesLayer.js";
10
+ const utf8Decoder = new TextDecoder();
11
+ function b3dmToMesh(data, layer, url) {
12
+ const urlBase = THREE.LoaderUtils.extractUrlBase(url);
13
+ const options = {
14
+ gltfUpAxis: layer.tileset.asset.gltfUpAxis,
15
+ urlBase,
16
+ overrideMaterials: layer.overrideMaterials,
17
+ doNotPatchMaterial: layer.doNotPatchMaterial,
18
+ registeredExtensions: layer.registeredExtensions,
19
+ layer
20
+ };
21
+ return B3dmParser.parse(data, options).then(result => {
22
+ const batchTable = result.batchTable;
23
+ // object3d is actually a THREE.Scene
24
+ const object3d = result.gltf.scene;
25
+ return {
26
+ batchTable,
27
+ object3d
28
+ };
29
+ });
30
+ }
31
+ function gltfToMesh(data, layer, url) {
32
+ const urlBase = THREE.LoaderUtils.extractUrlBase(url);
33
+ return itownsGLTFLoader.parseAsync(data, urlBase).then(result => ({
34
+ object3d: result.scene
35
+ }));
36
+ }
37
+ function pntsParse(data, layer) {
38
+ return PntsParser.parse(data, layer.registeredExtensions).then(result => {
39
+ const material = layer.material ? layer.material.clone() : new PointsMaterial({
40
+ size: 1,
41
+ mode: layer.pntsMode,
42
+ shape: layer.pntsShape,
43
+ classificationScheme: layer.classification,
44
+ sizeMode: layer.pntsSizeMode,
45
+ minAttenuatedSize: layer.pntsMinAttenuatedSize,
46
+ maxAttenuatedSize: layer.pntsMaxAttenuatedSize
47
+ });
48
+
49
+ // refer material properties in the layer so when layers opacity and visibility is updated, the material is
50
+ // automatically updated
51
+ ReferLayerProperties(material, layer);
52
+
53
+ // creation points with geometry and material
54
+ const points = new THREE.Points(result.point.geometry, material);
55
+ if (result.point.offset) {
56
+ points.position.copy(result.point.offset);
57
+ }
58
+ return {
59
+ object3d: points,
60
+ batchTable: result.batchTable
61
+ };
62
+ });
63
+ }
64
+ export function configureTile(tile, layer, metadata, parent) {
65
+ tile.frustumCulled = false;
66
+ tile.layer = layer;
67
+
68
+ // parse metadata
69
+ if (metadata.transform) {
70
+ tile.applyMatrix4(metadata.transform);
71
+ }
72
+ tile.geometricError = metadata.geometricError;
73
+ tile.tileId = metadata.tileId;
74
+ if (metadata.refine) {
75
+ tile.additiveRefinement = metadata.refine.toUpperCase() === 'ADD';
76
+ } else {
77
+ tile.additiveRefinement = parent ? parent.additiveRefinement : false;
78
+ }
79
+ tile.viewerRequestVolume = metadata.viewerRequestVolume;
80
+ tile.boundingVolume = metadata.boundingVolume;
81
+ tile.updateMatrixWorld();
82
+ }
83
+ function executeCommand(command) {
84
+ const layer = command.layer;
85
+ const metadata = command.metadata;
86
+ const tile = new THREE.Object3D();
87
+ configureTile(tile, layer, metadata, command.requester);
88
+ // Patch for supporting 3D Tiles pre 1.0 (metadata.content.url) and 1.0
89
+ // (metadata.content.uri)
90
+ const path = metadata.content && (metadata.content.url || metadata.content.uri);
91
+ const setLayer = obj => {
92
+ obj.userData.metadata = metadata;
93
+ obj.layer = layer;
94
+ };
95
+ if (path) {
96
+ // Check if we have relative or absolute url (with tileset's lopocs for example)
97
+ let url = path.startsWith('http') ? path : metadata.baseURL + path;
98
+ if (layer.source.isC3DTilesGoogleSource) {
99
+ url = layer.source.getTileUrl(url);
100
+ }
101
+ const supportedFormats = {
102
+ b3dm: b3dmToMesh,
103
+ pnts: pntsParse,
104
+ gltf: gltfToMesh
105
+ };
106
+ return Fetcher.arrayBuffer(url, layer.source.networkOptions).then(result => {
107
+ if (result !== undefined) {
108
+ let func;
109
+ const magic = utf8Decoder.decode(new Uint8Array(result, 0, 4));
110
+ if (magic[0] === '{') {
111
+ result = JSON.parse(utf8Decoder.decode(new Uint8Array(result)));
112
+ // Another specifics of 3D tiles from Google: tilesets in tilesets are required from the root base
113
+ // url and not from their parent base url
114
+ const newPrefix = layer.source.isC3DTilesGoogleSource ? layer.source.baseUrl : url.slice(0, url.lastIndexOf('/') + 1);
115
+ layer.tileset.extendTileset(result, metadata.tileId, newPrefix, layer.registeredExtensions);
116
+ } else if (magic == 'b3dm') {
117
+ func = supportedFormats.b3dm;
118
+ } else if (magic == 'pnts') {
119
+ layer.hasPnts = true;
120
+ func = supportedFormats.pnts;
121
+ } else if (magic == 'glTF') {
122
+ func = supportedFormats.gltf;
123
+ } else {
124
+ return Promise.reject(`Unsupported magic code ${magic}`);
125
+ }
126
+ if (func) {
127
+ // TODO: request should be delayed if there is a viewerRequestVolume
128
+ return func(result, layer, url).then(content => {
129
+ tile.content = content.object3d;
130
+ if (content.batchTable) {
131
+ tile.batchTable = content.batchTable;
132
+ }
133
+ tile.add(content.object3d);
134
+ tile.traverse(setLayer);
135
+ return tile;
136
+ });
137
+ }
138
+ }
139
+ tile.traverse(setLayer);
140
+ return tile;
141
+ });
142
+ } else {
143
+ tile.traverse(setLayer);
144
+ return Promise.resolve(tile);
145
+ }
146
+ }
147
+ export default {
148
+ executeCommand
149
+ };
@@ -0,0 +1,24 @@
1
+ export default {
2
+ executeCommand(command) {
3
+ const layer = command.layer;
4
+ const src = command.extentsSource;
5
+ const dst = command.extentsDestination || src;
6
+ const promises = src.map((from, i) => layer.getData(from, dst[i]));
7
+
8
+ // partialLoading sets the return promise as fulfilled if at least one sub-promise is fulfilled
9
+ // It waits until all promises are resolved
10
+ if (command.partialLoading) {
11
+ return Promise.allSettled(promises).then(results => {
12
+ const anyFulfilledPromise = results.find(promise => promise.status === 'fulfilled');
13
+ if (!anyFulfilledPromise) {
14
+ // All promises failed -> reject
15
+ return Promise.reject(new Error('Failed to load any data'));
16
+ }
17
+ return results.map(prom => prom.value ? prom.value : null);
18
+ });
19
+ }
20
+
21
+ // Without partialLoading, the return promise is rejected as soon as any sub-promise is rejected
22
+ return Promise.all(promises);
23
+ }
24
+ };