@loaders.gl/tile-converter 4.1.0-alpha.9 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
  2. package/dist/3d-tiles-converter/3d-tiles-converter.js +4 -4
  3. package/dist/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  4. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -1
  5. package/dist/3d-tiles-converter/helpers/b3dm-converter.js +8 -0
  6. package/dist/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  7. package/dist/3d-tiles-converter/json-templates/tileset.d.ts.map +1 -1
  8. package/dist/3d-tiles-converter/json-templates/tileset.js +3 -0
  9. package/dist/3d-tiles-converter/json-templates/tileset.js.map +1 -1
  10. package/dist/constants.d.ts +1 -0
  11. package/dist/constants.d.ts.map +1 -1
  12. package/dist/constants.js +1 -0
  13. package/dist/constants.js.map +1 -1
  14. package/dist/converter-cli.js +3 -3
  15. package/dist/converter-cli.js.map +1 -1
  16. package/dist/converter.min.cjs +131 -220
  17. package/dist/deps-installer/deps-installer.js +1 -1
  18. package/dist/deps-installer/deps-installer.js.map +1 -1
  19. package/dist/i3s-converter/helpers/progress.js +1 -1
  20. package/dist/i3s-converter/helpers/progress.js.map +1 -1
  21. package/dist/i3s-converter/i3s-converter.d.ts +14 -0
  22. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  23. package/dist/i3s-converter/i3s-converter.js +76 -25
  24. package/dist/i3s-converter/i3s-converter.js.map +1 -1
  25. package/dist/i3s-converter/types.d.ts +7 -0
  26. package/dist/i3s-converter/types.d.ts.map +1 -1
  27. package/dist/i3s-converter/types.js +8 -0
  28. package/dist/i3s-converter/types.js.map +1 -1
  29. package/dist/i3s-server/bin/i3s-server.min.cjs +76 -76
  30. package/dist/index.cjs +376 -104
  31. package/dist/lib/utils/compress-util.d.ts +0 -37
  32. package/dist/lib/utils/compress-util.d.ts.map +1 -1
  33. package/dist/lib/utils/compress-util.js +1 -149
  34. package/dist/lib/utils/compress-util.js.map +1 -1
  35. package/dist/lib/utils/conversion-dump.d.ts +81 -0
  36. package/dist/lib/utils/conversion-dump.d.ts.map +1 -0
  37. package/dist/lib/utils/conversion-dump.js +131 -0
  38. package/dist/lib/utils/conversion-dump.js.map +1 -0
  39. package/dist/lib/utils/statistic-utills.js +1 -1
  40. package/dist/lib/utils/statistic-utills.js.map +1 -1
  41. package/dist/lib/utils/write-queue.d.ts +6 -1
  42. package/dist/lib/utils/write-queue.d.ts.map +1 -1
  43. package/dist/lib/utils/write-queue.js +15 -3
  44. package/dist/lib/utils/write-queue.js.map +1 -1
  45. package/dist/pgm-loader.js +1 -1
  46. package/dist/pgm-loader.js.map +1 -1
  47. package/dist/slpk-extractor.min.cjs +31 -31
  48. package/package.json +16 -16
  49. package/src/3d-tiles-converter/3d-tiles-converter.ts +5 -4
  50. package/src/3d-tiles-converter/helpers/b3dm-converter.ts +19 -0
  51. package/src/3d-tiles-converter/json-templates/tileset.ts +3 -0
  52. package/src/constants.ts +1 -0
  53. package/src/converter-cli.ts +3 -3
  54. package/src/i3s-converter/helpers/progress.ts +1 -1
  55. package/src/i3s-converter/i3s-converter.ts +192 -57
  56. package/src/i3s-converter/types.ts +8 -0
  57. package/src/lib/utils/compress-util.ts +1 -264
  58. package/src/lib/utils/conversion-dump.ts +203 -0
  59. package/src/lib/utils/statistic-utills.ts +1 -1
  60. package/src/lib/utils/write-queue.ts +15 -2
@@ -30,12 +30,7 @@ import md5 from 'md5';
30
30
 
