@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.
- package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
- package/dist/3d-tiles-converter/3d-tiles-converter.js +4 -4
- package/dist/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
- package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -1
- package/dist/3d-tiles-converter/helpers/b3dm-converter.js +8 -0
- package/dist/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
- package/dist/3d-tiles-converter/json-templates/tileset.d.ts.map +1 -1
- package/dist/3d-tiles-converter/json-templates/tileset.js +3 -0
- package/dist/3d-tiles-converter/json-templates/tileset.js.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -1
- package/dist/converter-cli.js +3 -3
- package/dist/converter-cli.js.map +1 -1
- package/dist/converter.min.cjs +131 -220
- package/dist/deps-installer/deps-installer.js +1 -1
- package/dist/i3s-converter/helpers/attribute-metadata-info.d.ts +10 -0
- package/dist/i3s-converter/helpers/attribute-metadata-info.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/attribute-metadata-info.js +5 -0
- package/dist/i3s-converter/helpers/attribute-metadata-info.js.map +1 -1
- package/dist/i3s-converter/helpers/node-index-document.d.ts +2 -1
- package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/node-index-document.js +6 -8
- package/dist/i3s-converter/helpers/node-index-document.js.map +1 -1
- package/dist/i3s-converter/helpers/progress.js +1 -1
- package/dist/i3s-converter/helpers/progress.js.map +1 -1
- package/dist/i3s-converter/i3s-converter.d.ts +32 -0
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.js +195 -47
- package/dist/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/i3s-converter/types.d.ts +7 -0
- package/dist/i3s-converter/types.d.ts.map +1 -1
- package/dist/i3s-converter/types.js +8 -0
- package/dist/i3s-converter/types.js.map +1 -1
- package/dist/i3s-server/bin/i3s-server.min.cjs +76 -76
- package/dist/index.cjs +638 -139
- package/dist/lib/utils/compress-util.d.ts +0 -37
- package/dist/lib/utils/compress-util.d.ts.map +1 -1
- package/dist/lib/utils/compress-util.js +1 -149
- package/dist/lib/utils/compress-util.js.map +1 -1
- package/dist/lib/utils/conversion-dump.d.ts +131 -0
- package/dist/lib/utils/conversion-dump.d.ts.map +1 -0
- package/dist/lib/utils/conversion-dump.js +191 -0
- package/dist/lib/utils/conversion-dump.js.map +1 -0
- package/dist/lib/utils/statistic-utills.js +1 -1
- package/dist/lib/utils/statistic-utills.js.map +1 -1
- package/dist/lib/utils/write-queue.d.ts +6 -1
- package/dist/lib/utils/write-queue.d.ts.map +1 -1
- package/dist/lib/utils/write-queue.js +15 -3
- package/dist/lib/utils/write-queue.js.map +1 -1
- package/dist/pgm-loader.js +1 -1
- package/dist/slpk-extractor.min.cjs +31 -31
- package/package.json +16 -16
- package/src/3d-tiles-converter/3d-tiles-converter.ts +5 -4
- package/src/3d-tiles-converter/helpers/b3dm-converter.ts +19 -0
- package/src/3d-tiles-converter/json-templates/tileset.ts +3 -0
- package/src/constants.ts +1 -0
- package/src/converter-cli.ts +3 -3
- package/src/i3s-converter/helpers/attribute-metadata-info.ts +16 -0
- package/src/i3s-converter/helpers/node-index-document.ts +18 -8
- package/src/i3s-converter/helpers/progress.ts +1 -1
- package/src/i3s-converter/i3s-converter.ts +385 -93
- package/src/i3s-converter/types.ts +8 -0
- package/src/lib/utils/compress-util.ts +1 -264
- package/src/lib/utils/conversion-dump.ts +325 -0
- package/src/lib/utils/statistic-utills.ts +1 -1
- 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
|
|
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 {
|
|
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(
|
|
295
|
+
await removeDir(removePath);
|
|
279
296
|
} catch (e) {}
|
|
280
|
-
this.
|
|
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
|
|
372
|
-
|
|
373
|
-
|
|
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
|
|
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
|
-
|
|
416
|
-
|
|
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
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|