@cesium/engine 7.0.0 → 9.0.0

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 (200) hide show
  1. package/Build/ThirdParty/Workers/z-worker-pako.js +1 -5
  2. package/Build/Workers/{chunk-7XEAYGZK.js → chunk-24YTYWNB.js} +10 -10
  3. package/Build/Workers/{chunk-IQBYFRVW.js → chunk-2632RVPI.js} +7 -7
  4. package/Build/Workers/chunk-2KACWKS4.js +501 -0
  5. package/Build/Workers/{chunk-QZAD5O7I.js → chunk-2XPLH3JY.js} +7 -7
  6. package/Build/Workers/{chunk-JY5YEZFA.js → chunk-2ZBL3MVO.js} +8 -8
  7. package/Build/Workers/{chunk-ZK5JOS3D.js → chunk-3NCVAGDA.js} +14 -14
  8. package/Build/Workers/{chunk-AR5DNBJ4.js → chunk-5R6VWLMH.js} +6 -6
  9. package/Build/Workers/{chunk-PTQQUQC3.js → chunk-5TIV3L26.js} +13 -13
  10. package/Build/Workers/{chunk-BZP4T2JJ.js → chunk-6WF3KIF5.js} +10 -10
  11. package/Build/Workers/{chunk-5WQ523AW.js → chunk-73FKKY52.js} +5 -5
  12. package/Build/Workers/{chunk-F6SE42BK.js → chunk-7COR472O.js} +15 -472
  13. package/Build/Workers/{chunk-72SANQJV.js → chunk-ADOVHYWO.js} +9 -5
  14. package/Build/Workers/{chunk-5YLJ77FF.js → chunk-BCU2LH5T.js} +12 -11
  15. package/Build/Workers/{chunk-4EBHOMFX.js → chunk-C3XBUYBO.js} +17 -17
  16. package/Build/Workers/{chunk-IX2JCCNM.js → chunk-C6OI26DR.js} +1 -1
  17. package/Build/Workers/{chunk-2HJWSU7B.js → chunk-CO35JNNE.js} +4 -4
  18. package/Build/Workers/{chunk-OVLG3FRS.js → chunk-DGDUKCJJ.js} +6 -6
  19. package/Build/Workers/{chunk-DTAIXKTO.js → chunk-DPUSFA7S.js} +6 -6
  20. package/Build/Workers/{chunk-R5X4OQT4.js → chunk-E6WXPSJS.js} +7 -7
  21. package/Build/Workers/{chunk-VK3EJHWI.js → chunk-EOXYZ34O.js} +2 -2
  22. package/Build/Workers/{chunk-RAEV7K66.js → chunk-EPKE7GE3.js} +5 -5
  23. package/Build/Workers/{chunk-GV56Q4LU.js → chunk-GFA4SMXV.js} +11 -11
  24. package/Build/Workers/{chunk-NKPBIX7F.js → chunk-GXUXEOE2.js} +1 -1
  25. package/Build/Workers/{chunk-NY3K4IM3.js → chunk-HBQPB6IH.js} +12 -12
  26. package/Build/Workers/{chunk-6HZQPRUS.js → chunk-I37B3MZ2.js} +1 -1
  27. package/Build/Workers/{chunk-VRGFV2UO.js → chunk-L4BW3RUA.js} +10 -10
  28. package/Build/Workers/{chunk-6VJVYK2V.js → chunk-LAQP3SCC.js} +2 -2
  29. package/Build/Workers/{chunk-PNBGBETF.js → chunk-LQJ5FFFR.js} +10 -10
  30. package/Build/Workers/{chunk-UAEW6HKG.js → chunk-M2AYBTNH.js} +13 -13
  31. package/Build/Workers/{chunk-YUCVWAY6.js → chunk-MWV7IZK4.js} +7 -7
  32. package/Build/Workers/{chunk-JXDC723O.js → chunk-N4KXMWQU.js} +2 -2
  33. package/Build/Workers/{chunk-XWXM2O2R.js → chunk-NP2GYYE5.js} +6 -6
  34. package/Build/Workers/{chunk-GEJTYLCO.js → chunk-NZWNZA6S.js} +5 -5
  35. package/Build/Workers/{chunk-LZGHD6NY.js → chunk-P2YAAMT2.js} +15 -15
  36. package/Build/Workers/{chunk-S6SKF6DT.js → chunk-P4XKB3QZ.js} +5 -5
  37. package/Build/Workers/{chunk-U2VCRRQW.js → chunk-PXB7T27O.js} +6 -6
  38. package/Build/Workers/{chunk-RV7ZYPFT.js → chunk-QCQUZGXI.js} +4 -4
  39. package/Build/Workers/{chunk-JJ4VBOQ3.js → chunk-QKBGRKKG.js} +4 -4
  40. package/Build/Workers/{chunk-ODW7WYM4.js → chunk-RMOEYCZW.js} +2 -2
  41. package/Build/Workers/{chunk-ZUA2UUNV.js → chunk-RSJXEO2A.js} +2 -2
  42. package/Build/Workers/{chunk-UDO6BFSF.js → chunk-RV7ZOSS6.js} +13 -13
  43. package/Build/Workers/{chunk-LZ7JIV3K.js → chunk-SE4PXOEA.js} +17 -17
  44. package/Build/Workers/{chunk-S4MAZ3SS.js → chunk-SS4ESNE3.js} +2 -2
  45. package/Build/Workers/{chunk-AIPU2VSX.js → chunk-TJBU6GML.js} +6 -6
  46. package/Build/Workers/{chunk-5M3U6ZMA.js → chunk-TZORKRNK.js} +1 -1
  47. package/Build/Workers/{chunk-MY3VNFGQ.js → chunk-VR5RBW52.js} +7 -7
  48. package/Build/Workers/{chunk-FP6GYBFX.js → chunk-WHUSTDIB.js} +10 -10
  49. package/Build/Workers/{chunk-5HDYHG3F.js → chunk-X2F6BEPY.js} +13 -13
  50. package/Build/Workers/{chunk-WZU2YLWG.js → chunk-X6XOMPWL.js} +3 -3
  51. package/Build/Workers/{chunk-UGK3FCDY.js → chunk-YDVSBWEO.js} +1 -1
  52. package/Build/Workers/{chunk-46UD5ABS.js → chunk-YV4H2Y7M.js} +4 -4
  53. package/Build/Workers/{chunk-WBQCVXR3.js → chunk-Z7FQLK6N.js} +4 -4
  54. package/Build/Workers/{chunk-L2ZN645J.js → chunk-ZNVSKMQ2.js} +6 -6
  55. package/Build/Workers/{chunk-JCNXK6EL.js → chunk-ZYPTP7GS.js} +11 -11
  56. package/Build/Workers/combineGeometry.js +24 -23
  57. package/Build/Workers/createBoxGeometry.js +18 -17
  58. package/Build/Workers/createBoxOutlineGeometry.js +16 -15
  59. package/Build/Workers/createCircleGeometry.js +26 -25
  60. package/Build/Workers/createCircleOutlineGeometry.js +19 -18
  61. package/Build/Workers/createCoplanarPolygonGeometry.js +33 -32
  62. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +31 -30
  63. package/Build/Workers/createCorridorGeometry.js +29 -28
  64. package/Build/Workers/createCorridorOutlineGeometry.js +28 -27
  65. package/Build/Workers/createCylinderGeometry.js +20 -19
  66. package/Build/Workers/createCylinderOutlineGeometry.js +18 -17
  67. package/Build/Workers/createEllipseGeometry.js +26 -25
  68. package/Build/Workers/createEllipseOutlineGeometry.js +19 -18
  69. package/Build/Workers/createEllipsoidGeometry.js +19 -18
  70. package/Build/Workers/createEllipsoidOutlineGeometry.js +18 -17
  71. package/Build/Workers/createFrustumGeometry.js +18 -17
  72. package/Build/Workers/createFrustumOutlineGeometry.js +18 -17
  73. package/Build/Workers/createGeometry.js +54 -33
  74. package/Build/Workers/createGroundPolylineGeometry.js +22 -21
  75. package/Build/Workers/createPlaneGeometry.js +16 -15
  76. package/Build/Workers/createPlaneOutlineGeometry.js +15 -14
  77. package/Build/Workers/createPolygonGeometry.js +33 -32
  78. package/Build/Workers/createPolygonOutlineGeometry.js +30 -29
  79. package/Build/Workers/createPolylineGeometry.js +25 -24
  80. package/Build/Workers/createPolylineVolumeGeometry.js +31 -30
  81. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +27 -26
  82. package/Build/Workers/createRectangleGeometry.js +27 -26
  83. package/Build/Workers/createRectangleOutlineGeometry.js +20 -19
  84. package/Build/Workers/createSimplePolylineGeometry.js +23 -22
  85. package/Build/Workers/createSphereGeometry.js +19 -18
  86. package/Build/Workers/createSphereOutlineGeometry.js +18 -17
  87. package/Build/Workers/createTaskProcessorWorker.js +3 -3
  88. package/Build/Workers/createVectorTileClampedPolylines.js +14 -14
  89. package/Build/Workers/createVectorTileGeometries.js +24 -23
  90. package/Build/Workers/createVectorTilePoints.js +12 -12
  91. package/Build/Workers/createVectorTilePolygons.js +22 -21
  92. package/Build/Workers/createVectorTilePolylines.js +14 -14
  93. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +22 -21
  94. package/Build/Workers/createVerticesFromHeightmap.js +22 -21
  95. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +19 -18
  96. package/Build/Workers/createWallGeometry.js +24 -23
  97. package/Build/Workers/createWallOutlineGeometry.js +23 -22
  98. package/Build/Workers/decodeDraco.js +11 -11
  99. package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
  100. package/Build/Workers/decodeI3S.js +601 -92
  101. package/Build/Workers/transcodeKTX2.js +7 -7
  102. package/Build/Workers/transferTypedArrayTest.js +1 -1
  103. package/Build/Workers/upsampleQuantizedTerrainMesh.js +22 -21
  104. package/Source/Core/Check.d.ts +127 -0
  105. package/Source/Core/Check.js +0 -1
  106. package/Source/Core/Ellipsoid.js +6 -0
  107. package/Source/Core/Geometry.js +1 -1
  108. package/Source/Core/IntersectionTests.js +6 -3
  109. package/Source/Core/Ion.js +1 -1
  110. package/Source/Core/PixelFormat.js +5 -0
  111. package/Source/Core/PolygonGeometry.js +1 -1
  112. package/Source/Core/Transforms.js +3 -0
  113. package/Source/Core/VerticalExaggeration.js +2 -1
  114. package/Source/Core/srgbToLinear.js +32 -0
  115. package/Source/DataSources/CzmlDataSource.js +51 -23
  116. package/Source/DataSources/DataSourceDisplay.js +27 -0
  117. package/Source/DataSources/Entity.js +20 -2
  118. package/Source/DataSources/GeometryUpdaterSet.js +114 -0
  119. package/Source/DataSources/GeometryVisualizer.js +19 -83
  120. package/Source/Renderer/Context.js +10 -0
  121. package/Source/Renderer/ContextLimits.js +2 -0
  122. package/Source/Renderer/demodernizeShader.js +4 -1
  123. package/Source/Scene/ArcGisMapService.js +1 -1
  124. package/Source/Scene/Axis.js +12 -7
  125. package/Source/Scene/Billboard.js +32 -0
  126. package/Source/Scene/BillboardCollection.js +1 -1
  127. package/Source/Scene/BingMapsImageryProvider.js +4 -0
  128. package/Source/Scene/Camera.js +46 -4
  129. package/Source/Scene/Cesium3DTilesVoxelProvider.js +2 -9
  130. package/Source/Scene/Cesium3DTileset.js +10 -7
  131. package/Source/Scene/Cesium3DTilesetBaseTraversal.js +2 -4
  132. package/Source/Scene/FrameState.js +5 -0
  133. package/Source/Scene/Globe.js +0 -67
  134. package/Source/Scene/GlobeTranslucencyState.js +1 -1
  135. package/Source/Scene/GltfPipeline/updateVersion.js +69 -68
  136. package/Source/Scene/I3SDataProvider.js +270 -53
  137. package/Source/Scene/I3SDecoder.js +8 -1
  138. package/Source/Scene/I3SFeature.js +2 -5
  139. package/Source/Scene/I3SField.js +136 -31
  140. package/Source/Scene/I3SGeometry.js +70 -2
  141. package/Source/Scene/I3SLayer.js +55 -10
  142. package/Source/Scene/I3SNode.js +175 -18
  143. package/Source/Scene/I3SStatistics.js +94 -0
  144. package/Source/Scene/I3SSublayer.js +176 -0
  145. package/Source/Scene/I3SSymbology.js +337 -0
  146. package/Source/Scene/KeyframeNode.js +1 -1
  147. package/Source/Scene/Label.js +33 -0
  148. package/Source/Scene/LabelCollection.js +2 -1
  149. package/Source/Scene/Model/pickModel.js +25 -7
  150. package/Source/Scene/PickFramebuffer.js +37 -2
  151. package/Source/Scene/Picking.js +113 -39
  152. package/Source/Scene/Primitive.js +6 -5
  153. package/Source/Scene/Scene.js +126 -42
  154. package/Source/Scene/ScreenSpaceCameraController.js +21 -7
  155. package/Source/Scene/SensorVolumePortionToDisplay.js +69 -0
  156. package/Source/Scene/SpatialNode.js +12 -19
  157. package/Source/Scene/StructuralMetadata.js +1 -1
  158. package/Source/Scene/VoxelBoxShape.js +67 -6
  159. package/Source/Scene/VoxelCell.js +273 -0
  160. package/Source/Scene/VoxelCylinderShape.js +117 -163
  161. package/Source/Scene/VoxelEllipsoidShape.js +255 -304
  162. package/Source/Scene/VoxelPrimitive.js +109 -15
  163. package/Source/Scene/VoxelRenderResources.js +12 -3
  164. package/Source/Scene/VoxelShape.js +7 -4
  165. package/Source/Scene/VoxelTraversal.js +76 -54
  166. package/Source/Scene/buildVoxelDrawCommands.js +23 -0
  167. package/Source/Scene/createGooglePhotorealistic3DTileset.js +1 -0
  168. package/Source/Scene/processVoxelProperties.js +3 -0
  169. package/Source/Shaders/Voxels/IntersectBox.glsl +21 -47
  170. package/Source/Shaders/Voxels/IntersectBox.js +21 -47
  171. package/Source/Shaders/Voxels/IntersectClippingPlanes.glsl +1 -1
  172. package/Source/Shaders/Voxels/IntersectClippingPlanes.js +1 -1
  173. package/Source/Shaders/Voxels/IntersectCylinder.glsl +76 -203
  174. package/Source/Shaders/Voxels/IntersectCylinder.js +76 -203
  175. package/Source/Shaders/Voxels/IntersectEllipsoid.glsl +220 -229
  176. package/Source/Shaders/Voxels/IntersectEllipsoid.js +220 -229
  177. package/Source/Shaders/Voxels/IntersectLongitude.glsl +102 -0
  178. package/Source/Shaders/Voxels/IntersectLongitude.js +104 -0
  179. package/Source/Shaders/Voxels/IntersectionUtils.glsl +33 -11
  180. package/Source/Shaders/Voxels/IntersectionUtils.js +33 -11
  181. package/Source/Shaders/Voxels/Megatexture.glsl +1 -2
  182. package/Source/Shaders/Voxels/Megatexture.js +1 -2
  183. package/Source/Shaders/Voxels/Octree.glsl +14 -9
  184. package/Source/Shaders/Voxels/Octree.js +14 -9
  185. package/Source/Shaders/Voxels/VoxelFS.glsl +128 -40
  186. package/Source/Shaders/Voxels/VoxelFS.js +128 -40
  187. package/Source/Shaders/Voxels/VoxelUtils.glsl +31 -0
  188. package/Source/Shaders/Voxels/VoxelUtils.js +33 -0
  189. package/Source/Shaders/Voxels/convertUvToBox.glsl +24 -3
  190. package/Source/Shaders/Voxels/convertUvToBox.js +24 -4
  191. package/Source/Shaders/Voxels/convertUvToCylinder.glsl +64 -40
  192. package/Source/Shaders/Voxels/convertUvToCylinder.js +64 -40
  193. package/Source/Shaders/Voxels/convertUvToEllipsoid.glsl +100 -91
  194. package/Source/Shaders/Voxels/convertUvToEllipsoid.js +100 -91
  195. package/Source/ThirdParty/Workers/z-worker-pako.js +1 -1
  196. package/Source/Workers/createGeometry.js +40 -11
  197. package/Source/Workers/decodeI3S.js +720 -94
  198. package/index.d.ts +542 -40
  199. package/index.js +75 -66
  200. package/package.json +2 -2
