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

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 (85) hide show
  1. package/dist/dist.min.js +148 -102
  2. package/dist/es5/lib/extensions/EXT_mesh_features.js +3 -3
  3. package/dist/es5/lib/extensions/EXT_mesh_features.js.map +1 -1
  4. package/dist/es5/lib/extensions/EXT_structural_metadata.js +88 -86
  5. package/dist/es5/lib/extensions/EXT_structural_metadata.js.map +1 -1
  6. package/dist/es5/lib/extensions/deprecated/EXT_feature_metadata.js +26 -13
  7. package/dist/es5/lib/extensions/deprecated/EXT_feature_metadata.js.map +1 -1
  8. package/dist/es5/lib/extensions/{data-processing.js → utils/3d-tiles-utils.js} +25 -6
  9. package/dist/es5/lib/extensions/utils/3d-tiles-utils.js.map +1 -0
  10. package/dist/es5/lib/types/gltf-ext-structural-metadata-schema.js.map +1 -1
  11. package/dist/es5/lib/types/gltf-json-schema.js.map +1 -1
  12. package/dist/es5/lib/utils/version.js +1 -1
  13. package/dist/esm/lib/extensions/EXT_mesh_features.js +1 -1
  14. package/dist/esm/lib/extensions/EXT_mesh_features.js.map +1 -1
  15. package/dist/esm/lib/extensions/EXT_structural_metadata.js +85 -81
  16. package/dist/esm/lib/extensions/EXT_structural_metadata.js.map +1 -1
  17. package/dist/esm/lib/extensions/deprecated/EXT_feature_metadata.js +26 -13
  18. package/dist/esm/lib/extensions/deprecated/EXT_feature_metadata.js.map +1 -1
  19. package/dist/esm/lib/extensions/{data-processing.js → utils/3d-tiles-utils.js} +24 -6
  20. package/dist/esm/lib/extensions/utils/3d-tiles-utils.js.map +1 -0
  21. package/dist/esm/lib/types/gltf-ext-structural-metadata-schema.js.map +1 -1
  22. package/dist/esm/lib/types/gltf-json-schema.js.map +1 -1
  23. package/dist/esm/lib/utils/version.js +1 -1
  24. package/dist/lib/extensions/EXT_structural_metadata.d.ts +3 -3
  25. package/dist/lib/extensions/EXT_structural_metadata.d.ts.map +1 -1
  26. package/dist/lib/extensions/deprecated/EXT_feature_metadata.d.ts.map +1 -1
  27. package/dist/lib/extensions/utils/3d-tiles-utils.d.ts +52 -0
  28. package/dist/lib/extensions/utils/3d-tiles-utils.d.ts.map +1 -0
  29. package/dist/lib/types/gltf-ext-structural-metadata-schema.d.ts +4 -4
  30. package/dist/lib/types/gltf-ext-structural-metadata-schema.d.ts.map +1 -1
  31. package/dist/lib/types/gltf-json-schema.d.ts +1 -1
  32. package/dist/lib/types/gltf-json-schema.d.ts.map +1 -1
  33. package/package.json +6 -6
  34. package/src/lib/extensions/EXT_mesh_features.ts +1 -1
  35. package/src/lib/extensions/EXT_structural_metadata.ts +267 -200
  36. package/src/lib/extensions/deprecated/EXT_feature_metadata.ts +123 -19
  37. package/src/lib/extensions/{data-processing.ts → utils/3d-tiles-utils.ts} +95 -34
  38. package/src/lib/types/gltf-ext-structural-metadata-schema.ts +6 -4
  39. package/src/lib/types/gltf-json-schema.ts +1 -1
  40. package/dist/bundle.js +0 -5
  41. package/dist/es5/lib/extensions/data-processing.js.map +0 -1
  42. package/dist/esm/lib/extensions/data-processing.js.map +0 -1
  43. package/dist/glb-loader.js +0 -34
  44. package/dist/glb-writer.js +0 -35
  45. package/dist/gltf-loader.js +0 -50
  46. package/dist/gltf-writer.js +0 -32
  47. package/dist/index.js +0 -34
  48. package/dist/lib/api/gltf-extensions.js +0 -88
  49. package/dist/lib/api/gltf-scenegraph.js +0 -580
  50. package/dist/lib/api/normalize-gltf-v1.js +0 -299
  51. package/dist/lib/api/post-process-gltf.js +0 -433
  52. package/dist/lib/encoders/encode-glb.js +0 -72
  53. package/dist/lib/encoders/encode-gltf.js +0 -32
  54. package/dist/lib/extensions/EXT_mesh_features.js +0 -89
  55. package/dist/lib/extensions/EXT_meshopt_compression.js +0 -41
  56. package/dist/lib/extensions/EXT_structural_metadata.js +0 -504
  57. package/dist/lib/extensions/EXT_texture_webp.js +0 -36
  58. package/dist/lib/extensions/KHR_binary_gltf.js +0 -39
  59. package/dist/lib/extensions/KHR_draco_mesh_compression.js +0 -137
  60. package/dist/lib/extensions/KHR_texture_basisu.js +0 -29
  61. package/dist/lib/extensions/KHR_texture_transform.js +0 -227
  62. package/dist/lib/extensions/data-processing.d.ts +0 -34
  63. package/dist/lib/extensions/data-processing.d.ts.map +0 -1
  64. package/dist/lib/extensions/data-processing.js +0 -212
  65. package/dist/lib/extensions/deprecated/EXT_feature_metadata.js +0 -282
  66. package/dist/lib/extensions/deprecated/KHR_lights_punctual.js +0 -59
  67. package/dist/lib/extensions/deprecated/KHR_materials_unlit.js +0 -44
  68. package/dist/lib/extensions/deprecated/KHR_techniques_webgl.js +0 -79
  69. package/dist/lib/gltf-utils/get-typed-array.js +0 -41
  70. package/dist/lib/gltf-utils/gltf-attribute-utils.js +0 -73
  71. package/dist/lib/gltf-utils/gltf-constants.js +0 -43
  72. package/dist/lib/gltf-utils/gltf-utils.js +0 -90
  73. package/dist/lib/gltf-utils/resolve-url.js +0 -18
  74. package/dist/lib/parsers/parse-glb.js +0 -166
  75. package/dist/lib/parsers/parse-gltf.js +0 -185
  76. package/dist/lib/types/glb-types.js +0 -2
  77. package/dist/lib/types/gltf-ext-mesh-features-schema.js +0 -2
  78. package/dist/lib/types/gltf-ext-structural-metadata-schema.js +0 -2
  79. package/dist/lib/types/gltf-json-schema.js +0 -4
  80. package/dist/lib/types/gltf-postprocessed-schema.js +0 -4
  81. package/dist/lib/types/gltf-types.js +0 -3
  82. package/dist/lib/utils/assert.js +0 -12
  83. package/dist/lib/utils/version.js +0 -7
  84. package/dist/meshopt/meshopt-decoder.js +0 -118
  85. package/dist/webp/webp.js +0 -38
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable camelcase */
2
+ import type {BigTypedArray, TypedArray} from '@loaders.gl/schema';
2
3
  import type {GLTF, GLTFTextureInfoMetadata, GLTFMeshPrimitive} from '../types/gltf-json-schema';
