@loaders.gl/gltf 4.0.0-alpha.24 → 4.0.0-alpha.25

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 (77) hide show
  1. package/dist/dist.min.js +237 -146
  2. package/dist/es5/index.js +12 -0
  3. package/dist/es5/index.js.map +1 -1
  4. package/dist/es5/lib/api/gltf-extensions.js +1 -1
  5. package/dist/es5/lib/api/gltf-extensions.js.map +1 -1
  6. package/dist/es5/lib/extensions/EXT_mesh_features.js +12 -24
  7. package/dist/es5/lib/extensions/EXT_mesh_features.js.map +1 -1
  8. package/dist/es5/lib/extensions/EXT_structural_metadata.js +72 -28
  9. package/dist/es5/lib/extensions/EXT_structural_metadata.js.map +1 -1
  10. package/dist/es5/lib/extensions/deprecated/EXT_feature_metadata.js +38 -3
  11. package/dist/es5/lib/extensions/deprecated/EXT_feature_metadata.js.map +1 -1
  12. package/dist/es5/lib/extensions/utils/3d-tiles-utils.js +26 -18
  13. package/dist/es5/lib/extensions/utils/3d-tiles-utils.js.map +1 -1
  14. package/dist/es5/lib/gltf-utils/gltf-utils.js +29 -0
  15. package/dist/es5/lib/gltf-utils/gltf-utils.js.map +1 -1
  16. package/dist/es5/lib/types/gltf-ext-feature-metadata-schema.js +2 -0
  17. package/dist/es5/lib/types/gltf-ext-feature-metadata-schema.js.map +1 -0
  18. package/dist/es5/lib/types/gltf-ext-mesh-features-schema.js.map +1 -1
  19. package/dist/es5/lib/types/gltf-ext-structural-metadata-schema.js.map +1 -1
  20. package/dist/es5/lib/types/gltf-json-schema.js.map +1 -1
  21. package/dist/es5/lib/types/gltf-types.js.map +1 -1
  22. package/dist/es5/lib/utils/version.js +1 -1
  23. package/dist/esm/index.js +2 -0
  24. package/dist/esm/index.js.map +1 -1
  25. package/dist/esm/lib/api/gltf-extensions.js +1 -1
  26. package/dist/esm/lib/api/gltf-extensions.js.map +1 -1
  27. package/dist/esm/lib/extensions/EXT_mesh_features.js +13 -25
  28. package/dist/esm/lib/extensions/EXT_mesh_features.js.map +1 -1
  29. package/dist/esm/lib/extensions/EXT_structural_metadata.js +48 -14
  30. package/dist/esm/lib/extensions/EXT_structural_metadata.js.map +1 -1
  31. package/dist/esm/lib/extensions/deprecated/EXT_feature_metadata.js +38 -4
  32. package/dist/esm/lib/extensions/deprecated/EXT_feature_metadata.js.map +1 -1
  33. package/dist/esm/lib/extensions/utils/3d-tiles-utils.js +27 -19
  34. package/dist/esm/lib/extensions/utils/3d-tiles-utils.js.map +1 -1
  35. package/dist/esm/lib/gltf-utils/gltf-utils.js +30 -0
  36. package/dist/esm/lib/gltf-utils/gltf-utils.js.map +1 -1
  37. package/dist/esm/lib/types/gltf-ext-feature-metadata-schema.js +2 -0
  38. package/dist/esm/lib/types/gltf-ext-feature-metadata-schema.js.map +1 -0
  39. package/dist/esm/lib/types/gltf-ext-mesh-features-schema.js.map +1 -1
  40. package/dist/esm/lib/types/gltf-ext-structural-metadata-schema.js.map +1 -1
  41. package/dist/esm/lib/types/gltf-json-schema.js.map +1 -1
  42. package/dist/esm/lib/types/gltf-types.js.map +1 -1
  43. package/dist/esm/lib/utils/version.js +1 -1
  44. package/dist/index.d.ts +6 -3
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/lib/extensions/EXT_mesh_features.d.ts.map +1 -1
  47. package/dist/lib/extensions/EXT_structural_metadata.d.ts +9 -1
  48. package/dist/lib/extensions/EXT_structural_metadata.d.ts.map +1 -1
  49. package/dist/lib/extensions/deprecated/EXT_feature_metadata.d.ts +9 -0
  50. package/dist/lib/extensions/deprecated/EXT_feature_metadata.d.ts.map +1 -1
  51. package/dist/lib/extensions/utils/3d-tiles-utils.d.ts +12 -12
  52. package/dist/lib/extensions/utils/3d-tiles-utils.d.ts.map +1 -1
  53. package/dist/lib/gltf-utils/gltf-utils.d.ts +2 -0
  54. package/dist/lib/gltf-utils/gltf-utils.d.ts.map +1 -1
  55. package/dist/lib/types/gltf-ext-feature-metadata-schema.d.ts +421 -0
  56. package/dist/lib/types/gltf-ext-feature-metadata-schema.d.ts.map +1 -0
  57. package/dist/lib/types/gltf-ext-mesh-features-schema.d.ts +4 -6
  58. package/dist/lib/types/gltf-ext-mesh-features-schema.d.ts.map +1 -1
  59. package/dist/lib/types/gltf-ext-structural-metadata-schema.d.ts +44 -25
  60. package/dist/lib/types/gltf-ext-structural-metadata-schema.d.ts.map +1 -1
  61. package/dist/lib/types/gltf-json-schema.d.ts +1 -420
  62. package/dist/lib/types/gltf-json-schema.d.ts.map +1 -1
  63. package/dist/lib/types/gltf-types.d.ts +3 -0
  64. package/dist/lib/types/gltf-types.d.ts.map +1 -1
  65. package/package.json +6 -6
  66. package/src/index.ts +10 -5
  67. package/src/lib/api/gltf-extensions.ts +1 -1
  68. package/src/lib/extensions/EXT_mesh_features.ts +18 -44
  69. package/src/lib/extensions/EXT_structural_metadata.ts +176 -96
  70. package/src/lib/extensions/deprecated/EXT_feature_metadata.ts +70 -11
  71. package/src/lib/extensions/utils/3d-tiles-utils.ts +50 -39
  72. package/src/lib/gltf-utils/gltf-utils.ts +38 -0
  73. package/src/lib/types/gltf-ext-feature-metadata-schema.ts +470 -0
  74. package/src/lib/types/gltf-ext-mesh-features-schema.ts +4 -6
  75. package/src/lib/types/gltf-ext-structural-metadata-schema.ts +46 -27
  76. package/src/lib/types/gltf-json-schema.ts +1 -468
  77. package/src/lib/types/gltf-types.ts +4 -0
