@loaders.gl/tile-converter 4.1.0-alpha.9 → 4.2.0-alpha.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 (68) 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/i3s-converter/helpers/attribute-metadata-info.d.ts +10 -0
  19. package/dist/i3s-converter/helpers/attribute-metadata-info.d.ts.map +1 -1
  20. package/dist/i3s-converter/helpers/attribute-metadata-info.js +5 -0
  21. package/dist/i3s-converter/helpers/attribute-metadata-info.js.map +1 -1
  22. package/dist/i3s-converter/helpers/node-index-document.d.ts +2 -1
  23. package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -1
  24. package/dist/i3s-converter/helpers/node-index-document.js +6 -8
  25. package/dist/i3s-converter/helpers/node-index-document.js.map +1 -1
  26. package/dist/i3s-converter/helpers/progress.js +1 -1
  27. package/dist/i3s-converter/helpers/progress.js.map +1 -1
  28. package/dist/i3s-converter/i3s-converter.d.ts +32 -0
  29. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  30. package/dist/i3s-converter/i3s-converter.js +195 -47
  31. package/dist/i3s-converter/i3s-converter.js.map +1 -1
  32. package/dist/i3s-converter/types.d.ts +7 -0
  33. package/dist/i3s-converter/types.d.ts.map +1 -1
  34. package/dist/i3s-converter/types.js +8 -0
  35. package/dist/i3s-converter/types.js.map +1 -1
  36. package/dist/i3s-server/bin/i3s-server.min.cjs +76 -76
  37. package/dist/index.cjs +638 -139
  38. package/dist/lib/utils/compress-util.d.ts +0 -37
  39. package/dist/lib/utils/compress-util.d.ts.map +1 -1
  40. package/dist/lib/utils/compress-util.js +1 -149
  41. package/dist/lib/utils/compress-util.js.map +1 -1
  42. package/dist/lib/utils/conversion-dump.d.ts +131 -0
  43. package/dist/lib/utils/conversion-dump.d.ts.map +1 -0
  44. package/dist/lib/utils/conversion-dump.js +191 -0
  45. package/dist/lib/utils/conversion-dump.js.map +1 -0
  46. package/dist/lib/utils/statistic-utills.js +1 -1
  47. package/dist/lib/utils/statistic-utills.js.map +1 -1
  48. package/dist/lib/utils/write-queue.d.ts +6 -1
  49. package/dist/lib/utils/write-queue.d.ts.map +1 -1
  50. package/dist/lib/utils/write-queue.js +15 -3
  51. package/dist/lib/utils/write-queue.js.map +1 -1
  52. package/dist/pgm-loader.js +1 -1
  53. package/dist/slpk-extractor.min.cjs +31 -31
  54. package/package.json +16 -16
  55. package/src/3d-tiles-converter/3d-tiles-converter.ts +5 -4
  56. package/src/3d-tiles-converter/helpers/b3dm-converter.ts +19 -0
  57. package/src/3d-tiles-converter/json-templates/tileset.ts +3 -0
  58. package/src/constants.ts +1 -0
  59. package/src/converter-cli.ts +3 -3
  60. package/src/i3s-converter/helpers/attribute-metadata-info.ts +16 -0
  61. package/src/i3s-converter/helpers/node-index-document.ts +18 -8
  62. package/src/i3s-converter/helpers/progress.ts +1 -1
  63. package/src/i3s-converter/i3s-converter.ts +385 -93
  64. package/src/i3s-converter/types.ts +8 -0
  65. package/src/lib/utils/compress-util.ts +1 -264
  66. package/src/lib/utils/conversion-dump.ts +325 -0
  67. package/src/lib/utils/statistic-utills.ts +1 -1
  68. package/src/lib/utils/write-queue.ts +15 -2
@@ -9,7 +9,7 @@ import transform from 'json-map-transform';
9
9
  import md5 from 'md5';
10
10
  import NodePages from "./helpers/node-pages.js";
11
11
  import { writeFile, removeDir, writeFileForSlpk, removeFile } from "../lib/utils/file-utils.js";
12
- import { compressFileWithGzip, compressWithChildProcess } from "../lib/utils/compress-util.js";
12
+ import { compressFileWithGzip } from "../lib/utils/compress-util.js";
13
13
  import { calculateFilesSize, timeConverter } from "../lib/utils/statistic-utills.js";