@@ -45,6 +45,7 @@ async function initializeDecoder() {
45
45
  * @param {Object} defaultGeometrySchema Schema to use during decoding
46
46
  * @param {I3SGeometry} geometryData The draco encoded geometry data
47
47
  * @param {Array} [featureData] The draco encoded feature data
48
+ * @param {Object} [symbologyData] The rendering symbology to apply
48
49
  * @returns Promise<undefined|object> Returns a promise which resolves to the glTF result, or undefined if the task cannot be scheduled this frame.
49
50
  *
50
51
  * @exception {RuntimeError} I3S decoder could not be initialized.
@@ -53,7 +54,8 @@ I3SDecoder.decode = async function (
53
54
  url,
54
55
  defaultGeometrySchema,
55
56
  geometryData,
56
- featureData
57
+ featureData,
58
+ symbologyData
57
59
  ) {
58
60
  //>>includeStart('debug', pragmas.debug);
59
61
  Check.typeOf.string("url", url);
@@ -118,6 +120,11 @@ I3SDecoder.decode = async function (
118
120
  cartographicCenter: cartographicCenter,
119
121
  cartesianCenter: cartesianCenter,
120
122
  parentRotation: parentRotation,
123
+ enableFeatures: geometryData._dataProvider.showFeatures,
124
+ splitGeometryByColorTransparency:
125
+ geometryData._dataProvider.adjustMaterialAlphaMode,
126
+ symbologyData: symbologyData,
127
+ calculateNormals: geometryData._dataProvider.calculateNormals,
121
128
  };
122
129
 
123
130
  return taskProcessor.scheduleTask(payload);
@@ -50,14 +50,11 @@ Object.defineProperties(I3SFeature.prototype, {
50
50
 
51
51
  /**
52
52
  * Loads the content.
53
- * @returns {Promise} A promise that is resolved when the data of the I3S feature is loaded
53
+ * @returns {Promise<object>} A promise that is resolved when the data of the I3S feature is loaded
54
54
  * @private
55
55
  */
56
56
  I3SFeature.prototype.load = async function () {
57
- this._data = await I3SDataProvider.loadJson(
58
- this._resource,
59
- this._dataProvider._traceFetches
60
- );
57
+ this._data = await I3SDataProvider.loadJson(this._resource);
61
58
  return this._data;
62
59
  };
63
60
 
@@ -1,4 +1,5 @@
1
1
  import defined from "../Core/defined.js";
2
+ import RuntimeError from "../Core/RuntimeError.js";
2
3
 
3
4
  /**
4
5
  * This class implements an I3S Field which is custom data attached
@@ -12,6 +13,7 @@ function I3SField(parent, storageInfo) {
12
13
  this._storageInfo = storageInfo;
13
14
  this._parent = parent;
14
15
  this._dataProvider = parent._dataProvider;
16
+ this._loadPromise = undefined;
15
17
  const uri = `attributes/${storageInfo.key}/0`;
16
18
 
17
19
  if (defined(this._parent._nodeIndex)) {
@@ -54,9 +56,16 @@ Object.defineProperties(I3SField.prototype, {
54
56
  */
55
57
  values: {
56
58
  get: function () {
57
- return defined(this._values) && defined(this._values.attributeValues)
58
- ? this._values.attributeValues
59
- : [];
59
+ if (defined(this._values)) {
60
+ // attribute data can be stored either as values or as object identifiers
61
+ if (defined(this._values.attributeValues)) {
62
+ return this._values.attributeValues;
63
+ }
64
+ if (defined(this._values.objectIds)) {
65
+ return this._values.objectIds;
66
+ }
67
+ }
68
+ return [];
60
69
  },
61
70
  },
62
71
  /**
@@ -92,40 +101,37 @@ function getNumericTypeSize(type) {
92
101
  return 0;
93
102
  }
94
103
 
104
+ function getValueTypeSize(type) {
105
+ if (type === "String") {
106
+ return 1;
107
+ }
108
+ return getNumericTypeSize(type);
109
+ }
110
+
111
+ async function load(field) {
112
+ const data = await field._dataProvider._loadBinary(field._resource);
113
+ const dataView = new DataView(data);
114
+ field._data = data;
115
+ field._validateHeader(dataView);
116
+ const headerSize = field._parseHeader(dataView);
117
+ const offset = field._getBodyOffset(headerSize);
118
+ field._validateBody(dataView, offset);
119
+ field._parseBody(dataView, offset);
120
+ }
121
+
95
122
  /**
96
123
  * Loads the content.
97
124
  * @returns {Promise<void>} A promise that is resolved when the field data is loaded
98
125
  */
99
126
  I3SField.prototype.load = function () {
100
- const that = this;
101
- return this._dataProvider._loadBinary(this._resource).then(function (data) {
102
- // Check if we have a 404
103
- const dataView = new DataView(data);
104
- let success = true;
105
- if (dataView.getUint8(0) === "{".charCodeAt(0)) {
106
- const textContent = new TextDecoder();
107
- const str = textContent.decode(data);
108
- if (str.includes("404")) {
109
- success = false;
110
- console.error(`Failed to load: ${that.resource.url}`);
111
- }
112
- }
113
-
114
- if (success) {
115
- that._data = data;
116
- let offset = that._parseHeader(dataView);
117
-
118
- const valueSize = getNumericTypeSize(
119
- that._storageInfo.attributeValues.valueType
120
- );
121
- if (valueSize > 0) {
122
- // Values will be padded to align the addresses with the data size
123
- offset = Math.ceil(offset / valueSize) * valueSize;
124
- }
127
+ if (defined(this._loadPromise)) {
128
+ return this._loadPromise;
129
+ }
125
130
 
126
- that._parseBody(dataView, offset);
127
- }
131
+ this._loadPromise = load(this).catch(function (error) {
132
+ console.error(error);
128
133
  });
134
+ return this._loadPromise;
129
135
  };
130
136
 
131
137
  /**
@@ -217,7 +223,9 @@ I3SField.prototype._parseBody = function (dataView, offset) {
217
223
  itemIndex < this._storageInfo.ordering.length;
218
224
  itemIndex++
219
225
  ) {
220
- const item = this._storageInfo.ordering[itemIndex];
226
+ const orderingValue = this._storageInfo.ordering[itemIndex];
227
+ // all strings in the ordering array correspond to the property name, except ObjectIds
228
+ const item = orderingValue === "ObjectIds" ? "objectIds" : orderingValue;
221
229
  const desc = this._storageInfo[item];
222
230
  if (defined(desc)) {
223
231
  this._values[item] = [];
@@ -252,4 +260,101 @@ I3SField.prototype._parseBody = function (dataView, offset) {
252
260
  }
253
261
  };
254
262
 
263
+ /**
264
+ * @private
265
+ */
266
+ I3SField.prototype._getBodyOffset = function (headerSize) {
267
+ let valueSize = 0;
268
+ if (defined(this._storageInfo.attributeValues)) {
269
+ valueSize = getNumericTypeSize(this._storageInfo.attributeValues.valueType);
270
+ } else if (defined(this._storageInfo.objectIds)) {
271
+ valueSize = getNumericTypeSize(this._storageInfo.objectIds.valueType);
272
+ }
273
+ if (valueSize > 0) {
274
+ // Values will be padded to align the addresses with the data size
275
+ return Math.ceil(headerSize / valueSize) * valueSize;
276
+ }
277
+ return headerSize;
278
+ };
279
+
280
+ /**
281
+ * @private
282
+ */
283
+ I3SField.prototype._validateHeader = function (dataView) {
284
+ let headerSize = 0;
285
+ for (
286
+ let itemIndex = 0;
287
+ itemIndex < this._storageInfo.header.length;
288
+ itemIndex++
289
+ ) {
290
+ const item = this._storageInfo.header[itemIndex];
291
+ headerSize += getValueTypeSize(item.valueType);
292
+ }
293
+ if (dataView.byteLength < headerSize) {
294
+ throw new RuntimeError(
295
+ `Invalid attribute buffer size (field: ${this.name}, header: ${headerSize}, actual: ${dataView.byteLength})`
296
+ );
297
+ }
298
+ };
299
+
300
+ /**
301
+ * @private
302
+ */
303
+ I3SField.prototype._validateBody = function (dataView, offset) {
304
+ if (!defined(this._header.count)) {
305
+ throw new RuntimeError(
306
+ `Invalid attribute buffer (field: ${this.name}, count is missing)`
307
+ );
308
+ }
309
+ let attributeByteCountsOffset;
310
+ for (
311
+ let itemIndex = 0;
312
+ itemIndex < this._storageInfo.ordering.length &&
313
+ offset < dataView.byteLength;
314
+ itemIndex++
315
+ ) {
316
+ const orderingValue = this._storageInfo.ordering[itemIndex];
317
+ // all strings in the ordering array correspond to the property name, except ObjectIds
318
+ const item = orderingValue === "ObjectIds" ? "objectIds" : orderingValue;
319
+ const desc = this._storageInfo[item];
320
+ if (defined(desc)) {
321
+ if (desc.valueType !== "String") {
322
+ if (item === "attributeByteCounts") {
323
+ attributeByteCountsOffset = offset;
324
+ }
325
+ const valueSize = getNumericTypeSize(desc.valueType);
326
+ offset += valueSize * this._header.count;
327
+ } else {
328
+ if (!defined(attributeByteCountsOffset)) {
329
+ throw new RuntimeError(
330
+ `Invalid attribute buffer (field: ${this.name}, attributeByteCounts is missing)`
331
+ );
332
+ }
333
+ for (
334
+ let index = 0;
335
+ index < this._header.count && offset < dataView.byteLength;
336
+ ++index
337
+ ) {
338
+ const parsedValue = this._parseValue(
339
+ dataView,
340
+ this._storageInfo.attributeByteCounts.valueType,
341
+ attributeByteCountsOffset
342
+ );
343
+ offset += parsedValue.value;
344
+ attributeByteCountsOffset = parsedValue.offset;
345
+ }
346
+ }
347
+ } else {
348
+ throw new RuntimeError(
349
+ `Invalid attribute buffer (field: ${this.name}, ${item} is missing)`
350
+ );
351
+ }
352
+ }
353
+ if (dataView.byteLength < offset) {
354
+ throw new RuntimeError(
355
+ `Invalid attribute buffer size (field: ${this.name}, expected: ${offset}, actual: ${dataView.byteLength})`
356
+ );
357
+ }
358
+ };
359
+
255
360
  export default I3SField;
@@ -1,6 +1,8 @@
1
1
  import Cartesian3 from "../Core/Cartesian3.js";
2
+ import clone from "../Core/clone.js";
2
3
  import defined from "../Core/defined.js";
3
4
  import Matrix3 from "../Core/Matrix3.js";
5
+ import srgbToLinear from "../Core/srgbToLinear.js";
4
6
 
5
7
  /**
6
8
  * This class implements an I3S Geometry. Each I3SGeometry
@@ -267,6 +269,19 @@ I3SGeometry.prototype.getClosestPointIndexOnTriangle = function (px, py, pz) {
267
269
  };
268
270
  };
269
271
 
272
+ function convertColorFactor(factor) {
273
+ const convertedFactor = [];
274
+ const length = factor.length;
275
+ for (let i = 0; i < length; i++) {
276
+ if (i < 3) {
277
+ convertedFactor.push(srgbToLinear(factor[i]));
278
+ } else {
279
+ convertedFactor.push(factor[i]);
280
+ }
281
+ }
282
+ return convertedFactor;
283
+ }
284
+
270
285
  /**
271
286
  * @private
272
287
  */
@@ -276,7 +291,9 @@ I3SGeometry.prototype._generateGltf = function (
276
291
  meshes,
277
292
  buffers,
278
293
  bufferViews,
279
- accessors
294
+ accessors,
295
+ extensions,
296
+ extensionsUsed
280
297
  ) {
281
298
  // Get the material definition
282
299
  let gltfMaterial = {
@@ -344,6 +361,21 @@ I3SGeometry.prototype._generateGltf = function (
344
361
  }).url;
345
362
  }
346
363
  }
364
+
365
+ // Convert color factors from sRGB to linear color space
366
+ if (
367
+ defined(gltfMaterial.pbrMetallicRoughness) &&
368
+ defined(gltfMaterial.pbrMetallicRoughness.baseColorFactor)
369
+ ) {
370
+ gltfMaterial.pbrMetallicRoughness.baseColorFactor = convertColorFactor(
371
+ gltfMaterial.pbrMetallicRoughness.baseColorFactor
372
+ );
373
+ }
374
+ if (defined(gltfMaterial.emissiveFactor)) {
375
+ gltfMaterial.emissiveFactor = convertColorFactor(
376
+ gltfMaterial.emissiveFactor
377
+ );
378
+ }
347
379
  }
348
380
  } else if (defined(this._parent._data.textureData)) {
349
381
  // No material definition, but if there's a texture reference, we can create a simple material using it (version 1.6 support)
@@ -353,6 +385,10 @@ I3SGeometry.prototype._generateGltf = function (
353
385
  }).url;
354
386
  gltfMaterial.pbrMetallicRoughness.baseColorTexture = { index: 0 };
355
387
  }
388
+ if (defined(gltfMaterial.alphaMode)) {
389
+ // I3S specifies alphaMode values in lowercase, but glTF expects values in uppercase
390
+ gltfMaterial.alphaMode = gltfMaterial.alphaMode.toUpperCase();
391
+ }
356
392
 
357
393
  let gltfTextures = [];
358
394
  let gltfImages = [];
@@ -382,6 +418,36 @@ I3SGeometry.prototype._generateGltf = function (
382
418
  ];
383
419
  }
384
420
 
421
+ const gltfMaterials = [];
422
+ const meshesLength = meshes.length;
423
+ for (let meshIndex = 0; meshIndex < meshesLength; meshIndex++) {
424
+ const primitives = meshes[meshIndex].primitives;
425
+ const primitivesLength = primitives.length;
426
+ for (
427
+ let primitiveIndex = 0;
428
+ primitiveIndex < primitivesLength;
429
+ primitiveIndex++
430
+ ) {
431
+ const primitive = primitives[primitiveIndex];
432
+ if (defined(primitive.material)) {
433
+ // Create as many copies of the material as specified in the mesh primitives
434
+ while (primitive.material >= gltfMaterials.length) {
435
+ const material = clone(gltfMaterial, true);
436
+ gltfMaterials.push(material);
437
+ }
438
+ const primitiveMaterial = gltfMaterials[primitive.material];
439
+ if (defined(primitive.extra) && primitive.extra.isTransparent) {
440
+ // If the alpha mode is not specified in the original material but the geometry is transparent, we need to force set BLEND alpha mode. Otherwise the geometry will be rendered opaque.
441
+ if (!defined(primitiveMaterial.alphaMode)) {
442
+ primitiveMaterial.alphaMode = "BLEND";
443
+ }
444
+ } else if (primitiveMaterial.alphaMode === "BLEND") {
445
+ // If the geometry is not transparent, but the alpha mode is set to BLEND in the original material, we need to force set OPAQUE alpha mode. Otherwise the geometry will be rendered transparent.
446
+ primitiveMaterial.alphaMode = "OPAQUE";
447
+ }
448
+ }
449
+ }
450
+ }
385
451
  const gltfData = {
386
452
  scene: 0,
387
453
  scenes: [
@@ -394,13 +460,15 @@ I3SGeometry.prototype._generateGltf = function (
394
460
  buffers: buffers,
395
461
  bufferViews: bufferViews,
396
462
  accessors: accessors,
397
- materials: [gltfMaterial],
463
+ materials: gltfMaterials,
398
464
  textures: gltfTextures,
399
465
  images: gltfImages,
400
466
  samplers: gltfSamplers,
401
467
  asset: {
402
468
  version: "2.0",
403
469
  },
470
+ extensions: extensions,
471
+ extensionsUsed: extensionsUsed,
404
472
  };
405
473
 
406
474
  return gltfData;
@@ -1,9 +1,13 @@
1
+ import Cartesian4 from "../Core/Cartesian4.js";
2
+ import clone from "../Core/clone.js";
3
+ import Color from "../Core/Color.js";
1
4
  import defined from "../Core/defined.js";
2
5
  import Rectangle from "../Core/Rectangle.js";
3
6
  import Resource from "../Core/Resource.js";
4
7
  import RuntimeError from "../Core/RuntimeError.js";
5
8
  import Cesium3DTileset from "./Cesium3DTileset.js";
6
9
  import I3SNode from "./I3SNode.js";
10
+ import I3SSymbology from "./I3SSymbology.js";
7
11
 
8
12
  /**
9
13
  * This class implements an I3S layer. In CesiumJS each I3SLayer creates a Cesium3DTileset.
@@ -14,24 +18,25 @@ import I3SNode from "./I3SNode.js";
14
18
  * @internalConstructor
15
19
  * @privateParam {I3SDataProvider} dataProvider The i3s data provider
16
20
  * @privateParam {object} layerData The layer data that is loaded from the scene layer
17
- * @privateParam {number} index The index of the layer to be reflected
21
+ * @privateParam {I3SDataProvider|I3SSublayer} parent The parent of that layer
18
22
  */
19
- function I3SLayer(dataProvider, layerData, index) {
23
+ function I3SLayer(dataProvider, layerData, parent) {
20
24
  this._dataProvider = dataProvider;
25
+ this._parent = parent;
21
26
 
22
- if (!defined(layerData.href) && defined(index)) {
27
+ if (!defined(layerData.href) && defined(layerData.id)) {
23
28
  // assign a default layer
24
- layerData.href = `layers/${index}`;
29
+ layerData.href = `layers/${layerData.id}`;
25
30
  }
26
31
 
27
- const dataProviderUrl = this._dataProvider.resource.getUrlComponent();
32
+ const parentUrl = this._parent.resource.getUrlComponent();
28
33
 
29
34
  let tilesetUrl = "";
30
- if (dataProviderUrl.match(/layers\/\d/)) {
31
- tilesetUrl = `${dataProviderUrl}`.replace(/\/+$/, "");
35
+ if (parentUrl.match(/layers\/\d/)) {
36
+ tilesetUrl = `${parentUrl}`.replace(/\/+$/, "");
32
37
  } else {
33
38
  // Add '/' to url if needed + `${layerData.href}` if tilesetUrl not already in ../layers/[id] format
34
- tilesetUrl = `${dataProviderUrl}`
39
+ tilesetUrl = `${parentUrl}`
35
40
  .replace(/\/?$/, "/")
36
41
  .concat(`${layerData.href}`);
37
42
  }
@@ -53,6 +58,8 @@ function I3SLayer(dataProvider, layerData, index) {
53
58
  this._extent = undefined;
54
59
  this._tileset = undefined;
55
60
  this._geometryDefinitions = undefined;
61
+ this._filters = [];
62
+ this._symbology = undefined;
56
63
 
57
64
  this._computeGeometryDefinitions(true);
58
65
  this._computeExtent();
@@ -166,7 +173,7 @@ Object.defineProperties(I3SLayer.prototype, {
166
173
  /**
167
174
  * Loads the content, including the root node definition and its children
168
175
  * @param {Cesium3DTileset.ConstructorOptions} [cesium3dTilesetOptions] options for Cesium3dTileset constructor
169
- * @returns {Promise} A promise that is resolved when the layer data is loaded
176
+ * @returns {Promise<void>} A promise that is resolved when the layer data is loaded
170
177
  * @private
171
178
  */
172
179
  I3SLayer.prototype.load = async function (cesium3dTilesetOptions) {
@@ -176,6 +183,9 @@ I3SLayer.prototype.load = async function (cesium3dTilesetOptions) {
176
183
  );
177
184
  }
178
185
 
186
+ if (this._dataProvider.applySymbology) {
187
+ this._symbology = new I3SSymbology(this);
188
+ }
179
189
  await this._dataProvider.loadGeoidData();
180
190
  await this._loadRootNode(cesium3dTilesetOptions);
181
191
  await this._create3DTileset(cesium3dTilesetOptions);
@@ -387,11 +397,20 @@ I3SLayer.prototype._create3DTileset = async function (cesium3dTilesetOptions) {
387
397
  });
388
398
 
389
399
  const tilesetUrl = URL.createObjectURL(tilesetBlob);
400
+ const outlineColor = this._symbology?.defaultSymbology?.edges?.color;
401
+ if (defined(outlineColor) && !defined(cesium3dTilesetOptions?.outlineColor)) {
402
+ cesium3dTilesetOptions = defined(cesium3dTilesetOptions)
403
+ ? clone(cesium3dTilesetOptions)
404
+ : {};
405
+ cesium3dTilesetOptions.outlineColor = Color.fromCartesian4(
406
+ Cartesian4.fromArray(outlineColor)
407
+ );
408
+ }
390
409
  this._tileset = await Cesium3DTileset.fromUrl(
391
410
  tilesetUrl,
392
411
  cesium3dTilesetOptions
393
412
  );
394
- this._tileset.show = this._dataProvider.show;
413
+ this._tileset.show = this._parent.show;
395
414
  this._tileset._isI3STileSet = true;
396
415
  this._tileset.tileUnload.addEventListener(function (tile) {
397
416
  tile._i3sNode._clearGeometryData();
@@ -406,4 +425,30 @@ I3SLayer.prototype._create3DTileset = async function (cesium3dTilesetOptions) {
406
425
  });
407
426
  };
408
427
 
428
+ /**
429
+ * @private
430
+ */
431
+ I3SLayer.prototype._updateVisibility = function () {
432
+ if (defined(this._tileset)) {
433
+ this._tileset.show = this._parent.show;
434
+ }
435
+ };
436
+
437
+ /**
438
+ * Filters the drawn elements of a layer to specific attribute names and values
439
+ * @param {I3SNode.AttributeFilter[]} [filters=[]] The collection of attribute filters
440
+ * @returns {Promise<void>} A promise that is resolved when the filter is applied
441
+ */
442
+ I3SLayer.prototype.filterByAttributes = function (filters) {
443
+ // Filters are applied for each node in the layer when the node model is loaded
444
+ this._filters = defined(filters) ? clone(filters, true) : [];
445
+
446
+ // Forced filtering is required for loaded nodes only
447
+ const rootNode = this._rootNode;
448
+ if (defined(rootNode)) {
449
+ return rootNode._filterFeatures();
450
+ }
451
+ return Promise.resolve();
452
+ };
453
+
409
454
  export default I3SLayer;