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,459 @@
1
+ import * as THREE from 'three';
2
+ import GeometryLayer from "./GeometryLayer.js";
3
+ import { init3dTilesLayer, pre3dTilesUpdate, process3dTilesNode } from "../Process/3dTilesProcessing.js";
4
+ import C3DTileset from "../Core/3DTiles/C3DTileset.js";
5
+ import C3DTExtensions from "../Core/3DTiles/C3DTExtensions.js";
6
+ import { PNTS_MODE, PNTS_SHAPE, PNTS_SIZE_MODE } from "../Renderer/PointsMaterial.js";
7
+ // eslint-disable-next-line no-unused-vars
8
+ import Style from "../Core/Style.js";
9
+ import C3DTFeature from "../Core/3DTiles/C3DTFeature.js";
10
+ import { optimizeGeometryGroups } from "../Utils/ThreeUtils.js";
11
+ export const C3DTILES_LAYER_EVENTS = {
12
+ /**
13
+ * Fires when a tile content has been loaded
14
+ * @event C3DTilesLayer#on-tile-content-loaded
15
+ * @type {object}
16
+ * @property {THREE.Object3D} tileContent - object3D of the tile
17
+ */
18
+ ON_TILE_CONTENT_LOADED: 'on-tile-content-loaded',
19
+ /**
20
+ * Fires when a tile is requested
21
+ * @event C3DTilesLayer#on-tile-requested
22
+ * @type {object}
23
+ * @property {object} metadata - tile
24
+ */
25
+ ON_TILE_REQUESTED: 'on-tile-requested'
26
+ };
27
+ const update = process3dTilesNode();
28
+
29
+ /**
30
+ * Find tileId of object
31
+ * @param {THREE.Object3D} object - object
32
+ *
33
+ * @returns {number} tileId
34
+ */
35
+ function findTileID(object) {
36
+ let currentObject = object;
37
+ let result = currentObject.tileId;
38
+ while (isNaN(result) && currentObject.parent) {
39
+ currentObject = currentObject.parent;
40
+ result = currentObject.tileId;
41
+ }
42
+ return result;
43
+ }
44
+
45
+ /**
46
+ * Check if object3d has feature
47
+ * @param {THREE.Object3D} object3d - object3d to check
48
+ *
49
+ * @returns {boolean} - true if object3d has feature
50
+ */
51
+ function object3DHasFeature(object3d) {
52
+ return object3d.geometry && object3d.geometry.attributes._BATCHID;
53
+ }
54
+
55
+ /**
56
+ * @extends GeometryLayer
57
+ */
58
+ class C3DTilesLayer extends GeometryLayer {
59
+ #fillColorMaterialsBuffer;
60
+ /**
61
+ * @deprecated Deprecated 3D Tiles layer. Use {@link OGC3DTilesLayer} instead.
62
+ *
63
+ * @example
64
+ * // Create a new 3d-tiles layer from a web server
65
+ * const l3dt = new C3DTilesLayer('3dtiles', {
66
+ * name: '3dtl',
67
+ * source: new C3DTilesSource({
68
+ * url: 'https://tileset.json'
69
+ * })
70
+ * }, view);
71
+ * View.prototype.addLayer.call(view, l3dt);
72
+ *
73
+ * // Create a new 3d-tiles layer from a Cesium ion server
74
+ * const l3dt = new C3DTilesLayer('3dtiles', {
75
+ * name: '3dtl',
76
+ * source: new C3DTilesIonSource({
77
+ * accessToken: 'myAccessToken',
78
+ assetId: 12
79
+ * })
80
+ * }, view);
81
+ * View.prototype.addLayer.call(view, l3dt);
82
+ *
83
+ * @param {string} id - The id of the layer, that should be unique.
84
+ * It is not mandatory, but an error will be emitted if this layer is
85
+ * added a
86
+ * {@link View} that already has a layer going by that id.
87
+ * @param {object} config configuration, all elements in it
88
+ * will be merged as is in the layer.
89
+ * @param {C3DTilesSource} config.source The source of 3d Tiles.
90
+ *
91
+ * name.
92
+ * @param {Number} [config.sseThreshold=16] The [Screen Space Error](https://github.com/CesiumGS/3d-tiles/blob/main/specification/README.md#geometric-error)
93
+ * threshold at which child nodes of the current node will be loaded and added to the scene.
94
+ * @param {Number} [config.cleanupDelay=1000] The time (in ms) after which a tile content (and its children) are
95
+ * removed from the scene.
96
+ * @param {C3DTExtensions} [config.registeredExtensions] 3D Tiles extensions managers registered for this tileset.
97
+ * @param {String} [config.pntsMode= PNTS_MODE.COLOR] {@link PointsMaterial} Point cloud coloring mode.
98
+ * Only 'COLOR' or 'CLASSIFICATION' are possible. COLOR uses RGB colors of the points,
99
+ * CLASSIFICATION uses a classification property of the batch table to color points.
100
+ * @param {String} [config.pntsShape= PNTS_SHAPE.CIRCLE] Point cloud point shape. Only 'CIRCLE' or 'SQUARE' are possible.
101
+ * @param {String} [config.pntsSizeMode= PNTS_SIZE_MODE.VALUE] {@link PointsMaterial} Point cloud size mode. Only 'VALUE' or 'ATTENUATED' are possible. VALUE use constant size, ATTENUATED compute size depending on distance from point to camera.
102
+ * @param {Number} [config.pntsMinAttenuatedSize=3] Minimum scale used by 'ATTENUATED' size mode
103
+ * @param {Number} [config.pntsMaxAttenuatedSize=10] Maximum scale used by 'ATTENUATED' size mode
104
+ * @param {Style} [config.style=null] - style used for this layer
105
+ * @param {View} view The view
106
+ */
107
+ constructor(id, config, view) {
108
+ console.warn('C3DTilesLayer is deprecated and will be removed in iTowns 3.0 version. Use OGC3DTilesLayer instead.');
109
+ super(id, new THREE.Group(), {
110
+ source: config.source
111
+ });
112
+ this.isC3DTilesLayer = true;
113
+ this.sseThreshold = config.sseThreshold || 16;
114
+ this.cleanupDelay = config.cleanupDelay || 1000;
115
+ this.protocol = '3d-tiles';
116
+ this.name = config.name;
117
+ this.registeredExtensions = config.registeredExtensions || new C3DTExtensions();
118
+ this.pntsMode = PNTS_MODE.COLOR;
119
+ this.pntsShape = PNTS_SHAPE.CIRCLE;
120
+ this.classification = config.classification;
121
+ this.pntsSizeMode = PNTS_SIZE_MODE.VALUE;
122
+ this.pntsMinAttenuatedSize = config.pntsMinAttenuatedSize || 1;
123
+ this.pntsMaxAttenuatedSize = config.pntsMaxAttenuatedSize || 7;
124
+ if (config.pntsMode) {
125
+ const exists = Object.values(PNTS_MODE).includes(config.pntsMode);
126
+ if (!exists) {
127
+ console.warn("The points cloud mode doesn't exist. Use 'COLOR' or 'CLASSIFICATION' instead.");
128
+ } else {
129
+ this.pntsMode = config.pntsMode;
130
+ }
131
+ }
132
+ if (config.pntsShape) {
133
+ const exists = Object.values(PNTS_SHAPE).includes(config.pntsShape);
134
+ if (!exists) {
135
+ console.warn("The points cloud point shape doesn't exist. Use 'CIRCLE' or 'SQUARE' instead.");
136
+ } else {
137
+ this.pntsShape = config.pntsShape;
138
+ }
139
+ }
140
+ if (config.pntsSizeMode) {
141
+ const exists = Object.values(PNTS_SIZE_MODE).includes(config.pntsSizeMode);
142
+ if (!exists) {
143
+ console.warn("The points cloud size mode doesn't exist. Use 'VALUE' or 'ATTENUATED' instead.");
144
+ } else {
145
+ this.pntsSizeMode = config.pntsSizeMode;
146
+ }
147
+ }
148
+
149
+ /** @type {Style | null} */
150
+ this._style = config.style || null;
151
+
152
+ /** @type {Map<string, THREE.MeshStandardMaterial>} */
153
+ this.#fillColorMaterialsBuffer = new Map();
154
+
155
+ /**
156
+ * Map all C3DTFeature of the layer according their tileId and their batchId
157
+ * Map< tileId, Map< batchId, C3DTFeature>>
158
+ *
159
+ * @type {Map<number, Map<number,C3DTFeature>>}
160
+ */
161
+ this.tilesC3DTileFeatures = new Map();
162
+ if (config.onTileContentLoaded) {
163
+ console.warn('DEPRECATED onTileContentLoaded should not be passed at the contruction, use C3DTILES_LAYER_EVENTS.ON_TILE_CONTENT_LOADED event instead');
164
+ this.addEventListener(C3DTILES_LAYER_EVENTS.ON_TILE_CONTENT_LOADED, config.onTileContentLoaded);
165
+ }
166
+ if (config.overrideMaterials) {
167
+ console.warn('overrideMaterials is deprecated, use style API instead');
168
+ this.overrideMaterials = config.overrideMaterials;
169
+ }
170
+ this._cleanableTiles = [];
171
+ const resolve = this.addInitializationStep();
172
+ this.source.whenReady.then(tileset => {
173
+ this.tileset = new C3DTileset(tileset, this.source.baseUrl, this.registeredExtensions);
174
+ // Verify that extensions of the tileset have been registered in the layer
175
+ if (this.tileset.extensionsUsed) {
176
+ for (const extensionUsed of this.tileset.extensionsUsed) {
177
+ // if current extension is not registered
178
+ if (!this.registeredExtensions.isExtensionRegistered(extensionUsed)) {
179
+ // if it is required to load the tileset
180
+ if (this.tileset.extensionsRequired && this.tileset.extensionsRequired.includes(extensionUsed)) {
181
+ console.error(`3D Tiles tileset required extension "${extensionUsed}" must be registered to the 3D Tiles layer of iTowns to be parsed and used.`);
182
+ } else {
183
+ console.warn(`3D Tiles tileset used extension "${extensionUsed}" must be registered to the 3D Tiles layer of iTowns to be parsed and used.`);
184
+ }
185
+ }
186
+ }
187
+ }
188
+ // TODO: Move all init3dTilesLayer code to constructor
189
+ init3dTilesLayer(view, view.mainLoop.scheduler, this, tileset.root).then(resolve);
190
+ });
191
+ }
192
+ preUpdate(context) {
193
+ return pre3dTilesUpdate.bind(this)(context);
194
+ }
195
+ update(context, layer, node) {
196
+ return update(context, layer, node);
197
+ }
198
+ getObjectToUpdateForAttachedLayers(meta) {
199
+ if (meta.content) {
200
+ const result = [];
201
+ meta.content.traverse(obj => {
202
+ if (obj.isObject3D && obj.material && obj.layer == meta.layer) {
203
+ result.push(obj);
204
+ }
205
+ });
206
+ const p = meta.parent;
207
+ if (p && p.content) {
208
+ return {
209
+ elements: result,
210
+ parent: p.content
211
+ };
212
+ } else {
213
+ return {
214
+ elements: result
215
+ };
216
+ }
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Get the closest c3DTileFeature of an intersects array.
222
+ * @param {Array} intersects - @return An array containing all
223
+ * targets picked under specified coordinates. Intersects can be
224
+ * computed with view.pickObjectsAt(..). See fillHTMLWithPickingInfo()
225
+ * in 3dTilesHelper.js for an example.
226
+ *
227
+ * @returns {C3DTileFeature} - the closest C3DTileFeature of the intersects array
228
+ */
229
+ getC3DTileFeatureFromIntersectsArray(intersects) {
230
+ // find closest intersect with an attributes _BATCHID + face != undefined
231
+ let closestIntersect = null;
232
+ for (let index = 0; index < intersects.length; index++) {
233
+ const i = intersects[index];
234
+ if (i.object.geometry && i.object.geometry.attributes._BATCHID && i.face &&
235
+ // need face to get batch id
236
+ i.layer == this // just to be sure that the right layer intersected
237
+ ) {
238
+ closestIntersect = i;
239
+ break;
240
+ }
241
+ }
242
+ if (!closestIntersect) {
243
+ return null;
244
+ }
245
+ const tileId = findTileID(closestIntersect.object);
246
+ // face is a Face3 object of THREE which is a
247
+ // triangular face. face.a is its first vertex
248
+ const vertex = closestIntersect.face.a;
249
+ const batchID = closestIntersect.object.geometry.attributes._BATCHID.getX(vertex);
250
+ return this.tilesC3DTileFeatures.get(tileId).get(batchID);
251
+ }
252
+
253
+ /**
254
+ * Called when a tile content is loaded
255
+ * @param {THREE.Object3D} tileContent - tile as THREE.Object3D
256
+ */
257
+ onTileContentLoaded(tileContent) {
258
+ this.initC3DTileFeatures(tileContent);
259
+
260
+ // notify observer
261
+ this.dispatchEvent({
262
+ type: C3DTILES_LAYER_EVENTS.ON_TILE_CONTENT_LOADED,
263
+ tileContent
264
+ });
265
+
266
+ // only update style of tile features
267
+ this.updateStyle([tileContent.tileId]);
268
+ }
269
+
270
+ /**
271
+ * Initialize C3DTileFeatures from tileContent
272
+ * @param {THREE.Object3D} tileContent - tile as THREE.Object3D
273
+ */
274
+ initC3DTileFeatures(tileContent) {
275
+ this.tilesC3DTileFeatures.set(tileContent.tileId, new Map()); // initialize
276
+ tileContent.traverse(child => {
277
+ if (object3DHasFeature(child)) {
278
+ const batchIdAttribute = child.geometry.getAttribute('_BATCHID');
279
+ let currentBatchId = batchIdAttribute.getX(0);
280
+ let start = 0;
281
+ let count = 0;
282
+ const registerBatchIdGroup = () => {
283
+ if (this.tilesC3DTileFeatures.get(tileContent.tileId).has(currentBatchId)) {
284
+ // already created
285
+ const c3DTileFeature = this.tilesC3DTileFeatures.get(tileContent.tileId).get(currentBatchId);
286
+ // add new group
287
+ c3DTileFeature.groups.push({
288
+ start,
289
+ count
290
+ });
291
+ } else {
292
+ // first occurence
293
+ const c3DTileFeature = new C3DTFeature(tileContent.tileId, currentBatchId, [{
294
+ start,
295
+ count
296
+ }],
297
+ // initialize with current group
298
+ {}, child);
299
+ this.tilesC3DTileFeatures.get(tileContent.tileId).set(currentBatchId, c3DTileFeature);
300
+ }
301
+ };
302
+
303
+ // TODO: Could be simplified by incrementing of 1 and stopping the iteration at positionAttributeSize.count
304
+ // See https://github.com/iTowns/itowns/pull/2266#discussion_r1483285122
305
+ const positionAttribute = child.geometry.getAttribute('position');
306
+ const positionAttributeSize = positionAttribute.count * positionAttribute.itemSize;
307
+ for (let index = 0; index < positionAttributeSize; index += positionAttribute.itemSize) {
308
+ const batchIndex = index / positionAttribute.itemSize;
309
+ const batchId = batchIdAttribute.getX(batchIndex);
310
+
311
+ // check if batchId is currentBatchId
312
+ if (currentBatchId !== batchId) {
313
+ registerBatchIdGroup();
314
+
315
+ // reset
316
+ currentBatchId = batchId;
317
+ start = batchIndex;
318
+ count = 0;
319
+ }
320
+
321
+ // record this position in current C3DTileFeature
322
+ count++;
323
+
324
+ // check if end of the array
325
+ if (index + positionAttribute.itemSize >= positionAttributeSize) {
326
+ registerBatchIdGroup();
327
+ }
328
+ }
329
+ }
330
+ });
331
+ }
332
+
333
+ /**
334
+ * Update style of the C3DTFeatures, an allowList of tile id can be passed to only update certain tile.
335
+ * Note that this function only update THREE.Object3D materials, in order to see style changes you should call view.notifyChange()
336
+ * @param {Array<number>|null} [allowTileIdList] - tile ids to allow in updateStyle computation if null all tiles are updated
337
+ *
338
+ * @returns {boolean} true if style updated false otherwise
339
+ */
340
+ updateStyle() {
341
+ let allowTileIdList = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
342
+ if (!this._style) {
343
+ return false;
344
+ }
345
+ if (!this.object3d) {
346
+ return false;
347
+ }
348
+ const currentMaterials = []; // list materials used for this update
349
+
350
+ const mapObjects3d = new Map();
351
+ this.object3d.traverse(child => {
352
+ if (object3DHasFeature(child)) {
353
+ const tileId = findTileID(child);
354
+ if (allowTileIdList && !allowTileIdList.includes(tileId)) {
355
+ return; // this tileId is not updated
356
+ }
357
+
358
+ // push for update style
359
+ if (!mapObjects3d.has(tileId)) {
360
+ mapObjects3d.set(tileId, []);
361
+ }
362
+ mapObjects3d.get(tileId).push(child);
363
+ }
364
+ });
365
+ for (const [tileId, objects3d] of mapObjects3d) {
366
+ const c3DTileFeatures = this.tilesC3DTileFeatures.get(tileId); // features of this tile
367
+ objects3d.forEach(object3d => {
368
+ // clear
369
+ object3d.geometry.clearGroups();
370
+ object3d.material = [];
371
+ for (const [, c3DTileFeature] of c3DTileFeatures) {
372
+ if (c3DTileFeature.object3d != object3d) {
373
+ continue; // this feature do not belong to object3d
374
+ }
375
+ this._style.context.setGeometry({
376
+ properties: c3DTileFeature
377
+ });
378
+
379
+ /** @type {THREE.Color} */
380
+ const color = new THREE.Color(this._style.fill.color);
381
+
382
+ /** @type {number} */
383
+ const opacity = this._style.fill.opacity;
384
+ const materialId = color.getHexString() + opacity;
385
+ let material = null;
386
+ if (this.#fillColorMaterialsBuffer.has(materialId)) {
387
+ material = this.#fillColorMaterialsBuffer.get(materialId);
388
+ } else {
389
+ material = new THREE.MeshStandardMaterial({
390
+ color,
391
+ opacity,
392
+ transparent: opacity < 1,
393
+ alphaTest: 0.09
394
+ });
395
+ this.#fillColorMaterialsBuffer.set(materialId, material); // bufferize
396
+ }
397
+
398
+ // compute materialIndex
399
+ let materialIndex = -1;
400
+ for (let index = 0; index < object3d.material.length; index++) {
401
+ const childMaterial = object3d.material[index];
402
+ if (material.uuid === childMaterial.uuid) {
403
+ materialIndex = index;
404
+ break;
405
+ }
406
+ }
407
+ if (materialIndex < 0) {
408
+ // not in object3d.material add it
409
+ object3d.material.push(material);
410
+ materialIndex = object3d.material.length - 1;
411
+ }
412
+
413
+ // materialIndex groups is computed
414
+ c3DTileFeature.groups.forEach(group => {
415
+ object3d.geometry.addGroup(group.start, group.count, materialIndex);
416
+ });
417
+ }
418
+ optimizeGeometryGroups(object3d);
419
+
420
+ // record material(s) used in object3d
421
+ if (object3d.material instanceof Array) {
422
+ object3d.material.forEach(material => {
423
+ if (!currentMaterials.includes(material)) {
424
+ currentMaterials.push(material);
425
+ }
426
+ });
427
+ } else if (!currentMaterials.includes(object3d.material)) {
428
+ currentMaterials.push(object3d.material);
429
+ }
430
+ });
431
+ }
432
+
433
+ // remove buffered materials not in currentMaterials
434
+ for (const [id, fillMaterial] of this.#fillColorMaterialsBuffer) {
435
+ if (!currentMaterials.includes(fillMaterial)) {
436
+ fillMaterial.dispose();
437
+ this.#fillColorMaterialsBuffer.delete(id);
438
+ }
439
+ }
440
+ return true;
441
+ }
442
+ get materialCount() {
443
+ return this.#fillColorMaterialsBuffer.size;
444
+ }
445
+ set style(value) {
446
+ if (value instanceof Style) {
447
+ this._style = value;
448
+ } else if (!value) {
449
+ this._style = null;
450
+ } else {
451
+ this._style = new Style(value);
452
+ }
453
+ this.updateStyle();
454
+ }
455
+ get style() {
456
+ return this._style;
457
+ }
458
+ }
459
+ export default C3DTilesLayer;
@@ -0,0 +1,154 @@
1
+ import RasterLayer from "./RasterLayer.js";
2
+ import { updateLayeredMaterialNodeImagery } from "../Process/LayeredMaterialNodeProcessing.js";
3
+ import { RasterColorTile } from "../Renderer/RasterTile.js";
4
+ import { deprecatedColorLayerOptions } from "../Core/Deprecated/Undeprecator.js";
5
+
6
+ /**
7
+ * Fires when the visiblity of the layer has changed.
8
+ * @event ColorLayer#visible-property-changed
9
+ */
10
+ /**
11
+ * Fires when the opacity of the layer has changed.
12
+ * @event ColorLayer#opacity-property-changed
13
+ */
14
+ /**
15
+ * Fires when the sequence of the layer has changed, meaning that the order of
16
+ * the layer changed in the view it is attached to.
17
+ * @event ColorLayer#sequence-property-changed
18
+ */
19
+
20
+ /**
21
+ * @property {boolean} isColorLayer - Used to checkout whether this layer is a
22
+ * ColorLayer. Default is true. You should not change this, as it is used
23
+ * internally for optimisation.
24
+ * @property {StyleOptions|Style} style - style properties or a Style defined by the user,
25
+ * to apply to the layer features.
26
+ * @property {boolean} visible - property to display or to hide layer.
27
+ * @property {number} opacity - property to adjust transparency, opacity is between 0. and 1.
28
+ * @property {boolean} transparent - specify if the layer could be transparent.
29
+ * @property {boolean} noTextureParentOutsideLimit - don't parent texture if it's outside limit.
30
+ * @property {number} effect_type - type effect to apply on the raster color.
31
+ * If `effect_type` equals:
32
+ * * `0`: no effect.
33
+ * * `1`: light color to invisible effect: transparency effect is stronger for
34
+ * light colors (whose distance is closer to white). This effect can be
35
+ * amplified by `effect_parameter`.
36
+ * * `2`: white color to invisible effect: white color is considered as
37
+ * transparent.
38
+ * * `3`: custom shader effect: set `ShaderChunk.customBodyColorLayer` and
39
+ * `ShaderChunk.customHeaderColorLayer` to add your own glsl code in
40
+ * respectively the color layer function body and at top-level.
41
+ * @property {number} effect_parameter - value used as parameter of certain type
42
+ * of effects. If `effect_type` equals:
43
+ * * `0`: unused.
44
+ * * `1`: used to amplify the transparency effect.
45
+ * * `2`: unused.
46
+ * * `3`: could be used by your own glsl code.
47
+ *
48
+ * @extends RasterLayer
49
+ */
50
+ class ColorLayer extends RasterLayer {
51
+ /**
52
+ * A simple layer, usually managing a texture to display on a view. For example,
53
+ * it can be an aerial view of the ground or a simple transparent layer with the
54
+ * roads displayed.
55
+ *
56
+ * @param {string} id - The id of the layer, that should be unique. It is
57
+ * not mandatory, but an error will be emitted if this layer is added a
58
+ * {@link View} that already has a layer going by that id.
59
+ * @param {Object} [config] - Optional configuration, all elements in it
60
+ * will be merged as is in the layer. For example, if the configuration
61
+ * contains three elements `name, protocol, extent`, these elements will be
62
+ * available using `layer.name` or something else depending on the property
63
+ * name.
64
+ * @param {Source} [config.source] - Description and options of the source.
65
+ * @param {number} [config.magFilter] - How the texture is sampled when a texel covers more than one pixel. [see](https://threejs.org/docs/?q=texture#api/en/textures/Texture.magFilter)
66
+ * @param {number} [config.minFilter] - How the texture is sampled when a texel covers less than one pixel. [see](https://threejs.org/docs/?q=texture#api/en/textures/Texture.minFilter)
67
+ * @param {number} [config.effect_type=0] - type effect to apply on raster color.
68
+ * if `effect_type` equals:
69
+ * * `0`: no special effect.
70
+ * * `1`: light color to invisible effect.
71
+ * * `2`: white color to invisible effect.
72
+ * * `3`: custom shader effect (defined `ShaderChunk.customBodyColorLayer` and `ShaderChunk.customHeaderColorLayer`).
73
+ * @param {number} [config.effect_parameter=1.0] - amount value used with effect applied on raster color.
74
+ *
75
+ * @example
76
+ * // Create a ColorLayer
77
+ * const color = new ColorLayer('roads', {
78
+ * source: new SourceWMTS({
79
+ * protocol: 'wmts',
80
+ * url: 'http://server.geo/wmts/....',
81
+ * format: 'image/png',
82
+ * name: 'nameService',
83
+ * tileMatrixSet: 'PM',
84
+ * }),
85
+ * transparent: true,
86
+ * opacity: 0.5,
87
+ * });
88
+ *
89
+ * // Add the layer
90
+ * view.addLayer(color);
91
+ */
92
+ constructor(id) {
93
+ let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
94
+ deprecatedColorLayerOptions(config);
95
+ const {
96
+ effect_type = 0,
97
+ effect_parameter = 1.0,
98
+ transparent,
99
+ ...rasterConfig
100
+ } = config;
101
+ super(id, rasterConfig);
102
+
103
+ /**
104
+ * @type {boolean}
105
+ * @readonly
106
+ */
107
+ this.isColorLayer = true;
108
+
109
+ /**
110
+ * @type {boolean}
111
+ */
112
+ this.visible = true;
113
+ this.defineLayerProperty('visible', this.visible);
114
+
115
+ /**
116
+ * @type {number}
117
+ */
118
+ this.opacity = 1.0;
119
+ this.defineLayerProperty('opacity', this.opacity);
120
+
121
+ /**
122
+ * @type {number}
123
+ */
124
+ this.sequence = 0;
125
+ this.defineLayerProperty('sequence', this.sequence);
126
+ this.transparent = transparent || this.opacity < 1.0;
127
+ this.noTextureParentOutsideLimit = config.source ? config.source.isFileSource : false;
128
+ this.effect_type = effect_type;
129
+ this.effect_parameter = effect_parameter;
130
+
131
+ // Feature options
132
+ this.buildExtent = true;
133
+ this.structure = '2d';
134
+ }
135
+
136
+ /**
137
+ * Setup RasterColorTile added to TileMesh. This RasterColorTile handles
138
+ * the ColorLayer textures mapped on this TileMesh.
139
+ *
140
+ * @param {TileMesh} node The node to apply new RasterColorTile;
141
+ * @return {RasterColorTile} The raster color node added.
142
+ */
143
+ setupRasterNode(node) {
144
+ const rasterColorNode = new RasterColorTile(node.material, this);
145
+ node.material.addLayer(rasterColorNode);
146
+ // set up ColorLayer ordering.
147
+ node.material.setSequence(this.parent.colorLayersOrder);
148
+ return rasterColorNode;
149
+ }
150
+ update(context, layer, node, parent) {
151
+ return updateLayeredMaterialNodeImagery(context, this, node, parent);
152
+ }
153
+ }
154
+ export default ColorLayer;
@@ -0,0 +1,63 @@
1
+ import * as THREE from 'three';
2
+ import CopcNode from "../Core/CopcNode.js";
3
+ import PointCloudLayer from "./PointCloudLayer.js";
4
+
5
+ /**
6
+ * A layer for [Cloud Optimised Point Cloud](https://copc.io) (COPC) datasets.
7
+ * See {@link PointCloudLayer} class for documentation on base properties.
8
+ *
9
+ * @extends {PointCloudLayer}
10
+ *
11
+ * @example
12
+ * // Create a new COPC layer
13
+ * const copcSource = new CopcSource({
14
+ * url: 'https://s3.amazonaws.com/hobu-lidar/autzen-classified.copc.laz',
15
+ * crs: 'EPSG:4978',
16
+ * colorDepth: 16, // bit-depth of 'color' attribute (either 8 or 16 bits)
17
+ * });
18
+ *
19
+ * const copcLayer = new CopcLayer('COPC', {
20
+ * source: copcSource,
21
+ * });
22
+ *
23
+ * View.prototype.addLayer.call(view, copcLayer);
24
+ */
25
+ class CopcLayer extends PointCloudLayer {
26
+ /**
27
+ * @param {string} id - Unique id of the layer.
28
+ * @param {Object} config - See {@link PointCloudLayer} for base pointcloud
29
+ * options.
30
+ */
31
+ constructor(id, config) {
32
+ super(id, config);
33
+
34
+ /**
35
+ * @type {boolean}
36
+ * @readonly
37
+ */
38
+ this.isCopcLayer = true;
39
+ const resolve = () => this;
40
+ this.whenReady = this.source.whenReady.then((/** @type {CopcSource} */source) => {
41
+ const {
42
+ cube,
43
+ rootHierarchyPage
44
+ } = source.info;
45
+ const {
46
+ pageOffset,
47
+ pageLength
48
+ } = rootHierarchyPage;
49
+ this.root = new CopcNode(0, 0, 0, 0, pageOffset, pageLength, this, -1);
50
+ this.root.bbox.min.fromArray(cube, 0);
51
+ this.root.bbox.max.fromArray(cube, 3);
52
+ this.minElevationRange = this.minElevationRange ?? source.header.min[2];
53
+ this.maxElevationRange = this.maxElevationRange ?? source.header.max[2];
54
+ this.scale = new THREE.Vector3(1.0, 1.0, 1.0);
55
+ this.offset = new THREE.Vector3(0.0, 0.0, 0.0);
56
+ return this.root.loadOctree().then(resolve);
57
+ });
58
+ }
59
+ get spacing() {
60
+ return this.source.info.spacing;
61
+ }
62
+ }
63
+ export default CopcLayer;