@@ -1,3 +1,5 @@
1
+ // GLTF EXTENSION: EXT_structural_metadata
2
+ // https://github.com/CesiumGS/glTF/blob/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata
1
3
  /* eslint-disable camelcase */
2
4
  import type {BigTypedArray, TypedArray} from '@loaders.gl/schema';
3
5
  import type {GLTF, GLTFTextureInfoMetadata, GLTFMeshPrimitive} from '../types/gltf-json-schema';
@@ -7,12 +9,13 @@ import type {
7
9
  GLTF_EXT_structural_metadata_Enum,
8
10
  GLTF_EXT_structural_metadata_EnumValue,
9
11
  GLTF_EXT_structural_metadata_PropertyTable,
10
- GLTF_EXT_structural_metadata,
12
+ GLTF_EXT_structural_metadata_GLTF,
11
13
  GLTF_EXT_structural_metadata_PropertyTexture,
12
14
  GLTF_EXT_structural_metadata_PropertyTable_Property,
13
15
  GLTF_EXT_structural_metadata_Primitive
14
16
  } from '../types/gltf-ext-structural-metadata-schema';
15
17
  import type {GLTFLoaderOptions} from '../../gltf-loader';
18
+ import type {FeatureTableJson} from '../types/gltf-types';
16
19
 
17
20
  import {GLTFScenegraph} from '../api/gltf-scenegraph';
18
21
  import {
@@ -32,6 +35,52 @@ export async function decode(gltfData: {json: GLTF}, options: GLTFLoaderOptions)
32
35
  decodeExtStructuralMetadata(scenegraph, options);
33
36
  }
34
37
 