14
14
  import convertB3dmToI3sGeometry, { getPropertyTable } from "./helpers/geometry-converter.js";
15
15
  import { createBoundingVolumes, convertBoundingVolumeToI3SFullExtent } from "./helpers/coordinate-converter.js";
@@ -21,9 +21,8 @@ import { GEOMETRY_DEFINITION as geometryDefinitionTemlate } from "./json-templat
21
21
  import { SHARED_RESOURCES as sharedResourcesTemplate } from "./json-templates/shared-resources.js";
22
22
  import { validateNodeBoundingVolumes } from "./helpers/node-debug.js";
23
23
  import { KTX2BasisWriterWorker } from '@loaders.gl/textures';
24
- import { FileHandleFile } from '@loaders.gl/loader-utils';
25
24
  import { ImageWriter } from '@loaders.gl/images';
26
- import { GLTFPrimitiveModeString } from "./types.js";
25
+ import { GLTFPrimitiveModeString, ResourceType } from "./types.js";
27
26
  import { WorkerFarm } from '@loaders.gl/worker-utils';
28
27
  import WriteQueue from "../lib/utils/write-queue.js";
29
28
  import { BROWSER_ERROR_MESSAGE } from "../constants.js";
@@ -35,7 +34,8 @@ import { createBoundingVolume } from '@loaders.gl/tiles';
35
34
  import { traverseDatasetWith } from "./helpers/tileset-traversal.js";
36
35
  import { analyzeTileContent, mergePreprocessData } from "./helpers/preprocess-3d-tiles.js";
37
36
  import { Progress } from "./helpers/progress.js";
38
- import { addOneFile, composeHashFile } from '@loaders.gl/zip';
37
+ import { composeHashFile, createZip } from '@loaders.gl/zip';
38
+ import { ConversionDump } from "../lib/utils/conversion-dump.js";
39
39
  const ION_DEFAULT_TOKEN = (_process$env = process.env) === null || _process$env === void 0 ? void 0 : _process$env.IonToken;
40
40
  const HARDCODED_NODES_PER_PAGE = 64;
41
41
  const _3D_TILES = '3DTILES';