31
31
  import NodePages from './helpers/node-pages';
32
32
  import {writeFile, removeDir, writeFileForSlpk, removeFile} from '../lib/utils/file-utils';
33
- import {
34
- compressFileWithGzip,
35
- compressWithChildProcess
36
- // generateHash128FromZip,
37
- // addFileToZip
38
- } from '../lib/utils/compress-util';
33
+ import {compressFileWithGzip} from '../lib/utils/compress-util';
39
34
  import {calculateFilesSize, timeConverter} from '../lib/utils/statistic-utills';
40
35
  import convertB3dmToI3sGeometry, {getPropertyTable} from './helpers/geometry-converter';
41
36
  import {
@@ -51,7 +46,7 @@ import {GEOMETRY_DEFINITION as geometryDefinitionTemlate} from './json-templates
51
46
  import {SHARED_RESOURCES as sharedResourcesTemplate} from './json-templates/shared-resources';
52
47
  import {validateNodeBoundingVolumes} from './helpers/node-debug';
53
48
  import {KTX2BasisWriterWorker} from '@loaders.gl/textures';
54
- import {FileHandleFile, LoaderWithParser} from '@loaders.gl/loader-utils';
49
+ import {LoaderWithParser} from '@loaders.gl/loader-utils';
55
50
  import {I3SMaterialDefinition, TextureSetDefinitionFormats} from '@loaders.gl/i3s';
56
51
  import {ImageWriter} from '@loaders.gl/images';
57
52
  import {GLTFImagePostprocessed} from '@loaders.gl/gltf';
@@ -59,6 +54,7 @@ import {
59
54
  GLTFPrimitiveModeString,
60
55
  I3SConvertedResources,
61
56
  PreprocessData,
57
+ ResourceType,
62
58
  SharedResourcesArrays
63
59
  } from './types';
64
60
  import {WorkerFarm} from '@loaders.gl/worker-utils';
@@ -81,7 +77,8 @@ import {createBoundingVolume} from '@loaders.gl/tiles';
81
77
  import {TraversalConversionProps, traverseDatasetWith} from './helpers/tileset-traversal';
82
78
  import {analyzeTileContent, mergePreprocessData} from './helpers/preprocess-3d-tiles';
83
79
  import {Progress} from './helpers/progress';
84
- import {addOneFile, composeHashFile} from '@loaders.gl/zip';
80
+ import {composeHashFile, createZip} from '@loaders.gl/zip';
81
+ import {ConversionDump, ConversionDumpOptions} from '../lib/utils/conversion-dump';
85
82
 
86
83
  const ION_DEFAULT_TOKEN = process.env?.IonToken;
87
84
  const HARDCODED_NODES_PER_PAGE = 64;
@@ -136,13 +133,14 @@ export default class I3SConverter {
136
133
  generateBoundingVolumes: boolean;
137
134
  layersHasTexture: boolean;
138
135
  workerSource: {[key: string]: string} = {};
139
- writeQueue: WriteQueue<WriteQueueItem> = new WriteQueue();
136
+ writeQueue: WriteQueue<WriteQueueItem> = new WriteQueue(new ConversionDump());
140
137
  compressList: string[] | null = null;
141
138
  preprocessData: PreprocessData = {
142
139
  meshTopologyTypes: new Set(),
143
140
  metadataClasses: new Set()
144
141
  };
145
142
  progresses: Record<string, Progress> = {};
143
+ conversionDump: ConversionDump;
146
144
 
147
145
  constructor() {
148
146
  this.attributeMetadataInfo = new AttributeMetadataInfo();
@@ -165,6 +163,7 @@ export default class I3SConverter {
165
163
  this.generateBoundingVolumes = false;
166
164
  this.layersHasTexture = false;
167
165
  this.compressList = null;
166
+ this.conversionDump = new ConversionDump();
168
167
  }
169
168
 
170
169
  /**
@@ -228,6 +227,8 @@ export default class I3SConverter {
228
227
  analyze = false
229
228
  } = options;
230
229
  this.options = {
230
+ outputPath,
231
+ tilesetName,
231
232
  maxDepth,
232
233
  slpk,
233
234
  sevenZipExe,
@@ -247,7 +248,7 @@ export default class I3SConverter {
247
248
  this.generateTextures = Boolean(generateTextures);
248
249
  this.generateBoundingVolumes = Boolean(generateBoundingVolumes);
249
250
 
250
- this.writeQueue = new WriteQueue();
251
+ this.writeQueue = new WriteQueue(this.conversionDump);
251
252
  this.writeQueue.startListening();
252
253
 
253
254
  console.log('Loading egm file...'); // eslint-disable-line
@@ -258,6 +259,9 @@ export default class I3SConverter {
258
259
  this.nodePages.useWriteFunction(writeFileForSlpk);
259
260
  }
260
261
 
262
+ //create a dump file with convertion options
263
+ await this.conversionDump.createDumpFile(options as ConversionDumpOptions);
264
+
261
265
  try {
262
266
  const preloadOptions = await this._fetchPreloadOptions();
263
267
  let tilesetUrl = inputUrl;
@@ -554,38 +558,16 @@ export default class I3SConverter {
554
558
  * @param tilesetPath - Path to save file
555
559
  */
556
560
  private async _createSlpk(tilesetPath: string): Promise<void> {
561
+ await this.conversionDump.deleteDumpFile();
557
562
  if (this.options.slpk) {
558
563
  const slpkTilesetPath = join(tilesetPath, 'SceneServer', 'layers', '0');
559
564
  const slpkFileName = `${tilesetPath}.slpk`;
560
- await compressWithChildProcess(
561
- slpkTilesetPath,
562
- slpkFileName,
563
- 0,
564
- '.',
565
- this.options.sevenZipExe
566
- );
567
565
 
568
- const hashTable = await composeHashFile(new FileHandleFile(slpkFileName));
569
- await addOneFile(slpkFileName, hashTable, '@specialIndexFileHASH128@');
570
-
571
- // TODO: `addFileToZip` corrupts archive so it can't be validated with windows i3s_converter.exe
572
- // const fileHash128Path = `${tilesetPath}/@specialIndexFileHASH128@`;
573
- // try {
574
- // await generateHash128FromZip(slpkFileName, fileHash128Path);
575
- // await addFileToZip(
576
- // tilesetPath,
577
- // '@specialIndexFileHASH128@',
578
- // slpkFileName,
579
- // this.options.sevenZipExe
580
- // );
581
- // } catch (error) {
582
- // if (error.code === FS_FILE_TOO_LARGE) {
583
- // console.warn(`${slpkFileName} file is too big to generate a hash`); // eslint-disable-line
584
- // } else {
585
- // console.error(error); // eslint-disable-line
586
- // }
587
- // }
588
- // All converted files are contained in slpk now they can be deleted
566
+ await createZip(slpkTilesetPath, slpkFileName, async (fileList) => ({
567
+ path: '@specialIndexFileHASH128@',
568
+ file: await composeHashFile(fileList)
569
+ }));
570
+
589
571
  try {
590
572
  await removeDir(tilesetPath);
591
573
  } catch (e) {
@@ -618,6 +600,7 @@ export default class I3SConverter {
618
600
  if (sourceTile.id) {
619
601
  console.log(`[convert]: ${sourceTile.id}`); // eslint-disable-line
620
602
  }
603
+
621
604
  const {parentNodes, transform} = traversalProps;
622
605
  let transformationMatrix: Matrix4 = transform.clone();
623
606
  if (sourceTile.transform) {
@@ -642,8 +625,9 @@ export default class I3SConverter {
642
625
  timeRemainingString = `${timeRemainingStringBasedOnCount} left`;
643
626
  }
644
627
 
645
- let percentString = this.progresses[PROGRESS_PHASE1_COUNT].getPercentString();
646
- console.log(`[converted ${percentString}%, ${timeRemainingString}]: ${sourceTile.id}`); // eslint-disable-line
628
+ const percentString = this.progresses[PROGRESS_PHASE1_COUNT].getPercentString();
629
+ const progressString = percentString ? ` ${percentString}%, ${timeRemainingString}` : '';
630
+ console.log(`[converted${progressString}]: ${sourceTile.id}`); // eslint-disable-line
647
631
  }
648
632
  return newTraversalProps;
649
633
  }
@@ -756,7 +740,13 @@ export default class I3SConverter {
756
740
  nodes.push(node);
757
741
 
758
742
  if (nodeInPage.mesh) {
759
- await this._writeResources(resources, node.id);
743
+ //update a record in a dump file
744
+ if (sourceTile.id) {
745
+ await this.conversionDump.addNode(sourceTile.id, nodeInPage.index);
746
+ }
747
+
748
+ //write resources
749
+ await this._writeResources(resources, node.id, sourceTile);
760
750
  }
761
751
 
762
752
  if (this.validate) {
@@ -905,9 +895,15 @@ export default class I3SConverter {
905
895
  * @param resources.texture - texture image
906
896
  * @param resources.sharedResources - shared resource data object
907
897
  * @param resources.attributes - feature attributes
898
+ * @param nodePath - node path
899
+ * @param sourceTile - source tile (3DTile)
908
900
  * @return {Promise<void>}
909
901
  */
910
- private async _writeResources(resources: I3SConvertedResources, nodePath: string): Promise<void> {
902
+ private async _writeResources(
903
+ resources: I3SConvertedResources,
904
+ nodePath: string,
905
+ sourceTile: Tiles3DTileJSONPostprocessed
906
+ ): Promise<void> {
911
907
  const {
912
908
  geometry: geometryBuffer,
913
909
  compressedGeometry,
@@ -918,10 +914,36 @@ export default class I3SConverter {
918
914
  const childPath = join(this.layers0Path, 'nodes', nodePath);
919
915
  const slpkChildPath = join('nodes', nodePath);
920
916
 
921
- await this._writeGeometries(geometryBuffer!, compressedGeometry!, childPath, slpkChildPath);
922
- await this._writeShared(sharedResources, childPath, slpkChildPath, nodePath);
923
- await this._writeTexture(texture, childPath, slpkChildPath);
924
- await this._writeAttributes(attributes, childPath, slpkChildPath);
917
+ await this._writeGeometries(
918
+ geometryBuffer!,
919
+ compressedGeometry!,
920
+ childPath,
921
+ slpkChildPath,
922
+ sourceTile.id || '',
923
+ parseInt(nodePath)
924
+ );
925
+ await this._writeShared(
926
+ sharedResources,
927
+ childPath,
928
+ slpkChildPath,
929
+ nodePath,
930
+ sourceTile.id || '',
931
+ parseInt(nodePath)
932
+ );
933
+ await this._writeTexture(
934
+ texture,
935
+ childPath,
936
+ slpkChildPath,
937
+ sourceTile.id || '',
938
+ parseInt(nodePath)
939
+ );
940
+ await this._writeAttributes(
941
+ attributes,
942
+ childPath,
943
+ slpkChildPath,
944
+ sourceTile.id || '',
945
+ parseInt(nodePath)
946
+ );
925
947
  }
926
948
 
927
949
  /**
@@ -930,37 +952,57 @@ export default class I3SConverter {
930
952
  * @param compressedGeometry - Uint8Array with compressed (draco) geometry
931
953
  * @param childPath - a child path to write resources
932
954
  * @param slpkChildPath - resource path inside *slpk file
955
+ * @param sourceId - source filename
956
+ * @param nodeId - nodeId of a converted node for the writing
933
957
  */
934
958
  private async _writeGeometries(
935
959
  geometryBuffer: ArrayBuffer,
936
960
  compressedGeometry: Promise<ArrayBuffer>,
937
961
  childPath: string,
938
- slpkChildPath: string
962
+ slpkChildPath: string,
963
+ sourceId: string,
964
+ nodeId: number
939
965
  ): Promise<void> {
966
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.GEOMETRY, false);
967
+
940
968
  if (this.options.slpk) {
941
969
  const slpkGeometryPath = join(childPath, 'geometries');
942
970
  await this.writeQueue.enqueue({
943
971
  archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
972
+ sourceId,
973
+ outputId: nodeId,
974
+ resourceType: ResourceType.GEOMETRY,
944
975
  writePromise: () => writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
945
976
  });
946
977
  } else {
947
978
  const geometryPath = join(childPath, 'geometries/0/');
948
979
  await this.writeQueue.enqueue({
980
+ sourceId,
981
+ outputId: nodeId,
982
+ resourceType: ResourceType.GEOMETRY,
949
983
  writePromise: () => writeFile(geometryPath, geometryBuffer, 'index.bin')
950
984
  });
951
985
  }
952
986
 
953
987
  if (this.options.draco) {
988
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.DRACO_GEOMETRY, false);
989
+
954
990
  if (this.options.slpk) {
955
991
  const slpkCompressedGeometryPath = join(childPath, 'geometries');
956
992
  await this.writeQueue.enqueue({
957
993
  archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
994
+ sourceId,
995
+ outputId: nodeId,
996
+ resourceType: ResourceType.DRACO_GEOMETRY,
958
997
  writePromise: () =>
959
998
  writeFileForSlpk(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
960
999
  });
961
1000
  } else {
962
1001
  const compressedGeometryPath = join(childPath, 'geometries/1/');
963
1002
  await this.writeQueue.enqueue({
1003
+ sourceId,
1004
+ outputId: nodeId,
1005
+ resourceType: ResourceType.DRACO_GEOMETRY,
964
1006
  writePromise: () => writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
965
1007
  });
966
1008
  }
@@ -973,12 +1015,16 @@ export default class I3SConverter {
973
1015
  * @param childPath - a child path to write resources
974
1016
  * @param slpkChildPath - resource path inside *slpk file
975
1017
  * @param nodePath - a node path
1018
+ * @param sourceId - source filename
1019
+ * @param nodeId - nodeId of a converted node for the writing
976
1020
  */
977
1021
  private async _writeShared(
978
1022
  sharedResources: SharedResourcesArrays | null,
979
1023
  childPath: string,
980
1024
  slpkChildPath: string,
981
- nodePath: string
1025
+ nodePath: string,
1026
+ sourceId: string,
1027
+ nodeId: number
982
1028
  ): Promise<void> {
983
1029
  if (!sharedResources) {
984
1030
  return;
@@ -986,15 +1032,24 @@ export default class I3SConverter {
986
1032
  sharedResources.nodePath = nodePath;
987
1033
  const sharedData = transform(sharedResources, sharedResourcesTemplate());
988
1034
  const sharedDataStr = JSON.stringify(sharedData);
1035
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.SHARED, false);
989
1036
  if (this.options.slpk) {
990
1037
  const slpkSharedPath = join(childPath, 'shared');
991
1038
  await this.writeQueue.enqueue({
992
1039
  archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
1040
+ sourceId,
1041
+ outputId: nodeId,
1042
+ resourceType: ResourceType.SHARED,
993
1043
  writePromise: () => writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
994
1044
  });
995
1045
  } else {
996
1046
  const sharedPath = join(childPath, 'shared/');
997
- await this.writeQueue.enqueue({writePromise: () => writeFile(sharedPath, sharedDataStr)});
1047
+ await this.writeQueue.enqueue({
1048
+ sourceId,
1049
+ outputId: nodeId,
1050
+ resourceType: ResourceType.SHARED,
1051
+ writePromise: () => writeFile(sharedPath, sharedDataStr)
1052
+ });
998
1053
  }
999
1054
  }
1000
1055
 
@@ -1003,11 +1058,15 @@ export default class I3SConverter {
1003
1058
  * @param texture - the texture image
1004
1059
  * @param childPath - a child path to write resources
1005
1060
  * @param slpkChildPath - the resource path inside *slpk file
1061
+ * @param sourceId - source filename
1062
+ * @param nodeId - nodeId of a converted node for the writing
1006
1063
  */
1007
1064
  private async _writeTexture(
1008
1065
  texture: GLTFImagePostprocessed,
1009
1066
  childPath: string,
1010
- slpkChildPath: string
1067
+ slpkChildPath: string,
1068
+ sourceId: string,
1069
+ nodeId: number
1011
1070
  ): Promise<void> {
1012
1071
  if (texture) {
1013
1072
  const format = this._getFormatByMimeType(texture?.mimeType);
@@ -1018,7 +1077,21 @@ export default class I3SConverter {
1018
1077
  case 'jpg':
1019
1078
  case 'png': {
1020
1079
  formats.push({name: '0', format});
1021
- await this.writeTextureFile(textureData, '0', format, childPath, slpkChildPath);
1080
+ this.conversionDump.updateDoneStatus(
1081
+ sourceId,
1082
+ nodeId,
1083
+ `${ResourceType.TEXTURE}/${format}`,
1084
+ false
1085
+ );
1086
+ await this.writeTextureFile(
1087
+ textureData,
1088
+ '0',
1089
+ format,
1090
+ childPath,
1091
+ slpkChildPath,
1092
+ sourceId,
1093
+ nodeId
1094
+ );
1022
1095
 
1023
1096
  if (this.generateTextures) {
1024
1097
  formats.push({name: '1', format: 'ktx2'});
@@ -1041,7 +1114,22 @@ export default class I3SConverter {
1041
1114
  }
1042
1115
  );
1043
1116
 
1044
- await this.writeTextureFile(ktx2TextureData, '1', 'ktx2', childPath, slpkChildPath);
1117
+ this.conversionDump.updateDoneStatus(
1118
+ sourceId,
1119
+ nodeId,
1120
+ `${ResourceType.TEXTURE}/ktx2`,
1121
+ false
1122
+ );
1123
+
1124
+ await this.writeTextureFile(
1125
+ ktx2TextureData,
1126
+ '1',
1127
+ 'ktx2',
1128
+ childPath,
1129
+ slpkChildPath,
1130
+ sourceId,
1131
+ nodeId
1132
+ );
1045
1133
  }
1046
1134
 
1047
1135
  break;
@@ -1049,17 +1137,39 @@ export default class I3SConverter {
1049
1137
 
1050
1138
  case 'ktx2': {
1051
1139
  formats.push({name: '1', format});
1052
- await this.writeTextureFile(textureData, '1', format, childPath, slpkChildPath);
1140
+ this.conversionDump.updateDoneStatus(
1141
+ sourceId,
1142
+ nodeId,
1143
+ `${ResourceType.TEXTURE}/${format}`,
1144
+ false
1145
+ );
1146
+ await this.writeTextureFile(
1147
+ textureData,
1148
+ '1',
1149
+ format,
1150
+ childPath,
1151
+ slpkChildPath,
1152
+ sourceId,
1153
+ nodeId
1154
+ );
1053
1155
 
1054
1156
  if (this.generateTextures) {
1055
1157
  formats.push({name: '0', format: 'jpg'});
1056
1158
  const decodedFromKTX2TextureData = encode(texture.image!.data[0], ImageWriter);
1159
+ this.conversionDump.updateDoneStatus(
1160
+ sourceId,
1161
+ nodeId,
1162
+ `${ResourceType.TEXTURE}/jpg`,
1163
+ false
1164
+ );
1057
1165
  await this.writeTextureFile(
1058
1166
  decodedFromKTX2TextureData,
1059
1167
  '0',
1060
1168
  'jpg',
1061
1169
  childPath,
1062
- slpkChildPath
1170
+ slpkChildPath,
1171
+ sourceId,
1172
+ nodeId
1063
1173
  );
1064
1174
  }
1065
1175
  }
@@ -1079,13 +1189,17 @@ export default class I3SConverter {
1079
1189
  * @param format
1080
1190
  * @param childPath
1081
1191
  * @param slpkChildPath
1192
+ * @param sourceId
1193
+ * @param nodeId
1082
1194
  */
1083
1195
  private async writeTextureFile(
1084
1196
  textureData: Uint8Array | Promise<ArrayBuffer>,
1085
1197
  name: string,
1086
1198
  format: 'jpg' | 'png' | 'ktx2',
1087
1199
  childPath: string,
1088
- slpkChildPath: string
1200
+ slpkChildPath: string,
1201
+ sourceId: string,
1202
+ nodeId: number
1089
1203
  ): Promise<void> {
1090
1204
  if (this.options.slpk) {
1091
1205
  const slpkTexturePath = join(childPath, 'textures');
@@ -1093,12 +1207,18 @@ export default class I3SConverter {
1093
1207
 
1094
1208
  await this.writeQueue.enqueue({
1095
1209
  archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
1210
+ sourceId,
1211
+ outputId: nodeId,
1212
+ resourceType: `${ResourceType.TEXTURE}/${format}`,
1096
1213
  writePromise: () =>
1097
1214
  writeFileForSlpk(slpkTexturePath, textureData, `${name}.${format}`, compress)
1098
1215
  });
1099
1216
  } else {
1100
1217
  const texturePath = join(childPath, `textures/${name}/`);
1101
1218
  await this.writeQueue.enqueue({
1219
+ sourceId,
1220
+ outputId: nodeId,
1221
+ resourceType: `${ResourceType.TEXTURE}/${format}`,
1102
1222
  writePromise: () => writeFile(texturePath, textureData, `index.${format}`)
1103
1223
  });
1104
1224
  }
@@ -1109,11 +1229,15 @@ export default class I3SConverter {
1109
1229
  * @param attributes - feature attributes
1110
1230
  * @param childPath - a child path to write resources
1111
1231
  * @param slpkChildPath - the resource path inside *slpk file
1232
+ * @param sourceId - source filename
1233
+ * @param nodeId - nodeId of a converted node for the writing
1112
1234
  */
1113
1235
  private async _writeAttributes(
1114
1236
  attributes: ArrayBuffer[] | null = [],
1115
1237
  childPath: string,
1116
- slpkChildPath: string
1238
+ slpkChildPath: string,
1239
+ sourceId: string,
1240
+ nodeId: number
1117
1241
  ): Promise<void> {
1118
1242
  if (attributes?.length && this.attributeMetadataInfo.attributeStorageInfo.length) {
1119
1243
  const minimumLength =
@@ -1124,16 +1248,27 @@ export default class I3SConverter {
1124
1248
  for (let index = 0; index < minimumLength; index++) {
1125
1249
  const folderName = this.attributeMetadataInfo.attributeStorageInfo[index].key;
1126
1250
  const fileBuffer = new Uint8Array(attributes[index]);
1127
-
1251
+ this.conversionDump.updateDoneStatus(
1252
+ sourceId,
1253
+ nodeId,
1254
+ `${ResourceType.ATTRIBUTES}/${folderName}`,
1255
+ false
1256
+ );
1128
1257
  if (this.options.slpk) {
1129
1258
  const slpkAttributesPath = join(childPath, 'attributes', folderName);
1130
1259
  await this.writeQueue.enqueue({
1131
1260
  archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
1261
+ sourceId,
1262
+ outputId: nodeId,
1263
+ resourceType: `${ResourceType.ATTRIBUTES}/${folderName}`,
1132
1264
  writePromise: () => writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
1133
1265
  });
1134
1266
  } else {
1135
1267
  const attributesPath = join(childPath, `attributes/${folderName}/0`);
1136
1268
  await this.writeQueue.enqueue({
1269
+ sourceId,
1270
+ outputId: nodeId,
1271
+ resourceType: `${ResourceType.ATTRIBUTES}/${folderName}`,
1137
1272
  writePromise: () => writeFile(attributesPath, fileBuffer, 'index.bin')
1138
1273
  });
1139
1274
  }
@@ -241,3 +241,11 @@ export const AttributeType = {
241
241
  /** Integer data type name for feature attributes */
242
242
  SHORT_INT_TYPE: 'Int32'
243
243
  } as const;
244
+
245
+ export enum ResourceType {
246
+ ATTRIBUTES = 'ATTRIBUTES',
247
+ DRACO_GEOMETRY = 'DRACO_GEOMETRY',
248
+ GEOMETRY = 'GEOMETRY',
249
+ SHARED = 'SHARED',
250
+ TEXTURE = 'TEXTURE'
251
+ }