38
+ /**
39
+ * Handles EXT_structural_metadata to get property table.
40
+ * @param extension - Global level of EXT_STRUCTURAL_METADATA extension.
41
+ * @param metadataClass - User selected feature metadata class name.
42
+ * @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly.
43
+ */
44
+ export function getPropertyTableFromExtStructuralMetadata(
45
+ extension: GLTF_EXT_structural_metadata_GLTF,
46
+ metadataClass?: string
47
+ ): FeatureTableJson | null {
48
+ if (extension.propertyTables) {
49
+ /**
50
+ * Take only first feature table to generate attributes storage info object.
51
+ * TODO: Think about getting data from all feature tables?
52
+ * It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
53
+ * In I3S we should decide which featureIds attribute will be passed to geometry data.
54
+ */
55
+ const firstPropertyTable = extension?.propertyTables[0];
56
+ const propertyTableWithData = {};
57
+
58
+ for (const propertyName in firstPropertyTable.properties) {
59
+ propertyTableWithData[propertyName] = firstPropertyTable.properties[propertyName].data;
60
+ }
61
+
62
+ return propertyTableWithData;
63
+ }
64
+
65
+ if (extension.propertyTextures) {
66
+ // TODO: Think about getting data from all property textures.
67
+ const firstPropertyTexture = extension?.propertyTextures[0];
68
+ const propertyTableWithData = {};
69
+
70
+ for (const propertyName in firstPropertyTexture.properties) {
71
+ propertyTableWithData[propertyName] = firstPropertyTexture.properties[propertyName].data;
72
+ }
73
+
74
+ return propertyTableWithData;
75
+ }
76
+
77
+ // eslint-disable-next-line no-console
78
+ console.warn(
79
+ 'Cannot get property table from EXT_structural_metadata extension. There is neither propertyTables, nor propertyTextures in the extension.'
80
+ );
81
+ return null;
82
+ }
83
+
35
84
  /*
36
85
  // Example of the extension.
37
86
  // See more info at https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata
@@ -100,7 +149,7 @@ export function getPropertyTablePopulated(
100
149
  scenegraph: GLTFScenegraph,
101
150
  propertyTableIndex: number
102
151
  ): GLTF_EXT_structural_metadata_PropertyTable {
103
- const extension: GLTF_EXT_structural_metadata | null = scenegraph.getExtension(
152
+ const extension: GLTF_EXT_structural_metadata_GLTF | null = scenegraph.getExtension(
104
153
  EXT_STRUCTURAL_METADATA_NAME
105
154
  );
106
155
  const propertyTable = extension?.propertyTables?.[propertyTableIndex];
@@ -114,21 +163,42 @@ export function getPropertyTablePopulated(
114
163
  }
115
164
 
116
165
  /**
117
- * Decodes feature metadata from extension
166
+ * Decodes feature metadata from extension.
118
167
  * @param scenegraph - Instance of the class for structured access to GLTF data.
119
- * @param options - loader options.
168
+ * @param options - GLTFLoader options.
120
169
  */