3
4
  import type {
4
5
  GLTF_EXT_structural_metadata_Schema,
@@ -11,8 +12,6 @@ import type {
11
12
  GLTF_EXT_structural_metadata_PropertyTable_Property,
12
13
  GLTF_EXT_structural_metadata_Primitive
13
14
  } from '../types/gltf-ext-structural-metadata-schema';
14
-
15
- import type {TypedArray} from '@loaders.gl/schema';
16
15
  import type {GLTFLoaderOptions} from '../../gltf-loader';
17
16
 
18
17
  import {GLTFScenegraph} from '../api/gltf-scenegraph';
@@ -20,8 +19,10 @@ import {
20
19
  convertRawBufferToMetadataArray,
21
20
  getPrimitiveTextureData,
22
21
  primitivePropertyDataToAttributes,
23
- getArrayElementByteSize
24
- } from './data-processing';
22
+ getArrayElementByteSize,
23
+ NumericComponentType,
24
+ getOffsetsForProperty
25
+ } from './utils/3d-tiles-utils';
25
26
 
26
27
  const EXT_STRUCTURAL_METADATA_NAME = 'EXT_structural_metadata';
27
28
  export const name = EXT_STRUCTURAL_METADATA_NAME;
@@ -90,9 +91,9 @@ const extensions = {
90
91
 
91
92
  /**
92
93
  * Returns the property table populated with the data taken according to the extension schema.
93
- * @param {GLTFScenegraph} scenegraph - Instance of the class for structured access to GLTF data.
94
- * @param {number} propertyTableIndex - Index of the property table to locate.
95
- * @returns {GLTF_EXT_structural_metadata_PropertyTable} Property table populated with the data.
94
+ * @param scenegraph - Instance of the class for structured access to GLTF data.
95
+ * @param propertyTableIndex - Index of the property table to locate.
96
+ * @returns Property table populated with the data.
96
97
  * Throws an exception if no property table was found for propertyTableIndex provided.
97
98
  */
98
99
  export function getPropertyTablePopulated(
@@ -114,8 +115,8 @@ export function getPropertyTablePopulated(
114
115
 
115
116
  /**
116
117
  * Decodes feature metadata from extension
117
- * @param {GLTFScenegraph} scenegraph - Instance of the class for structured access to GLTF data.
118
- * @param {GLTFLoaderOptions} options - loader options.
118
+ * @param scenegraph - Instance of the class for structured access to GLTF data.
119
+ * @param options - loader options.
119
120
  */
120
121
  function decodeExtStructuralMetadata(scenegraph: GLTFScenegraph, options: GLTFLoaderOptions): void {
121
122
  const extension: GLTF_EXT_structural_metadata | null = scenegraph.getExtension(
@@ -148,12 +149,32 @@ function decodeExtStructuralMetadata(scenegraph: GLTFScenegraph, options: GLTFLo
148
149
  }
149
150
  }
150
151
 
152
+ /**
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
156
+ */
157
+ function findPropertyTableByClass(
158
+ propertyTables: GLTF_EXT_structural_metadata_PropertyTable[],
159
+ schemaClassName: string
160
+ ): GLTF_EXT_structural_metadata_PropertyTable | null {
161
+ for (let i = 0, len = propertyTables.length; i < len; i++) {
162
+ const propertyTable = propertyTables[i];
163
+
164
+ if (propertyTable.class === schemaClassName) {
165
+ return propertyTable;
166
+ }
167
+ }
168
+
169
+ return null;
170
+ }
171
+
151
172
  /**
152
173
  * Takes data from property textures reffered by the primitive
153
- * @param {GLTFScenegraph} scenegraph - Instance of the class for structured access to GLTF data.
154
- * @param {GLTF_EXT_structural_metadata_PropertyTexture[]} propertyTextures - propertyTexture definition taken from the top-level extention
155
- * @param {GLTFMeshPrimitive} primitive - Primitive object
156
- * @param {GLTF_EXT_structural_metadata} extension - top-level extension
174
+ * @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
157
178
  */
158
179
  function processPrimitivePropertyTextures(
159
180
  scenegraph: GLTFScenegraph,
@@ -180,10 +201,10 @@ function processPrimitivePropertyTextures(
180
201
 
181
202
  /**
182
203
  * Takes property data from the texture pointed by the primitive and appends them to `exension.data`
183
- * @param {GLTFScenegraph} scenegraph - Instance of the class for structured access to GLTF data.
184
- * @param {GLTF_EXT_structural_metadata_PropertyTexture} propertyTexture - propertyTexture definition taken from the top-level extension.
185
- * @param {GLTFMeshPrimitive} primitive - Primitive object
186
- * @param {GLTF_EXT_structural_metadata} extension - top-level extension
204
+ * @param scenegraph - Instance of the class for structured access to GLTF data.
205
+ * @param propertyTexture - propertyTexture definition taken from the top-level extension.
206
+ * @param primitive - Primitive object
207
+ * @param extension - top-level extension
187
208
  */
188
209
  function processPrimitivePropertyTexture(
189
210
  scenegraph: GLTFScenegraph,
@@ -259,9 +280,9 @@ function processPrimitivePropertyTexture(
259
280
  /**
260
281
  * Navigates through all properies in the property table, gets properties data,
261
282
  * and put the data to `propertyTable.data` as an array.
262
- * @param {GLTFScenegraph} scenegraph - Instance of the class for structured access to GLTF data.
263
- * @param {GLTF_EXT_structural_metadata_Schema} schema - schema object
264
- * @param {GLTF_EXT_structural_metadata_PropertyTable} propertyTable - propertyTable definition taken from the top-level extension
283
+ * @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
265
286
  */
266
287
  function processPropertyTable(
267
288
  scenegraph: GLTFScenegraph,
@@ -297,56 +318,36 @@ function processPropertyTable(
297
318
  }
298
319
 
299
320
  /**
300
- * Decodes properties from binary sourse based on property type.
301
- * @param {GLTFScenegraph} scenegraph - Instance of the class for structured access to GLTF data.
302
- * @param {GLTF_EXT_structural_metadata_Schema} schema - Schema object
303
- * @param {GLTF_EXT_structural_metadata_ClassProperty} classProperty - class property object
304
- * @param {GLTF_EXT_structural_metadata_PropertyTable_Property} propertyTableProperty
305
- * @param {number} numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
321
+ * Decodes a propertyTable column from binary source based on property type
322
+ * @param scenegraph - Instance of the class for structured access to GLTF data.
323
+ * @param schema - Schema object
324
+ * @param classProperty - class property object
325
+ * @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
306
327
  * @returns {string[] | number[] | string[][] | number[][]}
307
328
  */
308
- /* eslint complexity: ["error", 17]*/
309
329
  function getPropertyDataFromBinarySource(
310
330
  scenegraph: GLTFScenegraph,
311
331
  schema: GLTF_EXT_structural_metadata_Schema,
312
332
  classProperty: GLTF_EXT_structural_metadata_ClassProperty,
313
333
  numberOfElements: number,
314
334
  propertyTableProperty: GLTF_EXT_structural_metadata_PropertyTable_Property
315
- ): string[] | number[] | string[][] | number[][] {
316
- let data: string[] | number[] | string[][] | number[][] = [];
335
+ ): string[] | BigTypedArray | string[][] | BigTypedArray[] {
336
+ let data: string[] | BigTypedArray | string[][] | BigTypedArray[] = [];
317
337
  const valuesBufferView = propertyTableProperty.values;
318
338
  const valuesDataBytes: Uint8Array = scenegraph.getTypedArrayForBufferView(valuesBufferView);
319
339
 
320
- let arrayOffsets: TypedArray | null = null;
321
- if (
322
- classProperty.array &&
323
- // `count` is a number of array elements. May only be defined when `array` is true.
324
- typeof classProperty.count === 'undefined' && // If `count` is NOT defined, it's a VARIABLE-length array
325
- typeof propertyTableProperty.arrayOffsets !== 'undefined' && // `arrayOffsets` is an index of the buffer view containing offsets for variable-length arrays.
326
- typeof propertyTableProperty.arrayOffsetType !== 'undefined'
327
- ) {
328
- // Data are in a VARIABLE-length array
329
- arrayOffsets = getOffsetArray(
330
- scenegraph,
331
- propertyTableProperty.arrayOffsets,
332
- propertyTableProperty.arrayOffsetType,
333
- numberOfElements
334
- );
335
- }
336
-
337
- let stringOffsets: TypedArray | null = null;
338
- if (
339
- typeof propertyTableProperty.stringOffsets !== 'undefined' && // `stringOffsets` is an index of the buffer view containing offsets for strings.
340
- typeof propertyTableProperty.stringOffsetType !== 'undefined'
341
- ) {
342
- // Data are in a FIXED-length array
343
- stringOffsets = getOffsetArray(
344
- scenegraph,
345
- propertyTableProperty.stringOffsets,
346
- propertyTableProperty.stringOffsetType,
347
- numberOfElements
348
- );
349
- }
340
+ const arrayOffsets = getArrayOffsetsForProperty(
341
+ scenegraph,
342
+ classProperty,
343
+ propertyTableProperty,
344
+ numberOfElements
345
+ );
346
+ const stringOffsets = getStringOffsetsForProperty(
347
+ scenegraph,
348
+ propertyTableProperty,
349
+ numberOfElements
350
+ );
350
351
 
351
352
  switch (classProperty.type) {
352
353
  case 'SCALAR':
@@ -391,59 +392,100 @@ function getPropertyDataFromBinarySource(
391
392
  }
392
393
 
393
394
  /**
394
- * Gets offset array from `arrayOffsets` or `stringOffsets`.
395
- * @param {GLTFScenegraph} scenegraph - Instance of the class for structured access to GLTF data.
396
- * @param {number} offsets - Buffer view index
397
- * @param offsetType - The type of values in `arrayOffsets` or `stringOffsets`.
398
- * @param {number} numberOfElements - The number of elements in each property array.
399
- * @returns {TypedArray}
395
+ * Parse propertyTable.property.arrayOffsets that are offsets of sub-arrays in a flatten array of values
396
+ * @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
399
+ * @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
401
+ * @see https://github.com/CesiumGS/glTF/blob/2976f1183343a47a29e4059a70961371cd2fcee8/extensions/2.0/Vendor/EXT_structural_metadata/schema/propertyTable.property.schema.json#L21
400
402
  */
401
- function getOffsetArray(
403
+ function getArrayOffsetsForProperty(
402
404
  scenegraph: GLTFScenegraph,
403
- offsets: number,
404
- offsetType: 'UINT8' | 'UINT16' | 'UINT32' | 'UINT64',
405
+ classProperty: GLTF_EXT_structural_metadata_ClassProperty,
406
+ propertyTableProperty: GLTF_EXT_structural_metadata_PropertyTable_Property,
405
407
  numberOfElements: number
406
- ): TypedArray {
407
- const arrayOffsetsBufferView = offsets;
408
- const arrayOffsetsBytes = scenegraph.getTypedArrayForBufferView(arrayOffsetsBufferView);
409
-
410
- const arrayOffsets = convertRawBufferToMetadataArray(
411
- arrayOffsetsBytes,
412
- 'SCALAR', // offsets consist of ONE component
413
- offsetType,
414
- numberOfElements + 1 // The number of offsets is equal to the property table `count` plus one.
415
- );
416
- return arrayOffsets;
408
+ ): TypedArray | null {
409
+ if (
410
+ classProperty.array &&
411
+ // `count` is a number of array elements. May only be defined when `array` is true.
412
+ // If `count` is NOT defined, it's a VARIABLE-length array
413
+ typeof classProperty.count === 'undefined' &&
414
+ // `arrayOffsets` is an index of the buffer view containing offsets for variable-length arrays.
415
+ typeof propertyTableProperty.arrayOffsets !== 'undefined' &&
416
+ typeof propertyTableProperty.arrayOffsetType !== 'undefined'
417
+ ) {
418
+ // Data are in a VARIABLE-length array
419
+ return getOffsetsForProperty(
420
+ scenegraph,
421
+ propertyTableProperty.arrayOffsets,
422
+ propertyTableProperty.arrayOffsetType,
423
+ numberOfElements
424
+ );
425
+ }
426
+ return null;
427
+ }
428
+
429
+ /**
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
435
+ * @see https://github.com/CesiumGS/glTF/blob/2976f1183343a47a29e4059a70961371cd2fcee8/extensions/2.0/Vendor/EXT_structural_metadata/schema/propertyTable.property.schema.json#L29C10-L29C23
436
+ */
437
+ function getStringOffsetsForProperty(
438
+ scenegraph: GLTFScenegraph,
439
+ propertyTableProperty: GLTF_EXT_structural_metadata_PropertyTable_Property,
440
+ numberOfElements: number
441
+ ): TypedArray | null {
442
+ if (
443
+ typeof propertyTableProperty.stringOffsets !== 'undefined' && // `stringOffsets` is an index of the buffer view containing offsets for strings.
444
+ typeof propertyTableProperty.stringOffsetType !== 'undefined'
445
+ ) {
446
+ // Data are in a FIXED-length array
447
+ return getOffsetsForProperty(
448
+ scenegraph,
449
+ propertyTableProperty.stringOffsets,
450
+ propertyTableProperty.stringOffsetType,
451
+ numberOfElements
452
+ );
453
+ }
454
+ return null;
417
455
  }
418
456
 
419
457
  /**
420
458
  * Decodes properties of SCALAR, VEC-N, MAT-N types from binary sourse.
421
- * @param {GLTF_EXT_structural_metadata_ClassProperty} classProperty - class property object
422
- * @param {number} numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
423
- * @param {Uint8Array} valuesDataBytes - data taken from values property of the property table property.
424
- * @param {TypedArray | null} arrayOffsets - offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
425
- * @returns {number[] | number[][]}
459
+ * @param classProperty - class property object
460
+ * @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
426
464
  */
427
465
  function getPropertyDataNumeric(
428
466
  classProperty: GLTF_EXT_structural_metadata_ClassProperty,
429
467
  numberOfElements: number,
430
468
  valuesDataBytes: Uint8Array,
431
469
  arrayOffsets: TypedArray | null
432
- ): number[] | number[][] {
470
+ ): BigTypedArray | BigTypedArray[] {
433
471
  const isArray = classProperty.array;
434
472
  const arrayCount = classProperty.count;
435
473
 
436
474
  const elementSize = getArrayElementByteSize(classProperty.type, classProperty.componentType);
437
475
  const elementCount = valuesDataBytes.byteLength / elementSize;
438
476
 
439
- let valuesData: TypedArray;
477
+ let valuesData: BigTypedArray | null;
440
478
  if (classProperty.componentType) {
441
479
  valuesData = convertRawBufferToMetadataArray(
442
480
  valuesDataBytes,
443
481
  classProperty.type,
444
- classProperty.componentType, // The datatype of the element's components. Only applicable to `SCALAR`, `VECN`, and `MATN` types.
482
+ // The datatype of the element's components. Only applicable to `SCALAR`, `VECN`, and `MATN` types.
483
+ classProperty.componentType as NumericComponentType,
445
484
  elementCount
446
485
  );
486
+ if (!valuesData) {
487
+ valuesData = valuesDataBytes;
488
+ }
447
489
  } else {
448
490
  // The spec doesn't provide any info what to do if componentType is not set.
449
491
  valuesData = valuesDataBytes;
@@ -452,7 +494,7 @@ function getPropertyDataNumeric(
452
494
  if (isArray) {
453
495
  if (arrayOffsets) {
454
496
  // VARIABLE-length array
455
- return handleVariableLengthArrayNumeric(
497
+ return parseVariableLengthArrayNumeric(
456
498
  valuesData,
457
499
  numberOfElements,
458
500
  arrayOffsets,
@@ -462,70 +504,76 @@ function getPropertyDataNumeric(
462
504
  }
463
505
  if (arrayCount) {
464
506
  // FIXED-length array
465
- return handleFixedLengthArrayNumeric(valuesData, numberOfElements, arrayCount);
507
+ return parseFixedLengthArrayNumeric(valuesData, numberOfElements, arrayCount);
466
508
  }
467
509
  return [];
468
510
  }
469
511
 
470
- // Single value (not an array)
471
- const attributeValueArray: number[] = [];
472
- for (let index = 0; index < numberOfElements; index++) {
473
- const value = valuesData[index];
474
- attributeValueArray.push(value);
475
- }
476
- return attributeValueArray;
512
+ return valuesData;
477
513
  }
478
514
 
479
- function handleVariableLengthArrayNumeric(
480
- valuesData: TypedArray,
515
+ /**
516
+ * Parse variable-length array data.
517
+ * 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
525
+ */
526
+ function parseVariableLengthArrayNumeric(
527
+ valuesData: BigTypedArray,
481
528
  numberOfElements: number,
482
529
  arrayOffsets: TypedArray,
483
530
  valuesDataBytesLength: number,
484
- elementSize: number
485
- ) {
486
- const attributeValueArray: number[][] = [];
531
+ valueSize: number
532
+ ): BigTypedArray[] {
533
+ const attributeValueArray: BigTypedArray[] = [];
487
534
  for (let index = 0; index < numberOfElements; index++) {
488
- const array: number[] = [];
489
535
  const arrayOffset = arrayOffsets[index];
490
536
  const arrayByteSize = arrayOffsets[index + 1] - arrayOffsets[index];
491
- if (arrayByteSize + arrayOffset <= valuesDataBytesLength) {
492
- const typedArrayOffset = arrayOffset / elementSize;
493
- const elementCount = arrayByteSize / elementSize;
494
- for (let i = 0; i < elementCount; i++) {
495
- const value = valuesData[typedArrayOffset + i];
496
- array.push(value);
497
- }
537
+ if (arrayByteSize + arrayOffset > valuesDataBytesLength) {
538
+ break;
498
539
  }
499
- attributeValueArray.push(array);
540
+ const typedArrayOffset = arrayOffset / valueSize;
541
+ const elementCount = arrayByteSize / valueSize;
542
+ attributeValueArray.push(valuesData.slice(typedArrayOffset, typedArrayOffset + elementCount));
500
543
  }
501
544
  return attributeValueArray;
502
545
  }
503
546
 
504
- function handleFixedLengthArrayNumeric(
505
- valuesData: TypedArray,
547
+ /**
548
+ * Parse fixed-length array data
549
+ * 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
555
+ */
556
+ function parseFixedLengthArrayNumeric(
557
+ valuesData: BigTypedArray,
506
558
  numberOfElements: number,
507
559
  arrayCount: number
508
- ) {
509
- const attributeValueArray: number[][] = [];
560
+ ): BigTypedArray[] {
561
+ const attributeValueArray: BigTypedArray[] = [];
510
562
  for (let index = 0; index < numberOfElements; index++) {
511
- const array: number[] = [];
512
- for (let i = 0; i < arrayCount; i++) {
513
- const value = valuesData[i];
514
- array.push(value);
515
- }
516
- attributeValueArray.push(array);
563
+ const elementOffset = index * arrayCount;
564
+ attributeValueArray.push(valuesData.slice(elementOffset, elementOffset + arrayCount));
517
565
  }
518
566
  return attributeValueArray;
519
567
  }
520
568
 
521
569
  /**
522
- * Decodes properties of string type from binary sourse.
523
- * @param {GLTF_EXT_structural_metadata_ClassProperty} classProperty - class property object
524
- * @param {number} numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
525
- * @param {Uint8Array} valuesDataBytes - data taken from values property of the property table property.
526
- * @param {TypedArray | null} arrayOffsets - offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
527
- * @param {TypedArray | null} stringOffsets - index of the buffer view containing offsets for strings. It should be available for string type.
528
- * @returns {string[] | string[][]}
570
+ * Decodes properties of string type from binary source.
571
+ * @param classProperty - class property object
572
+ * @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
529
577
  */
530
578
  function getPropertyDataString(
531
579
  classProperty: GLTF_EXT_structural_metadata_ClassProperty,
@@ -562,13 +610,13 @@ function getPropertyDataString(
562
610
  }
563
611
 
564
612
  /**
565
- * Decodes properties of enum type from binary sourse.
566
- * @param {GLTF_EXT_structural_metadata_Schema} schema - schema object
567
- * @param {GLTF_EXT_structural_metadata_ClassProperty} classProperty - class property object
568
- * @param {number} numberOfElements - The number of elements in each property array that propertyTableProperty contains. It's a number of rows in the table.
569
- * @param {Uint8Array} valuesDataBytes - data taken from values property of the property table property.
570
- * @param {TypedArray | null} arrayOffsets - offsets for variable-length arrays. It's null for fixed-length arrays or scalar types.
571
- * @returns {string[] | string[][]}
613
+ * Decodes properties of enum type from binary source.
614
+ * @param schema - schema object
615
+ * @param classProperty - class property object
616
+ * @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
572
620
  */
573
621
  function getPropertyDataENUM(
574
622
  schema: GLTF_EXT_structural_metadata_Schema,
@@ -577,11 +625,6 @@ function getPropertyDataENUM(
577
625
  valuesDataBytes: Uint8Array,
578
626
  arrayOffsets: TypedArray | null
579
627
  ): string[] | string[][] {
580
- const data: string[] = [];
581
-
582
- const isArray = classProperty.array;
583
- const arrayCount = classProperty.count;
584
-
585
628
  const enumType = classProperty.enumType;
586
629
  // Enum ID as declared in the `enums` dictionary. Required when `type` is `ENUM`.
587
630
  if (!enumType) {
@@ -600,114 +643,138 @@ function getPropertyDataENUM(
600
643
  const enumValueType = enumEntry.valueType || 'UINT16';
601
644
  const elementSize = getArrayElementByteSize(classProperty.type, enumValueType);
602
645
  const elementCount = valuesDataBytes.byteLength / elementSize;
603
- const valuesData: TypedArray = convertRawBufferToMetadataArray(
646
+ let valuesData: BigTypedArray | null = convertRawBufferToMetadataArray(
604
647
  valuesDataBytes,
605
648
  classProperty.type,
606
649
  enumValueType,
607
650
  elementCount
608
651
  );
652
+ if (!valuesData) {
653
+ valuesData = valuesDataBytes;
654
+ }
609
655
 
610
- if (isArray) {
656
+ if (classProperty.array) {
611
657
  if (arrayOffsets) {
612
658
  // VARIABLE-length array
613
- return handleVariableLengthArrayENUM(
659
+ return parseVariableLengthArrayENUM({
614
660
  valuesData,
615
661
  numberOfElements,
616
662
  arrayOffsets,
617
- valuesDataBytes.length,
663
+ valuesDataBytesLength: valuesDataBytes.length,
618
664
  elementSize,
619
665
  enumEntry
620
- );
666
+ });
621
667
  }
668
+
669
+ const arrayCount = classProperty.count;
622
670
  if (arrayCount) {
623
671
  // FIXED-length array
624
- return handleFixedLengthArrayENUM(valuesData, numberOfElements, arrayCount, enumEntry);
672
+ return parseFixedLengthArrayENUM(valuesData, numberOfElements, arrayCount, enumEntry);
625
673
  }
626
674
  return [];
627
675
  }
628
676
 
629
677
  // Single value (not an array)
630
- for (let index = 0; index < numberOfElements; index++) {
631
- const enumValue = valuesData[index];
632
- const enumObject = getEnumByValue(enumEntry, enumValue);
633
- if (enumObject) {
634
- data.push(enumObject.name);
635
- }
636
- }
637
-
638
- return data;
678
+ return getEnumsArray(valuesData, 0, numberOfElements, enumEntry);
639
679
  }
640
680
 
641
- /* eslint max-params: ["error", 6]*/
642
- function handleVariableLengthArrayENUM(
643
- valuesData: TypedArray,
644
- numberOfElements: number,
645
- arrayOffsets: TypedArray,
646
- valuesDataBytesLength: number,
647
- elementSize: number,
648
- enumEntry: GLTF_EXT_structural_metadata_Enum
649
- ) {
681
+ /**
682
+ * Parse variable length nested ENUM arrays
683
+ * @param params.valuesData - values in a flat typed array
684
+ * @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
690
+ */
691
+ function parseVariableLengthArrayENUM(params: {
692
+ valuesData: BigTypedArray;
693
+ numberOfElements: number;
694
+ arrayOffsets: TypedArray;
695
+ valuesDataBytesLength: number;
696
+ elementSize: number;
697
+ enumEntry: GLTF_EXT_structural_metadata_Enum;
698
+ }): string[][] {
699
+ const {
700
+ valuesData,
701
+ numberOfElements,
702
+ arrayOffsets,
703
+ valuesDataBytesLength,
704
+ elementSize,
705
+ enumEntry
706
+ } = params;
650
707
  const attributeValueArray: string[][] = [];
651
708
  for (let index = 0; index < numberOfElements; index++) {
652
- const array: string[] = [];
653
709
  const arrayOffset = arrayOffsets[index];
654
710
  const arrayByteSize = arrayOffsets[index + 1] - arrayOffsets[index];
655
- if (arrayByteSize + arrayOffset <= valuesDataBytesLength) {
656
- const typedArrayOffset = arrayOffset / elementSize;
657
- const elementCount = arrayByteSize / elementSize;
658
- for (let i = 0; i < elementCount; i++) {
659
- const value = valuesData[typedArrayOffset + i];
660
-
661
- const enumObject = getEnumByValue(enumEntry, value);
662
- if (enumObject) {
663
- array.push(enumObject.name);
664
- }
665
- }
711
+ if (arrayByteSize + arrayOffset > valuesDataBytesLength) {
712
+ break;
666
713
  }
714
+
715
+ const typedArrayOffset = arrayOffset / elementSize;
716
+ const elementCount = arrayByteSize / elementSize;
717
+ const array: string[] = getEnumsArray(valuesData, typedArrayOffset, elementCount, enumEntry);
667
718
  attributeValueArray.push(array);
668
719
  }
669
720
  return attributeValueArray;
670
721
  }
671
722
 
672
- function handleFixedLengthArrayENUM(
673
- valuesData: TypedArray,
723
+ /**
724
+ * Parse fixed length ENUM arrays
725
+ * @param valuesData - values in a flat typed array
726
+ * @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
730
+ */
731
+ function parseFixedLengthArrayENUM(
732
+ valuesData: BigTypedArray,
674
733
  numberOfElements: number,
675
734
  arrayCount: number,
676
735
  enumEntry: GLTF_EXT_structural_metadata_Enum
677
- ) {
736
+ ): string[][] {
678
737
  const attributeValueArray: string[][] = [];
679
738
  for (let index = 0; index < numberOfElements; index++) {
680
- const array: string[] = [];
681
- for (let i = 0; i < arrayCount; i++) {
682
- const value = valuesData[i];
683
-
684
- const enumObject = getEnumByValue(enumEntry, value);
685
- if (enumObject) {
686
- array.push(enumObject.name);
687
- }
688
- }
739
+ const elementOffset = arrayCount * index;
740
+ const array: string[] = getEnumsArray(valuesData, elementOffset, arrayCount, enumEntry);
689
741
  attributeValueArray.push(array);
690
742
  }
691
743
  return attributeValueArray;
692
744
  }
745
+
693
746
  /**
694
- * Find the property table by class name.
695
- * @param {GLTF_EXT_structural_metadata_PropertyTable[]} propertyTables
696
- * @param {string} schemaClassName
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
697
753
  */
698
- function findPropertyTableByClass(
699
- propertyTables: GLTF_EXT_structural_metadata_PropertyTable[],
700
- schemaClassName: string
701
- ): GLTF_EXT_structural_metadata_PropertyTable | null {
702
- for (let i = 0, len = propertyTables.length; i < len; i++) {
703
- const propertyTable = propertyTables[i];
754
+ function getEnumsArray(
755
+ valuesData: BigTypedArray,
756
+ offset: number,
757
+ count: number,
758
+ enumEntry: GLTF_EXT_structural_metadata_Enum
759
+ ): string[] {
760
+ const array: string[] = [];
761
+ for (let i = 0; i < count; i++) {
762
+ // At the moment we don't support BigInt. It requires additional calculations logic
763
+ // and might be an issue in Safari
764
+ if (valuesData instanceof BigInt64Array || valuesData instanceof BigUint64Array) {
765
+ array.push('');
766
+ } else {
767
+ const value = valuesData[offset + i];
704
768
 
705
- if (propertyTable.class === schemaClassName) {
706
- return propertyTable;
769
+ const enumObject = getEnumByValue(enumEntry, value);
770
+ if (enumObject) {
771
+ array.push(enumObject.name);
772
+ } else {
773
+ array.push('');
774
+ }
707
775
  }
708
776
  }
709
-
710
- return null;
777
+ return array;
711
778
  }
712
779
 
713
780
  /**