@@ -82,13 +82,14 @@ export default class I3SConverter {
82
82
  this.generateBoundingVolumes = void 0;
83
83
  this.layersHasTexture = void 0;
84
84
  this.workerSource = {};
85
- this.writeQueue = new WriteQueue();
85
+ this.writeQueue = new WriteQueue(new ConversionDump());
86
86
  this.compressList = null;
87
87
  this.preprocessData = {
88
88
  meshTopologyTypes: new Set(),
89
89
  metadataClasses: new Set()
90
90
  };
91
91
  this.progresses = {};
92
+ this.conversionDump = void 0;
92
93
  this.attributeMetadataInfo = new AttributeMetadataInfo();
93
94
  this.nodePages = new NodePages(writeFile, HARDCODED_NODES_PER_PAGE, this);
94
95
  this.options = {};
@@ -109,6 +110,7 @@ export default class I3SConverter {
109
110
  this.generateBoundingVolumes = false;
110
111
  this.layersHasTexture = false;
111
112
  this.compressList = null;
113
+ this.conversionDump = new ConversionDump();
112
114
  }
113
115
  async convert(options) {
114
116
  if (isBrowser) {
@@ -136,6 +138,8 @@ export default class I3SConverter {
136
138
  analyze = false
137
139
  } = options;
138
140
  this.options = {
141
+ outputPath,
142
+ tilesetName,
139
143
  maxDepth,
140
144
  slpk,
141
145
  sevenZipExe,
@@ -154,7 +158,7 @@ export default class I3SConverter {
154
158
  this.Loader = inputUrl.indexOf(CESIUM_DATASET_PREFIX) !== -1 ? CesiumIonLoader : Tiles3DLoader;
155
159
  this.generateTextures = Boolean(generateTextures);
156
160
  this.generateBoundingVolumes = Boolean(generateBoundingVolumes);
157
- this.writeQueue = new WriteQueue();
161
+ this.writeQueue = new WriteQueue(this.conversionDump);
158
162
  this.writeQueue.startListening();
159
163
  console.log('Loading egm file...');
160
164
  this.geoidHeightModel = await load(egmFilePath, PGMLoader);
@@ -274,12 +278,34 @@ export default class I3SConverter {
274
278
  async _createAndSaveTileset(outputPath, tilesetName) {
275
279
  var _this$sourceTileset, _this$sourceTileset$r, _this$sourceTileset$r2;
276
280
  const tilesetPath = join(`${outputPath}`, `${tilesetName}`);
281
+ await this.conversionDump.createDump(this.options);
282
+ if (this.conversionDump.restored && this.options.inquirer) {
283
+ const result = await this.options.inquirer.prompt([{
284
+ name: 'resumeConversion',
285
+ type: 'confirm',
286
+ message: 'Dump file of the previous conversion exists, do you want to resume that conversion?'
287
+ }]);
288
+ if (!result.resumeConversion) {
289
+ this.conversionDump.reset();
290
+ }
291
+ }
292
+ this.layers0Path = join(tilesetPath, 'SceneServer', 'layers', '0');
293
+ const removePath = this.conversionDump.restored ? join(this.layers0Path, 'nodepages') : tilesetPath;
277
294
  try {
278
- await removeDir(tilesetPath);
295
+ await removeDir(removePath);
279
296
  } catch (e) {}
280
- this.layers0Path = join(tilesetPath, 'SceneServer', 'layers', '0');
297
+ if (this.conversionDump.restored && this.conversionDump.attributeMetadataInfo) {
298
+ this.attributeMetadataInfo.fromObject(this.conversionDump.attributeMetadataInfo);
299
+ }
281
300
  this.materialDefinitions = [];
282
301
  this.materialMap = new Map();
302
+ if (this.conversionDump.restored && this.conversionDump.materialDefinitions) {
303
+ for (let i = 0; i < this.conversionDump.materialDefinitions.length; i++) {
304
+ const hash = md5(JSON.stringify(this.conversionDump.materialDefinitions[i]));
305
+ this.materialMap.set(hash, i);
306
+ }
307
+ this.materialDefinitions = this.conversionDump.materialDefinitions;
308
+ }
283
309
  const sourceRootTile = this.sourceTileset.root;
284
310
  const sourceBoundingVolume = createBoundingVolume(sourceRootTile.boundingVolume, new Matrix4(sourceRootTile.transform), null);
285
311
  this._formLayers0(tilesetName, sourceBoundingVolume, (_this$sourceTileset = this.sourceTileset) === null || _this$sourceTileset === void 0 ? void 0 : (_this$sourceTileset$r = _this$sourceTileset.root) === null || _this$sourceTileset$r === void 0 ? void 0 : (_this$sourceTileset$r2 = _this$sourceTileset$r.boundingVolume) === null || _this$sourceTileset$r2 === void 0 ? void 0 : _this$sourceTileset$r2.region);
@@ -304,6 +330,9 @@ export default class I3SConverter {
304
330
  if (this.attributeMetadataInfo.attributeStorageInfo.length) {
305
331
  this.layers0.layerType = _3D_OBJECT_LAYER_TYPE;
306
332
  }
333
+ if (this.conversionDump.restored && this.conversionDump.textureSetDefinitions) {
334
+ this.layers0.textureSetDefinitions = this.conversionDump.textureSetDefinitions;
335
+ }
307
336
  this.layers0.materialDefinitions = this.materialDefinitions;
308
337
  this.layers0.geometryDefinitions = transform(this.geometryConfigs.map(config => ({
309
338
  geometryConfig: {
@@ -365,12 +394,14 @@ export default class I3SConverter {
365
394
  }
366
395
  }
367
396
  async _createSlpk(tilesetPath) {
397
+ await this.conversionDump.deleteDumpFile();
368
398
  if (this.options.slpk) {
369
399
  const slpkTilesetPath = join(tilesetPath, 'SceneServer', 'layers', '0');
370
400
  const slpkFileName = `${tilesetPath}.slpk`;
371
- await compressWithChildProcess(slpkTilesetPath, slpkFileName, 0, '.', this.options.sevenZipExe);
372
- const hashTable = await composeHashFile(new FileHandleFile(slpkFileName));
373
- await addOneFile(slpkFileName, hashTable, '@specialIndexFileHASH128@');
401
+ await createZip(slpkTilesetPath, slpkFileName, async fileList => ({
402
+ path: '@specialIndexFileHASH128@',
403
+ file: await composeHashFile(fileList)
404
+ }));
374
405
  try {
375
406
  await removeDir(tilesetPath);
376
407
  } catch (e) {}
@@ -399,7 +430,13 @@ export default class I3SConverter {
399
430
  transformationMatrix = transformationMatrix.multiplyRight(sourceTile.transform);
400
431
  }
401
432
  const parentNode = parentNodes[0];
402
- const childNodes = await this._createNode(parentNode, sourceTile, transformationMatrix);
433
+ const restoreResult = await this._restoreNode(parentNode, sourceTile, transformationMatrix);
434
+ let childNodes;
435
+ if (restoreResult === null) {
436
+ childNodes = await this._createNode(parentNode, sourceTile, transformationMatrix);
437
+ } else {
438
+ childNodes = restoreResult;
439
+ }
403
440
  await parentNode.addChildren(childNodes);
404
441
  const newTraversalProps = {
405
442
  transform: transformationMatrix,
@@ -412,8 +449,9 @@ export default class I3SConverter {
412
449
  if (timeRemainingStringBasedOnCount) {
413
450
  timeRemainingString = `${timeRemainingStringBasedOnCount} left`;
414
451
  }
415
- let percentString = this.progresses[PROGRESS_PHASE1_COUNT].getPercentString();
416
- console.log(`[converted ${percentString}%, ${timeRemainingString}]: ${sourceTile.id}`);
452
+ const percentString = this.progresses[PROGRESS_PHASE1_COUNT].getPercentString();
453
+ const progressString = percentString ? ` ${percentString}%, ${timeRemainingString}` : '';
454
+ console.log(`[converted${progressString}]: ${sourceTile.id}`);
417
455
  }
418
456
  return newTraversalProps;
419
457
  }
@@ -427,6 +465,57 @@ export default class I3SConverter {
427
465
  await node.save();
428
466
  }
429
467
  }
468
+ async _generateNodeIndexDocument(boundingVolumes, resources, parentNode, sourceTile, isDumped) {
469
+ this.layersHasTexture = this.layersHasTexture || Boolean('texture' in resources && resources.texture || 'texelCountHint' in resources && resources.texelCountHint);
470
+ if (this.generateBoundingVolumes && resources.boundingVolumes) {
471
+ boundingVolumes = resources.boundingVolumes;
472
+ }
473
+ const lodSelection = convertGeometricErrorToScreenThreshold(sourceTile, boundingVolumes);
474
+ const maxScreenThresholdSQ = lodSelection.find(val => val.metricType === 'maxScreenThresholdSQ') || {
475
+ maxError: 0
476
+ };
477
+ if (isDumped) {
478
+ const draftObb = {
479
+ center: [],
480
+ halfSize: [],
481
+ quaternion: []
482
+ };
483
+ await this.nodePages.push({
484
+ index: 0,
485
+ obb: draftObb
486
+ }, parentNode.inPageId);
487
+ }
488
+ const nodeInPage = await this._updateNodeInNodePages(maxScreenThresholdSQ, boundingVolumes, sourceTile, parentNode.inPageId, resources);
489
+ const nodeData = await NodeIndexDocument.createNodeIndexDocument(parentNode, boundingVolumes, lodSelection, nodeInPage, resources);
490
+ const node = await new NodeIndexDocument(nodeInPage.index, this).addData(nodeData);
491
+ return {
492
+ node,
493
+ nodeInPage,
494
+ nodeData
495
+ };
496
+ }
497
+ async _restoreNode(parentNode, sourceTile, transformationMatrix) {
498
+ this._checkAddRefinementTypeForTile(sourceTile);
499
+ await this._updateTilesetOptions();
500
+ if (this.conversionDump.restored && sourceTile.id && this.conversionDump.isFileConversionComplete(sourceTile.id)) {
501
+ const sourceBoundingVolume = createBoundingVolume(sourceTile.boundingVolume, transformationMatrix, null);
502
+ let boundingVolumes = createBoundingVolumes(sourceBoundingVolume, this.geoidHeightModel);
503
+ const nodes = [];
504
+ for (const convertedNode of this.conversionDump.tilesConverted[sourceTile.id].nodes) {
505
+ const {
506
+ node
507
+ } = await this._generateNodeIndexDocument(boundingVolumes, {
508
+ ...convertedNode.dumpMetadata,
509
+ nodeId: convertedNode.nodeId
510
+ }, parentNode, sourceTile, true);
511
+ nodes.push(node);
512
+ }
513
+ return nodes;
514
+ } else if (this.conversionDump.restored && sourceTile.id) {
515
+ this.conversionDump.clearDumpRecord(sourceTile.id);
516
+ }
517
+ return null;
518
+ }
430
519
  async _createNode(parentNode, sourceTile, transformationMatrix) {
431
520
  this._checkAddRefinementTypeForTile(sourceTile);
432
521
  await this._updateTilesetOptions();
@@ -440,6 +529,11 @@ export default class I3SConverter {
440
529
  let boundingVolumes = createBoundingVolumes(sourceBoundingVolume, this.geoidHeightModel);
441
530
  const propertyTable = getPropertyTable(tileContent, this.options.metadataClass);
442
531
  this.createAttributeStorageInfo(tileContent, propertyTable);
532
+ this.conversionDump.attributeMetadataInfo = {
533
+ attributeStorageInfo: this.attributeMetadataInfo.attributeStorageInfo,
534
+ fields: this.attributeMetadataInfo.fields,
535
+ popupInfo: this.attributeMetadataInfo.popupInfo
536
+ };
443
537
  const resourcesData = await this._convertResources(sourceTile, transformationMatrix, sourceBoundingVolume, tileContent, parentNode.inPageId, propertyTable);
444
538
  const nodes = [];
445
539
  const nodeIds = [];
@@ -457,20 +551,29 @@ export default class I3SConverter {
457
551
  boundingVolumes: null
458
552
  };
459
553
  for (const resources of resourcesData || [emptyResources]) {
460
- this.layersHasTexture = this.layersHasTexture || Boolean(resources.texture);
461
- if (this.generateBoundingVolumes && resources.boundingVolumes) {
462
- boundingVolumes = resources.boundingVolumes;
463
- }
464
- const lodSelection = convertGeometricErrorToScreenThreshold(sourceTile, boundingVolumes);
465
- const maxScreenThresholdSQ = lodSelection.find(val => val.metricType === 'maxScreenThresholdSQ') || {
466
- maxError: 0
467
- };
468
- const nodeInPage = await this._updateNodeInNodePages(maxScreenThresholdSQ, boundingVolumes, sourceTile, parentNode.inPageId, resources);
469
- const nodeData = await NodeIndexDocument.createNodeIndexDocument(parentNode, boundingVolumes, lodSelection, nodeInPage, resources);
470
- const node = await new NodeIndexDocument(nodeInPage.index, this).addData(nodeData);
554
+ const {
555
+ node,
556
+ nodeInPage,
557
+ nodeData
558
+ } = await this._generateNodeIndexDocument(boundingVolumes, resources, parentNode, sourceTile, false);
471
559
  nodes.push(node);
472
560
  if (nodeInPage.mesh) {
473
- await this._writeResources(resources, node.id);
561
+ if (sourceTile.id) {
562
+ var _resources$attributes;
563
+ const dumpMetadata = {
564
+ boundingVolumes: resources.boundingVolumes,
565
+ attributesCount: (_resources$attributes = resources.attributes) === null || _resources$attributes === void 0 ? void 0 : _resources$attributes.length,
566
+ featureCount: resources.featureCount,
567
+ geometry: Boolean(resources.geometry),
568
+ hasUvRegions: resources.hasUvRegions,
569
+ materialId: nodeInPage.mesh.material.definition,
570
+ texelCountHint: nodeInPage.mesh.material.texelCountHint,
571
+ vertexCount: resources.vertexCount
572
+ };
573
+ this.conversionDump.setMaterialsDefinitions(this.materialDefinitions);
574
+ await this.conversionDump.addNode(sourceTile.id, nodeInPage.index, dumpMetadata);
575
+ }
576
+ await this._writeResources(resources, node.id, sourceTile);
474
577
  }
475
578
  if (this.validate) {
476
579
  this.boundingVolumeWarnings = validateNodeBoundingVolumes(nodeData);
@@ -500,8 +603,6 @@ export default class I3SConverter {
500
603
  }
501
604
  async _updateNodeInNodePages(maxScreenThresholdSQ, boundingVolumes, sourceTile, parentId, resources) {
502
605
  const {
503
- meshMaterial,
504
- texture,
505
606
  vertexCount,
506
607
  featureCount,
507
608
  geometry,
@@ -516,7 +617,7 @@ export default class I3SConverter {
516
617
  if (geometry && this.isContentSupported(sourceTile)) {
517
618
  nodeInPage.mesh = {
518
619
  geometry: {
519
- definition: this.findOrCreateGeometryDefinition(Boolean(texture), hasUvRegions),
620
+ definition: this.findOrCreateGeometryDefinition(Boolean('texture' in resources && resources.texture || 'texelCountHint' in resources && resources.texelCountHint), hasUvRegions),
520
621
  resource: 0
521
622
  },
522
623
  attribute: {
@@ -527,7 +628,7 @@ export default class I3SConverter {
527
628
  }
528
629
  };
529
630
  }
530
- let nodeId = resources.nodeId;
631
+ let nodeId = 'nodeId' in resources ? resources.nodeId : undefined;
531
632
  let node;
532
633
  if (!nodeId) {
533
634
  node = await this.nodePages.push(nodeInPage, parentId);
@@ -538,12 +639,16 @@ export default class I3SConverter {
538
639
  console.log(`[warning]: node ${node.index} is created with empty content`);
539
640
  }
540
641
  NodePages.updateAll(node, nodeInPage);
541
- if (meshMaterial) {
542
- NodePages.updateMaterialByNodeId(node, this._findOrCreateMaterial(meshMaterial));
642
+ if ('meshMaterial' in resources && resources.meshMaterial) {
643
+ NodePages.updateMaterialByNodeId(node, this._findOrCreateMaterial(resources.meshMaterial));
644
+ } else if ('materialId' in resources && resources.materialId !== null) {
645
+ NodePages.updateMaterialByNodeId(node, resources.materialId);
543
646
  }
544
- if (texture) {
545
- const texelCountHint = texture.image.height * texture.image.width;
647
+ if ('texture' in resources && resources.texture) {
648
+ const texelCountHint = resources.texture.image.height * resources.texture.image.width;
546
649
  NodePages.updateTexelCountHintByNodeId(node, texelCountHint);
650
+ } else if ('texelCountHint' in resources && resources.texelCountHint) {
651
+ NodePages.updateTexelCountHintByNodeId(node, resources.texelCountHint);
547
652
  }
548
653
  if (vertexCount) {
549
654
  this.vertexCounter += vertexCount;
@@ -556,7 +661,7 @@ export default class I3SConverter {
556
661
  this.nodePages.saveNode(node);
557
662
  return node;
558
663
  }
559
- async _writeResources(resources, nodePath) {
664
+ async _writeResources(resources, nodePath, sourceTile) {
560
665
  const {
561
666
  geometry: geometryBuffer,
562
667
  compressedGeometry,
@@ -566,60 +671,81 @@ export default class I3SConverter {
566
671
  } = resources;
567
672
  const childPath = join(this.layers0Path, 'nodes', nodePath);
568
673
  const slpkChildPath = join('nodes', nodePath);
569
- await this._writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath);
570
- await this._writeShared(sharedResources, childPath, slpkChildPath, nodePath);
571
- await this._writeTexture(texture, childPath, slpkChildPath);
572
- await this._writeAttributes(attributes, childPath, slpkChildPath);
674
+ await this._writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath, sourceTile.id || '', parseInt(nodePath));
675
+ await this._writeShared(sharedResources, childPath, slpkChildPath, nodePath, sourceTile.id || '', parseInt(nodePath));
676
+ await this._writeTexture(texture, childPath, slpkChildPath, sourceTile.id || '', parseInt(nodePath));
677
+ await this._writeAttributes(attributes, childPath, slpkChildPath, sourceTile.id || '', parseInt(nodePath));
573
678
  }
574
- async _writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath) {
679
+ async _writeGeometries(geometryBuffer, compressedGeometry, childPath, slpkChildPath, sourceId, nodeId) {
680
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.GEOMETRY, false);
575
681
  if (this.options.slpk) {
576
682
  const slpkGeometryPath = join(childPath, 'geometries');
577
683
  await this.writeQueue.enqueue({
578
684
  archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
685
+ sourceId,
686
+ outputId: nodeId,
687
+ resourceType: ResourceType.GEOMETRY,
579
688
  writePromise: () => writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
580
689
  });
581
690
  } else {
582
691
  const geometryPath = join(childPath, 'geometries/0/');
583
692
  await this.writeQueue.enqueue({
693
+ sourceId,
694
+ outputId: nodeId,
695
+ resourceType: ResourceType.GEOMETRY,
584
696
  writePromise: () => writeFile(geometryPath, geometryBuffer, 'index.bin')
585
697
  });
586
698
  }
587
699
  if (this.options.draco) {
700
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.DRACO_GEOMETRY, false);
588
701
  if (this.options.slpk) {
589
702
  const slpkCompressedGeometryPath = join(childPath, 'geometries');
590
703
  await this.writeQueue.enqueue({
591
704
  archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
705
+ sourceId,
706
+ outputId: nodeId,
707
+ resourceType: ResourceType.DRACO_GEOMETRY,
592
708
  writePromise: () => writeFileForSlpk(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
593
709
  });
594
710
  } else {
595
711
  const compressedGeometryPath = join(childPath, 'geometries/1/');
596
712
  await this.writeQueue.enqueue({
713
+ sourceId,
714
+ outputId: nodeId,
715
+ resourceType: ResourceType.DRACO_GEOMETRY,
597
716
  writePromise: () => writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
598
717
  });
599
718
  }
600
719
  }
601
720
  }
602
- async _writeShared(sharedResources, childPath, slpkChildPath, nodePath) {
721
+ async _writeShared(sharedResources, childPath, slpkChildPath, nodePath, sourceId, nodeId) {
603
722
  if (!sharedResources) {
604
723
  return;
605
724
  }
606
725
  sharedResources.nodePath = nodePath;
607
726
  const sharedData = transform(sharedResources, sharedResourcesTemplate());
608
727
  const sharedDataStr = JSON.stringify(sharedData);
728
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, ResourceType.SHARED, false);
609
729
  if (this.options.slpk) {
610
730
  const slpkSharedPath = join(childPath, 'shared');
611
731
  await this.writeQueue.enqueue({
612
732
  archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
733
+ sourceId,
734
+ outputId: nodeId,
735
+ resourceType: ResourceType.SHARED,
613
736
  writePromise: () => writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
614
737
  });
615
738
  } else {
616
739
  const sharedPath = join(childPath, 'shared/');
617
740
  await this.writeQueue.enqueue({
741
+ sourceId,
742
+ outputId: nodeId,
743
+ resourceType: ResourceType.SHARED,
618
744
  writePromise: () => writeFile(sharedPath, sharedDataStr)
619
745
  });
620
746
  }
621
747
  }
622
- async _writeTexture(texture, childPath, slpkChildPath) {
748
+ async _writeTexture(texture, childPath, slpkChildPath, sourceId, nodeId) {
623
749
  if (texture) {
624
750
  const format = this._getFormatByMimeType(texture === null || texture === void 0 ? void 0 : texture.mimeType);
625
751
  const formats = [];
@@ -632,7 +758,8 @@ export default class I3SConverter {
632
758
  name: '0',
633
759
  format
634
760
  });
635
- await this.writeTextureFile(textureData, '0', format, childPath, slpkChildPath);
761
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, `${ResourceType.TEXTURE}/${format}`, false);
762
+ await this.writeTextureFile(textureData, '0', format, childPath, slpkChildPath, sourceId, nodeId);
636
763
  if (this.generateTextures) {
637
764
  formats.push({
638
765
  name: '1',
@@ -652,7 +779,8 @@ export default class I3SConverter {
652
779
  _nodeWorkers: true,
653
780
  useLocalLibraries: true
654
781
  });
655
- await this.writeTextureFile(ktx2TextureData, '1', 'ktx2', childPath, slpkChildPath);
782
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, `${ResourceType.TEXTURE}/ktx2`, false);
783
+ await this.writeTextureFile(ktx2TextureData, '1', 'ktx2', childPath, slpkChildPath, sourceId, nodeId);
656
784
  }
657
785
  break;
658
786
  }
@@ -662,14 +790,16 @@ export default class I3SConverter {
662
790
  name: '1',
663
791
  format
664
792
  });
665
- await this.writeTextureFile(textureData, '1', format, childPath, slpkChildPath);
793
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, `${ResourceType.TEXTURE}/${format}`, false);
794
+ await this.writeTextureFile(textureData, '1', format, childPath, slpkChildPath, sourceId, nodeId);
666
795
  if (this.generateTextures) {
667
796
  formats.push({
668
797
  name: '0',
669
798
  format: 'jpg'
670
799
  });
671
800
  const decodedFromKTX2TextureData = encode(texture.image.data[0], ImageWriter);
672
- await this.writeTextureFile(decodedFromKTX2TextureData, '0', 'jpg', childPath, slpkChildPath);
801
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, `${ResourceType.TEXTURE}/jpg`, false);
802
+ await this.writeTextureFile(decodedFromKTX2TextureData, '0', 'jpg', childPath, slpkChildPath, sourceId, nodeId);
673
803
  }
674
804
  }
675
805
  }
@@ -681,20 +811,29 @@ export default class I3SConverter {
681
811
  formats,
682
812
  atlas: true
683
813
  });
814
+ if (this.layers0.textureSetDefinitions) {
815
+ this.conversionDump.addTexturesDefinitions(this.layers0.textureSetDefinitions);
816
+ }
684
817
  }
685
818
  }
686
819
  }
687
- async writeTextureFile(textureData, name, format, childPath, slpkChildPath) {
820
+ async writeTextureFile(textureData, name, format, childPath, slpkChildPath, sourceId, nodeId) {
688
821
  if (this.options.slpk) {
689
822
  const slpkTexturePath = join(childPath, 'textures');
690
823
  const compress = false;
691
824
  await this.writeQueue.enqueue({
692
825
  archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
826
+ sourceId,
827
+ outputId: nodeId,
828
+ resourceType: `${ResourceType.TEXTURE}/${format}`,
693
829
  writePromise: () => writeFileForSlpk(slpkTexturePath, textureData, `${name}.${format}`, compress)
694
830
  });
695
831
  } else {
696
832
  const texturePath = join(childPath, `textures/${name}/`);
697
833
  await this.writeQueue.enqueue({
834
+ sourceId,
835
+ outputId: nodeId,
836
+ resourceType: `${ResourceType.TEXTURE}/${format}`,
698
837
  writePromise: () => writeFile(texturePath, textureData, `index.${format}`)
699
838
  });
700
839
  }
@@ -703,20 +842,29 @@ export default class I3SConverter {
703
842
  let attributes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
704
843
  let childPath = arguments.length > 1 ? arguments[1] : undefined;
705
844
  let slpkChildPath = arguments.length > 2 ? arguments[2] : undefined;
845
+ let sourceId = arguments.length > 3 ? arguments[3] : undefined;
846
+ let nodeId = arguments.length > 4 ? arguments[4] : undefined;
706
847
  if (attributes !== null && attributes !== void 0 && attributes.length && this.attributeMetadataInfo.attributeStorageInfo.length) {
707
848
  const minimumLength = attributes.length < this.attributeMetadataInfo.attributeStorageInfo.length ? attributes.length : this.attributeMetadataInfo.attributeStorageInfo.length;
708
849
  for (let index = 0; index < minimumLength; index++) {
709
850
  const folderName = this.attributeMetadataInfo.attributeStorageInfo[index].key;
710
851
  const fileBuffer = new Uint8Array(attributes[index]);
852
+ this.conversionDump.updateDoneStatus(sourceId, nodeId, `${ResourceType.ATTRIBUTES}/${folderName}`, false);
711
853
  if (this.options.slpk) {
712
854
  const slpkAttributesPath = join(childPath, 'attributes', folderName);
713
855
  await this.writeQueue.enqueue({
714
856
  archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
857
+ sourceId,
858
+ outputId: nodeId,
859
+ resourceType: `${ResourceType.ATTRIBUTES}/${folderName}`,
715
860
  writePromise: () => writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
716
861
  });
717
862
  } else {
718
863
  const attributesPath = join(childPath, `attributes/${folderName}/0`);
719
864
  await this.writeQueue.enqueue({
865
+ sourceId,
866
+ outputId: nodeId,
867
+ resourceType: `${ResourceType.ATTRIBUTES}/${folderName}`,
720
868
  writePromise: () => writeFile(attributesPath, fileBuffer, 'index.bin')
721
869
  });
722
870
  }