121
170
  function decodeExtStructuralMetadata(scenegraph: GLTFScenegraph, options: GLTFLoaderOptions): void {
122
- const extension: GLTF_EXT_structural_metadata | null = scenegraph.getExtension(
171
+ // Decoding metadata involves buffers processing.
172
+ // So, if buffers have not been loaded, there is no reason to process metadata.
173
+ if (!options.gltf?.loadBuffers) {
174
+ return;
175
+ }
176
+ const extension: GLTF_EXT_structural_metadata_GLTF | null = scenegraph.getExtension(
123
177
  EXT_STRUCTURAL_METADATA_NAME
124
178
  );
125
- if (!extension?.schema) {
179
+ if (!extension) {
126
180
  return;
127
181
  }
128
182
 
183
+ if (options.gltf?.loadImages) {
184
+ decodePropertyTextures(scenegraph, extension);
185
+ }
186
+
187
+ decodePropertyTables(scenegraph, extension);
188
+ }
189
+
190
+ /**
191
+ * Processes the data stored in the textures
192
+ * @param scenegraph - Instance of the class for structured access to GLTF data.
193
+ * @param extension - Top-level extension.
194
+ */
195
+ function decodePropertyTextures(
196
+ scenegraph: GLTFScenegraph,
197
+ extension: GLTF_EXT_structural_metadata_GLTF
198
+ ): void {
129
199
  const propertyTextures = extension.propertyTextures;
130
200
  const json = scenegraph.gltf.json;
131
- if (propertyTextures && json.meshes && options?.gltf?.loadImages) {
201
+ if (propertyTextures && json.meshes) {
132
202
  // Iterate through all meshes/primitives.
133
203
  for (const mesh of json.meshes) {
134
204
  for (const primitive of mesh.primitives) {
@@ -136,31 +206,43 @@ function decodeExtStructuralMetadata(scenegraph: GLTFScenegraph, options: GLTFLo
136
206
  }
137
207
  }
138
208
  }
209
+ }
139
210
 
140
- const schemaClasses = extension.schema.classes;
211
+ /**
212
+ * Processes the data stored in the property tables.
213
+ * @param scenegraph - Instance of the class for structured access to GLTF data.
214
+ * @param extension - Top-level extension.
215
+ */
216
+ function decodePropertyTables(
217
+ scenegraph: GLTFScenegraph,
218
+ extension: GLTF_EXT_structural_metadata_GLTF
219
+ ): void {
220
+ const schema = extension.schema;
221
+ if (!schema) {
222
+ return;
223
+ }
224
+ const schemaClasses = schema.classes;
141
225
  const propertyTables = extension.propertyTables;
142
226
  if (schemaClasses && propertyTables) {
143
227
  for (const schemaName in schemaClasses) {
144
228
  const propertyTable = findPropertyTableByClass(propertyTables, schemaName);
145
229
  if (propertyTable) {
146
- processPropertyTable(scenegraph, extension.schema, propertyTable);
230
+ processPropertyTable(scenegraph, schema, propertyTable);
147
231
  }
148
232
  }
149
233
  }
150
234
  }
151
235
 
152
236
  /**
153
- * Find the property table by class name.
154
- * @param propertyTables - propertyTable definition taken from the top-level extension
155
- * @param schemaClassName - class name in the extension schema
237
+ * Finds the property table by class name.
238
+ * @param propertyTables - propertyTable definition taken from the top-level extension.
239
+ * @param schemaClassName - class name in the extension schema.
156
240
  */
157
241
  function findPropertyTableByClass(
158
242
  propertyTables: GLTF_EXT_structural_metadata_PropertyTable[],
159
243
  schemaClassName: string
160
244
  ): GLTF_EXT_structural_metadata_PropertyTable | null {
161
- for (let i = 0, len = propertyTables.length; i < len; i++) {
162
- const propertyTable = propertyTables[i];
163
-
245
+ for (const propertyTable of propertyTables) {
164
246
  if (propertyTable.class === schemaClassName) {
165
247
  return propertyTable;
166
248
  }
@@ -170,17 +252,17 @@ function findPropertyTableByClass(
170
252
  }
171
253
 
172
254
  /**
173
- * Takes data from property textures reffered by the primitive
255
+ * Takes data from property textures reffered by the primitive.
174
256
  * @param scenegraph - Instance of the class for structured access to GLTF data.
175
- * @param propertyTextures - propertyTexture definition taken from the top-level extention
176
- * @param primitive - Primitive object
177
- * @param extension - top-level extension
257
+ * @param propertyTextures - propertyTexture definition taken from the top-level extention.
258
+ * @param primitive - Primitive object.
259
+ * @param extension - Top-level extension.
178
260
  */
179
261
  function processPrimitivePropertyTextures(
180
262
  scenegraph: GLTFScenegraph,
181
263
  propertyTextures: GLTF_EXT_structural_metadata_PropertyTexture[],
182
264
  primitive: GLTFMeshPrimitive,
183
- extension: GLTF_EXT_structural_metadata
265
+ extension: GLTF_EXT_structural_metadata_GLTF
184
266
  ): void {
185
267
  if (!propertyTextures) {
186
268
  return;
@@ -200,17 +282,17 @@ function processPrimitivePropertyTextures(
200
282
  }
201
283
 
202
284
  /**
203
- * Takes property data from the texture pointed by the primitive and appends them to `exension.data`
285
+ * Takes property data from the texture pointed by the primitive and appends them to `exension.data`.
204
286
  * @param scenegraph - Instance of the class for structured access to GLTF data.
205
287
  * @param propertyTexture - propertyTexture definition taken from the top-level extension.
206
- * @param primitive - Primitive object
207
- * @param extension - top-level extension
288
+ * @param primitive - Primitive object.
289
+ * @param extension - Top-level extension.
208
290
  */
209
291
  function processPrimitivePropertyTexture(
210
292
  scenegraph: GLTFScenegraph,
211
293
  propertyTexture: GLTF_EXT_structural_metadata_PropertyTexture,
212
294
  primitive: GLTFMeshPrimitive,
213
- extension: GLTF_EXT_structural_metadata
295
+ extension: GLTF_EXT_structural_metadata_GLTF
214
296
  ): void {
215
297
  if (!propertyTexture.properties) {
216
298
  return;
@@ -238,12 +320,12 @@ function processPrimitivePropertyTexture(
238
320
  }
239
321
  */
240
322
  const className = propertyTexture.class;
241
- for (const propName in propertyTexture.properties) {
242
- // propName has values like "speed", "direction"
323
+ for (const propertyName in propertyTexture.properties) {
324
+ // propertyName has values like "speed", "direction"
243
325
  // Make attributeName as a combination of the class name and the propertyName like "wind_speed" or "wind_direction"
244
- const attributeName = `${className}_${propName}`;
326
+ const attributeName = `${className}_${propertyName}`;
245
327
  const textureInfoTopLevel: GLTFTextureInfoMetadata | undefined =
246
- propertyTexture.properties?.[propName];
328
+ propertyTexture.properties?.[propertyName];
247
329
  if (!textureInfoTopLevel) {
248
330
  // eslint-disable-next-line no-continue
249
331
  continue;
@@ -281,8 +363,8 @@ function processPrimitivePropertyTexture(
281
363
  * Navigates through all properies in the property table, gets properties data,
282
364
  * and put the data to `propertyTable.data` as an array.
283
365
  * @param scenegraph - Instance of the class for structured access to GLTF data.
284
- * @param schema - schema object
285
- * @param propertyTable - propertyTable definition taken from the top-level extension
366
+ * @param schema - schema object.
367
+ * @param propertyTable - propertyTable definition taken from the top-level extension.
286
368
  */
287
369
  function processPropertyTable(
288
370
  scenegraph: GLTFScenegraph,
@@ -318,12 +400,12 @@ function processPropertyTable(
318
400
  }
319
401
 
320
402
  /**
321
- * Decodes a propertyTable column from binary source based on property type
403
+ * Decodes a propertyTable column from binary source based on property type.
322
404
  * @param scenegraph - Instance of the class for structured access to GLTF data.
323
- * @param schema - Schema object
324
- * @param classProperty - class property object
405
+ * @param schema - Schema object.
406
+ * @param classProperty - class property object.
325
407
  * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
326
- * @param propertyTableProperty - propertyTable's property metadata
408
+ * @param propertyTableProperty - propertyTable's property metadata.
327
409
  * @returns {string[] | number[] | string[][] | number[][]}
328
410
  */
329
411
  function getPropertyDataFromBinarySource(
@@ -392,12 +474,12 @@ function getPropertyDataFromBinarySource(
392
474
  }
393
475
 
394
476
  /**
395
- * Parse propertyTable.property.arrayOffsets that are offsets of sub-arrays in a flatten array of values
477
+ * Parses propertyTable.property.arrayOffsets that are offsets of sub-arrays in a flatten array of values.
396
478
  * @param scenegraph - Instance of the class for structured access to GLTF data.
397
- * @param classProperty - class property object
398
- * @param propertyTableProperty - propertyTable's property metadata
479
+ * @param classProperty - class property object.
480
+ * @param propertyTableProperty - propertyTable's property metadata.
399
481
  * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
400
- * @returns typed array with offset values
482
+ * @returns Typed array with offset values.
401
483
  * @see https://github.com/CesiumGS/glTF/blob/2976f1183343a47a29e4059a70961371cd2fcee8/extensions/2.0/Vendor/EXT_structural_metadata/schema/propertyTable.property.schema.json#L21
402
484
  */
403
485
  function getArrayOffsetsForProperty(
@@ -412,14 +494,13 @@ function getArrayOffsetsForProperty(
412
494
  // If `count` is NOT defined, it's a VARIABLE-length array
413
495
  typeof classProperty.count === 'undefined' &&
414
496
  // `arrayOffsets` is an index of the buffer view containing offsets for variable-length arrays.
415
- typeof propertyTableProperty.arrayOffsets !== 'undefined' &&
416
- typeof propertyTableProperty.arrayOffsetType !== 'undefined'
497
+ typeof propertyTableProperty.arrayOffsets !== 'undefined'
417
498
  ) {
418
499
  // Data are in a VARIABLE-length array
419
500
  return getOffsetsForProperty(
420
501
  scenegraph,
421
502
  propertyTableProperty.arrayOffsets,
422
- propertyTableProperty.arrayOffsetType,
503
+ propertyTableProperty.arrayOffsetType || 'UINT32',
423
504
  numberOfElements
424
505
  );
425
506
  }
@@ -427,11 +508,11 @@ function getArrayOffsetsForProperty(
427
508
  }
428
509
 
429
510
  /**
430
- * Parse propertyTable.property.stringOffsets
431
- * @param scenegraph - Instance of the class for structured access to GLTF data
432
- * @param propertyTableProperty - propertyTable's property metadata
433
- * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table
434
- * @returns typed array with offset values
511
+ * Parses propertyTable.property.stringOffsets.
512
+ * @param scenegraph - Instance of the class for structured access to GLTF data.
513
+ * @param propertyTableProperty - propertyTable's property metadata.
514
+ * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
515
+ * @returns Typed array with offset values.
435
516
  * @see https://github.com/CesiumGS/glTF/blob/2976f1183343a47a29e4059a70961371cd2fcee8/extensions/2.0/Vendor/EXT_structural_metadata/schema/propertyTable.property.schema.json#L29C10-L29C23
436
517
  */
437
518
  function getStringOffsetsForProperty(
@@ -440,14 +521,13 @@ function getStringOffsetsForProperty(
440
521
  numberOfElements: number
441
522
  ): TypedArray | null {
442
523
  if (
443
- typeof propertyTableProperty.stringOffsets !== 'undefined' && // `stringOffsets` is an index of the buffer view containing offsets for strings.
444
- typeof propertyTableProperty.stringOffsetType !== 'undefined'
524
+ typeof propertyTableProperty.stringOffsets !== 'undefined' // `stringOffsets` is an index of the buffer view containing offsets for strings.
445
525
  ) {
446
526
  // Data are in a FIXED-length array
447
527
  return getOffsetsForProperty(
448
528
  scenegraph,
449
529
  propertyTableProperty.stringOffsets,
450
- propertyTableProperty.stringOffsetType,
530
+ propertyTableProperty.stringOffsetType || 'UINT32',
451
531
  numberOfElements
452
532
  );
453
533
  }
@@ -456,11 +536,11 @@ function getStringOffsetsForProperty(
456
536
 
457
537
  /**
458
538
  * Decodes properties of SCALAR, VEC-N, MAT-N types from binary sourse.
459
- * @param classProperty - class property object
539
+ * @param classProperty - class property object.
460
540
  * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
461
- * @param valuesDataBytes - data taken from values property of the property table property.
462
- * @param arrayOffsets - offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
463
- * @returns property values in a typed array or in an array of typed arrays
541
+ * @param valuesDataBytes - Data taken from values property of the property table property.
542
+ * @param arrayOffsets - Offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
543
+ * @returns Property values in a typed array or in an array of typed arrays.
464
544
  */
465
545
  function getPropertyDataNumeric(
466
546
  classProperty: GLTF_EXT_structural_metadata_ClassProperty,
@@ -513,15 +593,15 @@ function getPropertyDataNumeric(
513
593
  }
514
594
 
515
595
  /**
516
- * Parse variable-length array data.
596
+ * Parses variable-length array data.
517
597
  * In this case every value of the property in the table will be an array
518
- * of arbitrary length
519
- * @param valuesData - values in a flat typed array
520
- * @param numberOfElements - number of rows in the property table
521
- * @param arrayOffsets - offsets of nested arrays in the flat values array
522
- * @param valuesDataBytesLength - data byte length
523
- * @param valueSize - value size in bytes
524
- * @returns array of typed arrays
598
+ * of arbitrary length.
599
+ * @param valuesData - Values in a flat typed array.
600
+ * @param numberOfElements - Number of rows in the property table.
601
+ * @param arrayOffsets - Offsets of nested arrays in the flat values array.
602
+ * @param valuesDataBytesLength - Data byte length.
603
+ * @param valueSize - Value size in bytes.
604
+ * @returns Array of typed arrays.
525
605
  */
526
606
  function parseVariableLengthArrayNumeric(
527
607
  valuesData: BigTypedArray,
@@ -545,13 +625,13 @@ function parseVariableLengthArrayNumeric(
545
625
  }
546
626
 
547
627
  /**
548
- * Parse fixed-length array data
628
+ * Parses fixed-length array data.
549
629
  * In this case every value of the property in the table will be an array
550
- * of constant length equal to `arrayCount`
551
- * @param valuesData - values in a flat typed array
552
- * @param numberOfElements - number of rows in the property table
553
- * @param arrayCount - nested arrays length
554
- * @returns array of typed arrays
630
+ * of constant length equal to `arrayCount`.
631
+ * @param valuesData - Values in a flat typed array.
632
+ * @param numberOfElements - Number of rows in the property table.
633
+ * @param arrayCount - Nested arrays length.
634
+ * @returns Array of typed arrays.
555
635
  */
556
636
  function parseFixedLengthArrayNumeric(
557
637
  valuesData: BigTypedArray,
@@ -568,12 +648,12 @@ function parseFixedLengthArrayNumeric(
568
648
 
569
649
  /**
570
650
  * Decodes properties of string type from binary source.
571
- * @param classProperty - class property object
651
+ * @param classProperty - Class property object.
572
652
  * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
573
- * @param valuesDataBytes - data taken from values property of the property table property.
574
- * @param arrayOffsets - offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
575
- * @param stringOffsets - index of the buffer view containing offsets for strings. It should be available for string type.
576
- * @returns string property values
653
+ * @param valuesDataBytes - Data taken from values property of the property table property.
654
+ * @param arrayOffsets - Offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
655
+ * @param stringOffsets - Index of the buffer view containing offsets for strings. It should be available for string type.
656
+ * @returns String property values
577
657
  */
578
658
  function getPropertyDataString(
579
659
  classProperty: GLTF_EXT_structural_metadata_ClassProperty,
@@ -611,12 +691,12 @@ function getPropertyDataString(
611
691
 
612
692
  /**
613
693
  * Decodes properties of enum type from binary source.
614
- * @param schema - schema object
615
- * @param classProperty - class property object
694
+ * @param schema - Schema object.
695
+ * @param classProperty - Class property object.
616
696
  * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
617
- * @param valuesDataBytes - data taken from values property of the property table property.
618
- * @param arrayOffsets - offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
619
- * @returns strings array of nested strings array
697
+ * @param valuesDataBytes - Data taken from values property of the property table property.
698
+ * @param arrayOffsets - Offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
699
+ * @returns Strings array of nested strings array.
620
700
  */
621
701
  function getPropertyDataENUM(
622
702
  schema: GLTF_EXT_structural_metadata_Schema,
@@ -679,14 +759,14 @@ function getPropertyDataENUM(
679
759
  }
680
760
 
681
761
  /**
682
- * Parse variable length nested ENUM arrays
683
- * @param params.valuesData - values in a flat typed array
762
+ * Parses variable length nested ENUM arrays.
763
+ * @param params.valuesData - Values in a flat typed array.
684
764
  * @param params.numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
685
- * @param params.arrayOffsets - offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
686
- * @param params.valuesDataBytesLength - byte length of values array
687
- * @param params.elementSize - single element byte size
688
- * @param params.enumEntry - enums dictionary
689
- * @returns nested strings array
765
+ * @param params.arrayOffsets - Offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
766
+ * @param params.valuesDataBytesLength - Byte length of values array.
767
+ * @param params.elementSize - Single element byte size.
768
+ * @param params.enumEntry - Enums dictionary.
769
+ * @returns Nested strings array.
690
770
  */
691
771
  function parseVariableLengthArrayENUM(params: {
692
772
  valuesData: BigTypedArray;
@@ -721,12 +801,12 @@ function parseVariableLengthArrayENUM(params: {
721
801
  }
722
802
 
723
803
  /**
724
- * Parse fixed length ENUM arrays
725
- * @param valuesData - values in a flat typed array
804
+ * Parses fixed length ENUM arrays.
805
+ * @param valuesData - Values in a flat typed array.
726
806
  * @param numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
727
- * @param arrayCount - nested arrays length
728
- * @param enumEntry - enums dictionary
729
- * @returns nested strings array
807
+ * @param arrayCount - Nested arrays length.
808
+ * @param enumEntry - Enums dictionary.
809
+ * @returns Nested strings array.
730
810
  */
731
811
  function parseFixedLengthArrayENUM(
732
812
  valuesData: BigTypedArray,
@@ -744,12 +824,12 @@ function parseFixedLengthArrayENUM(
744
824
  }
745
825
 
746
826
  /**
747
- * Parse ENUM values into a string array
748
- * @param valuesData - values in a flat typed array
749
- * @param offset - offset to start parse from
750
- * @param count - values length to parse
751
- * @param enumEntry - enums dictionary
752
- * @returns array of string with parsed ENUM names
827
+ * Parses ENUM values into a string array.
828
+ * @param valuesData - Values in a flat typed array.
829
+ * @param offset - Offset to start parse from.
830
+ * @param count - Values length to parse.
831
+ * @param enumEntry - Enums dictionary.
832
+ * @returns Array of strings with parsed ENUM names.
753
833
  */
754
834
  function getEnumsArray(
755
835
  valuesData: BigTypedArray,
@@ -780,7 +860,7 @@ function getEnumsArray(
780
860
  /**
781
861
  * Looks up ENUM whose `value` property matches the specified number in the parameter `value`.
782
862
  * @param {GLTF_EXT_structural_metadata_Enum} enumEntry - ENUM entry containing the array of possible enums.
783
- * @param {number} value - the value of the ENUM to locate.
863
+ * @param {number} value - The value of the ENUM to locate.
784
864
  * @returns {GLTF_EXT_structural_metadata_EnumValue | null} ENUM matcihng the specified value or null of no ENUM object was found.
785
865
  */
786
866
  function getEnumByValue(
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable camelcase */
2
+ import type {GLTF} from '../../types/gltf-json-schema';
2
3
  import type {
3
- GLTF,
4
4
  GLTF_EXT_feature_metadata_Class,
5
5
  GLTF_EXT_feature_metadata_ClassProperty,
6
6
  GLTF_EXT_feature_metadata_FeatureTable,
@@ -8,12 +8,13 @@ import type {
8
8
  GLTF_EXT_feature_metadata_FeatureTexture,
9
9
  GLTF_EXT_feature_metadata_GLTF,
10
10
  GLTF_EXT_feature_metadata_TextureAccessor
11
- } from '../../types/gltf-json-schema';
11
+ } from '../../types/gltf-ext-feature-metadata-schema';
12
12
  import type {BigTypedArray, TypedArray} from '@loaders.gl/schema';
13
+ import type {FeatureTableJson} from '../../types/gltf-types';
13
14
  import {GLTFScenegraph} from '../../api/gltf-scenegraph';
14
15
  import {getImageData} from '@loaders.gl/images';
15
16
  import {GLTFMeshPrimitive} from '../../types/gltf-json-schema';
16
- import {getComponentTypeFromArray} from '../../gltf-utils/gltf-utils';
17
+ import {getComponentTypeFromArray, getFloat32ArrayForAccessor} from '../../gltf-utils/gltf-utils';
17
18
  import {GLTFLoaderOptions} from '../../../gltf-loader';
18
19
  import {emod} from '@loaders.gl/math';
19
20
  import {convertRawBufferToMetadataArray, getOffsetsForProperty} from '../utils/3d-tiles-utils';
@@ -27,6 +28,65 @@ export async function decode(gltfData: {json: GLTF}, options: GLTFLoaderOptions)
27
28
  decodeExtFeatureMetadata(scenegraph, options);
28
29
  }
29
30
 
31
+ /**
32
+ * Handles EXT_feature_metadata to get property table.
33
+ * @param extension - Global level of EXT_FEATURE_METADATA extension.
34
+ * @param metadataClass - User selected feature metadata class name.
35
+ * @returns {FeatureTableJson | null} Property table or null if the extension can't be handled properly.
36
+ */
37
+ export function getPropertyTableFromExtFeatureMetadata(
38
+ extension: GLTF_EXT_feature_metadata_GLTF,
39
+ metadataClass?: string
40
+ ): FeatureTableJson | null {
41
+ if (extension.featureTables) {
42
+ /**
43
+ * Take only first feature table to generate attributes storage info object.
44
+ * TODO: Think about getting data from all feature tables?
45
+ * It can be tricky just because 3dTiles is able to have multiple featureId attributes and multiple feature tables.
46
+ * In I3S we should decide which featureIds attribute will be passed to geometry data.
47
+ */
48
+ const firstFeatureTableName = Object.keys(extension.featureTables)?.[0];
49
+
50
+ if (firstFeatureTableName) {
51
+ const featureTable = extension.featureTables[firstFeatureTableName];
52
+ const propertyTable = {};
53
+
54
+ for (const propertyName in featureTable.properties) {
55
+ propertyTable[propertyName] = featureTable.properties[propertyName].data;
56
+ }
57
+
58
+ return propertyTable;
59
+ }
60
+ }
61
+
62
+ if (extension.featureTextures) {
63
+ let featureTexture: string | undefined;
64
+ for (const textureKey in extension.featureTextures) {
65
+ const texture = extension.featureTextures[textureKey];
66
+ if (texture.class === metadataClass) {
67
+ featureTexture = textureKey;
68
+ }
69
+ }
70
+
71
+ if (typeof featureTexture === 'string') {
72
+ const featureTable = extension.featureTextures[featureTexture];
73
+ const propertyTable = {};
74
+
75
+ for (const propertyName in featureTable.properties) {
76
+ propertyTable[propertyName] = featureTable.properties[propertyName].data;
77
+ }
78
+
79
+ return propertyTable;
80
+ }
81
+ }
82
+
83
+ // eslint-disable-next-line no-console
84
+ console.warn(
85
+ 'Cannot get property table from EXT_feature_metadata extension. There is neither featureTables, nor featureTextures in the extension.'
86
+ );
87
+ return null;
88
+ }
89
+
30
90
  /**
31
91
  * Decodes feature metadata from extension
32
92
  * @param scenegraph
@@ -320,16 +380,15 @@ function processPrimitiveTextures(
320
380
  const textureData: number[] = [];
321
381
  const texCoordAccessorKey = `TEXCOORD_${featureTextureProperty.texture.texCoord}`;
322
382
  const texCoordAccessorIndex = primitive.attributes[texCoordAccessorKey];
323
- const texCoordBufferView = scenegraph.getBufferView(texCoordAccessorIndex);
324
- const texCoordArray: Uint8Array = scenegraph.getTypedArrayForBufferView(texCoordBufferView);
325
-
326
- const textureCoordinates: Float32Array = new Float32Array(
327
- texCoordArray.buffer,
328
- texCoordArray.byteOffset,
329
- texCoordArray.length / 4
330
- );
331
383
  // textureCoordinates contains UV coordinates of the actual data stored in the texture
332
384
  // accessor.count is a number of UV pairs (they are stored as VEC2)
385
+ const textureCoordinates: Float32Array | null = getFloat32ArrayForAccessor(
386
+ scenegraph.gltf,
387
+ texCoordAccessorIndex
388
+ );
389
+ if (!textureCoordinates) {
390
+ return;
391
+ }
333
392
 
334
393
  const textureIndex = featureTextureProperty.texture.index;
335
394
  const texture = json.textures?.[textureIndex];