@loaders.gl/tile-converter 3.3.0-alpha.8 → 3.3.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-attributes-worker.js +2 -2
- package/dist/3d-tiles-attributes-worker.js.map +3 -3
- package/dist/converter-cli.js +14 -2
- package/dist/converter.min.js +22 -22
- package/dist/deps-installer/deps-installer.d.ts.map +1 -1
- package/dist/deps-installer/deps-installer.js +8 -0
- package/dist/dist.min.js +1167 -848
- package/dist/es5/3d-tiles-attributes-worker.js +1 -1
- package/dist/es5/3d-tiles-attributes-worker.js.map +1 -1
- package/dist/es5/converter-cli.js +14 -2
- package/dist/es5/converter-cli.js.map +1 -1
- package/dist/es5/deps-installer/deps-installer.js +13 -2
- package/dist/es5/deps-installer/deps-installer.js.map +1 -1
- package/dist/es5/i3s-attributes-worker.js +1 -1
- package/dist/es5/i3s-attributes-worker.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js +16 -7
- package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-converter.js +363 -113
- package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/gltf-attributes.js +6 -11
- package/dist/es5/i3s-converter/helpers/gltf-attributes.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/node-index-document.js +517 -0
- package/dist/es5/i3s-converter/helpers/node-index-document.js.map +1 -0
- package/dist/es5/i3s-converter/helpers/node-pages.js +455 -173
- package/dist/es5/i3s-converter/helpers/node-pages.js.map +1 -1
- package/dist/es5/i3s-converter/i3s-converter.js +549 -618
- package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/es5/i3s-converter/json-templates/geometry-definitions.js +107 -0
- package/dist/es5/i3s-converter/json-templates/geometry-definitions.js.map +1 -0
- package/dist/es5/i3s-converter/json-templates/layers.js +2 -93
- package/dist/es5/i3s-converter/json-templates/layers.js.map +1 -1
- package/dist/es5/i3s-converter/json-templates/shared-resources.js +3 -3
- package/dist/es5/i3s-converter/json-templates/shared-resources.js.map +1 -1
- package/dist/es5/i3s-converter/types.js.map +1 -1
- package/dist/es5/lib/utils/file-utils.js +93 -9
- package/dist/es5/lib/utils/file-utils.js.map +1 -1
- package/dist/es5/lib/utils/write-queue.js +38 -25
- package/dist/es5/lib/utils/write-queue.js.map +1 -1
- package/dist/es5/pgm-loader.js +1 -1
- package/dist/es5/pgm-loader.js.map +1 -1
- package/dist/es5/workers/i3s-attributes-worker.js +1 -1
- package/dist/es5/workers/i3s-attributes-worker.js.map +1 -1
- package/dist/esm/3d-tiles-attributes-worker.js +1 -1
- package/dist/esm/3d-tiles-attributes-worker.js.map +1 -1
- package/dist/esm/converter-cli.js +14 -2
- package/dist/esm/converter-cli.js.map +1 -1
- package/dist/esm/deps-installer/deps-installer.js +9 -1
- package/dist/esm/deps-installer/deps-installer.js.map +1 -1
- package/dist/esm/i3s-attributes-worker.js +1 -1
- package/dist/esm/i3s-attributes-worker.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js +16 -7
- package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-converter.js +150 -40
- package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/gltf-attributes.js +6 -9
- package/dist/esm/i3s-converter/helpers/gltf-attributes.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/node-index-document.js +202 -0
- package/dist/esm/i3s-converter/helpers/node-index-document.js.map +1 -0
- package/dist/esm/i3s-converter/helpers/node-pages.js +162 -76
- package/dist/esm/i3s-converter/helpers/node-pages.js.map +1 -1
- package/dist/esm/i3s-converter/i3s-converter.js +115 -220
- package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/esm/i3s-converter/json-templates/geometry-definitions.js +89 -0
- package/dist/esm/i3s-converter/json-templates/geometry-definitions.js.map +1 -0
- package/dist/esm/i3s-converter/json-templates/layers.js +2 -85
- package/dist/esm/i3s-converter/json-templates/layers.js.map +1 -1
- package/dist/esm/i3s-converter/json-templates/shared-resources.js +3 -3
- package/dist/esm/i3s-converter/json-templates/shared-resources.js.map +1 -1
- package/dist/esm/i3s-converter/types.js.map +1 -1
- package/dist/esm/lib/utils/file-utils.js +44 -3
- package/dist/esm/lib/utils/file-utils.js.map +1 -1
- package/dist/esm/lib/utils/write-queue.js +19 -10
- package/dist/esm/lib/utils/write-queue.js.map +1 -1
- package/dist/esm/pgm-loader.js +1 -1
- package/dist/esm/pgm-loader.js.map +1 -1
- package/dist/esm/workers/i3s-attributes-worker.js +1 -1
- package/dist/esm/workers/i3s-attributes-worker.js.map +1 -1
- package/dist/i3s-attributes-worker.js +2 -2
- package/dist/i3s-attributes-worker.js.map +2 -2
- package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +3 -3
- package/dist/i3s-converter/helpers/batch-ids-extensions.js +3 -3
- package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-attributes.js +16 -10
- package/dist/i3s-converter/helpers/geometry-converter.d.ts +8 -4
- package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.js +200 -44
- package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/gltf-attributes.js +2 -3
- package/dist/i3s-converter/helpers/node-index-document.d.ts +95 -0
- package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -0
- package/dist/i3s-converter/helpers/node-index-document.js +250 -0
- package/dist/i3s-converter/helpers/node-pages.d.ts +78 -43
- package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/node-pages.js +194 -93
- package/dist/i3s-converter/i3s-converter.d.ts +33 -58
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.js +122 -233
- package/dist/i3s-converter/json-templates/geometry-definitions.d.ts +7 -0
- package/dist/i3s-converter/json-templates/geometry-definitions.d.ts.map +1 -0
- package/dist/i3s-converter/json-templates/geometry-definitions.js +87 -0
- package/dist/i3s-converter/json-templates/layers.d.ts +1 -30
- package/dist/i3s-converter/json-templates/layers.d.ts.map +1 -1
- package/dist/i3s-converter/json-templates/layers.js +2 -86
- package/dist/i3s-converter/json-templates/shared-resources.js +3 -3
- package/dist/i3s-converter/types.d.ts +28 -2
- package/dist/i3s-converter/types.d.ts.map +1 -1
- package/dist/lib/utils/file-utils.d.ts +17 -1
- package/dist/lib/utils/file-utils.d.ts.map +1 -1
- package/dist/lib/utils/file-utils.js +64 -7
- package/dist/lib/utils/write-queue.d.ts +18 -2
- package/dist/lib/utils/write-queue.d.ts.map +1 -1
- package/dist/lib/utils/write-queue.js +18 -12
- package/dist/workers/i3s-attributes-worker.js +1 -1
- package/package.json +25 -20
- package/src/converter-cli.ts +22 -2
- package/src/deps-installer/deps-installer.ts +9 -0
- package/src/i3s-converter/helpers/batch-ids-extensions.ts +3 -3
- package/src/i3s-converter/helpers/geometry-attributes.ts +16 -11
- package/src/i3s-converter/helpers/geometry-converter.ts +217 -48
- package/src/i3s-converter/helpers/gltf-attributes.ts +2 -3
- package/src/i3s-converter/helpers/node-index-document.ts +315 -0
- package/src/i3s-converter/helpers/node-pages.ts +215 -110
- package/src/i3s-converter/i3s-converter.ts +170 -312
- package/src/i3s-converter/json-templates/geometry-definitions.ts +83 -0
- package/src/i3s-converter/json-templates/layers.ts +2 -91
- package/src/i3s-converter/json-templates/shared-resources.ts +3 -3
- package/src/i3s-converter/types.ts +29 -2
- package/src/lib/utils/file-utils.ts +62 -7
- package/src/lib/utils/write-queue.ts +36 -15
- package/src/workers/i3s-attributes-worker.ts +2 -1
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
// loaders.gl, MIT license
|
|
2
|
+
|
|
3
|
+
import type {Tileset3DProps} from '@loaders.gl/tiles';
|
|
2
4
|
import type {FeatureTableJson} from '@loaders.gl/3d-tiles';
|
|
3
5
|
import type {WriteQueueItem} from '../lib/utils/write-queue';
|
|
4
6
|
import type {
|
|
5
7
|
SceneLayer3D,
|
|
6
8
|
BoundingVolumes,
|
|
7
|
-
Node3DIndexDocument,
|
|
8
|
-
NodeReference,
|
|
9
9
|
MaxScreenThresholdSQ,
|
|
10
|
-
NodeInPage
|
|
11
|
-
LodSelection
|
|
10
|
+
NodeInPage
|
|
12
11
|
} from '@loaders.gl/i3s';
|
|
13
12
|
import {load, encode, fetchFile, getLoaderOptions, isBrowser} from '@loaders.gl/core';
|
|
14
13
|
import {Tileset3D} from '@loaders.gl/tiles';
|
|
@@ -21,8 +20,9 @@ import transform from 'json-map-transform';
|
|
|
21
20
|
import md5 from 'md5';
|
|
22
21
|
|
|
23
22
|
import NodePages from './helpers/node-pages';
|
|
24
|
-
import {writeFile, removeDir, writeFileForSlpk} from '../lib/utils/file-utils';
|
|
23
|
+
import {writeFile, removeDir, writeFileForSlpk, removeFile} from '../lib/utils/file-utils';
|
|
25
24
|
import {
|
|
25
|
+
compressFileWithGzip,
|
|
26
26
|
compressWithChildProcess
|
|
27
27
|
// generateHash128FromZip,
|
|
28
28
|
// addFileToZip
|
|
@@ -38,10 +38,12 @@ import {convertGeometricErrorToScreenThreshold} from '../lib/utils/lod-conversio
|
|
|
38
38
|
import {PGMLoader} from '../pgm-loader';
|
|
39
39
|
|
|
40
40
|
import {LAYERS as layersTemplate} from './json-templates/layers';
|
|
41
|
-
import {
|
|
41
|
+
import {GEOMETRY_DEFINITION as geometryDefinitionTemlate} from './json-templates/geometry-definitions';
|
|
42
42
|
import {SHARED_RESOURCES as sharedResourcesTemplate} from './json-templates/shared-resources';
|
|
43
43
|
import {validateNodeBoundingVolumes} from './helpers/node-debug';
|
|
44
|
-
|
|
44
|
+
// loaders.gl, MIT license
|
|
45
|
+
|
|
46
|
+
import {Tile3D} from '@loaders.gl/tiles';
|
|
45
47
|
import {KTX2BasisWriterWorker} from '@loaders.gl/textures';
|
|
46
48
|
import {LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
47
49
|
import {I3SMaterialDefinition, TextureSetDefinitionFormats} from '@loaders.gl/i3s/src/types';
|
|
@@ -60,6 +62,7 @@ import {
|
|
|
60
62
|
getAttributeType,
|
|
61
63
|
getFieldAttributeType
|
|
62
64
|
} from './helpers/feature-attributes';
|
|
65
|
+
import {NodeIndexDocument} from './helpers/node-index-document';
|
|
63
66
|
|
|
64
67
|
const ION_DEFAULT_TOKEN =
|
|
65
68
|
process.env?.IonToken || // eslint-disable-line
|
|
@@ -78,8 +81,10 @@ export default class I3SConverter {
|
|
|
78
81
|
nodePages: NodePages;
|
|
79
82
|
options: any;
|
|
80
83
|
layers0Path: string;
|
|
81
|
-
materialMap: Map<
|
|
84
|
+
materialMap: Map<string, number>;
|
|
82
85
|
materialDefinitions: I3SMaterialDefinition[];
|
|
86
|
+
geometryMap: Map<string, number>;
|
|
87
|
+
geometryConfigs: {hasTexture: boolean; hasUvRegions: boolean}[];
|
|
83
88
|
vertexCounter: number;
|
|
84
89
|
layers0: SceneLayer3D | null;
|
|
85
90
|
featuresHashArray: string[];
|
|
@@ -99,13 +104,16 @@ export default class I3SConverter {
|
|
|
99
104
|
layersHasTexture: boolean;
|
|
100
105
|
workerSource: {[key: string]: string} = {};
|
|
101
106
|
writeQueue: WriteQueue<WriteQueueItem> = new WriteQueue();
|
|
107
|
+
compressList: string[] | null = null;
|
|
102
108
|
|
|
103
109
|
constructor() {
|
|
104
|
-
this.nodePages = new NodePages(writeFile, HARDCODED_NODES_PER_PAGE);
|
|
110
|
+
this.nodePages = new NodePages(writeFile, HARDCODED_NODES_PER_PAGE, this);
|
|
105
111
|
this.options = {};
|
|
106
112
|
this.layers0Path = '';
|
|
107
113
|
this.materialMap = new Map();
|
|
108
114
|
this.materialDefinitions = [];
|
|
115
|
+
this.geometryMap = new Map();
|
|
116
|
+
this.geometryConfigs = [];
|
|
109
117
|
this.vertexCounter = 0;
|
|
110
118
|
this.layers0 = null;
|
|
111
119
|
this.featuresHashArray = [];
|
|
@@ -117,6 +125,7 @@ export default class I3SConverter {
|
|
|
117
125
|
this.generateTextures = false;
|
|
118
126
|
this.generateBoundingVolumes = false;
|
|
119
127
|
this.layersHasTexture = false;
|
|
128
|
+
this.compressList = null;
|
|
120
129
|
}
|
|
121
130
|
|
|
122
131
|
/**
|
|
@@ -132,6 +141,9 @@ export default class I3SConverter {
|
|
|
132
141
|
* @param options.token Token for Cesium ION tilesets authentication
|
|
133
142
|
* @param options.draco Generate I3S 1.7 draco compressed geometries
|
|
134
143
|
* @param options.validate -enable validation
|
|
144
|
+
* @param options.generateTextures - generate alternative type of textures (to have non-compressed jpeg/png and compressed ktx2)
|
|
145
|
+
* @param options.generateBoundingVolumes - generate bounding volumes from vertices coordinates instead of source tiles bounding volumes
|
|
146
|
+
* @param options.instantNodeWriting - Keep created 3DNodeIndexDocument files on disk instead of memory. This option reduce memory usage but decelerates conversion speed
|
|
135
147
|
*/
|
|
136
148
|
async convert(options: {
|
|
137
149
|
inputUrl: string;
|
|
@@ -143,9 +155,11 @@ export default class I3SConverter {
|
|
|
143
155
|
slpk?: boolean;
|
|
144
156
|
token?: string;
|
|
145
157
|
draco?: boolean;
|
|
158
|
+
mergeMaterials?: boolean;
|
|
146
159
|
validate?: boolean;
|
|
147
160
|
generateTextures?: boolean;
|
|
148
161
|
generateBoundingVolumes?: boolean;
|
|
162
|
+
instantNodeWriting?: boolean;
|
|
149
163
|
}): Promise<any> {
|
|
150
164
|
if (isBrowser) {
|
|
151
165
|
console.log(BROWSER_ERROR_MESSAGE);
|
|
@@ -159,14 +173,27 @@ export default class I3SConverter {
|
|
|
159
173
|
inputUrl,
|
|
160
174
|
validate,
|
|
161
175
|
outputPath,
|
|
162
|
-
draco,
|
|
176
|
+
draco = true,
|
|
163
177
|
sevenZipExe,
|
|
164
178
|
maxDepth,
|
|
165
179
|
token,
|
|
166
180
|
generateTextures,
|
|
167
|
-
generateBoundingVolumes
|
|
181
|
+
generateBoundingVolumes,
|
|
182
|
+
instantNodeWriting = false,
|
|
183
|
+
mergeMaterials = true
|
|
168
184
|
} = options;
|
|
169
|
-
this.options = {
|
|
185
|
+
this.options = {
|
|
186
|
+
maxDepth,
|
|
187
|
+
slpk,
|
|
188
|
+
sevenZipExe,
|
|
189
|
+
egmFilePath,
|
|
190
|
+
draco,
|
|
191
|
+
token,
|
|
192
|
+
inputUrl,
|
|
193
|
+
instantNodeWriting,
|
|
194
|
+
mergeMaterials
|
|
195
|
+
};
|
|
196
|
+
this.compressList = (this.options.instantNodeWriting && []) || null;
|
|
170
197
|
this.validate = Boolean(validate);
|
|
171
198
|
this.Loader = inputUrl.indexOf(CESIUM_DATASET_PREFIX) !== -1 ? CesiumIonLoader : Tiles3DLoader;
|
|
172
199
|
this.generateTextures = Boolean(generateTextures);
|
|
@@ -248,21 +275,26 @@ export default class I3SConverter {
|
|
|
248
275
|
this.materialDefinitions = [];
|
|
249
276
|
this.materialMap = new Map();
|
|
250
277
|
|
|
251
|
-
const sourceRootTile:
|
|
278
|
+
const sourceRootTile: Tile3D = this.sourceTileset!.root!;
|
|
252
279
|
const boundingVolumes = createBoundingVolumes(sourceRootTile, this.geoidHeightModel!);
|
|
253
|
-
|
|
280
|
+
await this.nodePages.push({
|
|
254
281
|
index: 0,
|
|
255
282
|
lodThreshold: 0,
|
|
256
283
|
obb: boundingVolumes.obb,
|
|
257
284
|
children: []
|
|
258
285
|
});
|
|
259
286
|
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
await this._convertNodesTree(root0, sourceRootTile, parentId, boundingVolumes);
|
|
287
|
+
const rootNode = await NodeIndexDocument.createRootNode(boundingVolumes, this);
|
|
288
|
+
await this._convertNodesTree(rootNode, sourceRootTile);
|
|
264
289
|
|
|
265
290
|
this.layers0!.materialDefinitions = this.materialDefinitions;
|
|
291
|
+
// @ts-ignore
|
|
292
|
+
this.layers0.geometryDefinitions = transform(
|
|
293
|
+
this.geometryConfigs.map((config) => ({
|
|
294
|
+
geometryConfig: {...config, draco: this.options.draco}
|
|
295
|
+
})),
|
|
296
|
+
geometryDefinitionTemlate()
|
|
297
|
+
);
|
|
266
298
|
|
|
267
299
|
if (this.layersHasTexture === false) {
|
|
268
300
|
this.layers0!.store.defaultGeometrySchema.ordering =
|
|
@@ -273,8 +305,11 @@ export default class I3SConverter {
|
|
|
273
305
|
|
|
274
306
|
await this._writeLayers0();
|
|
275
307
|
createSceneServerPath(tilesetName, this.layers0!, tilesetPath);
|
|
276
|
-
|
|
277
|
-
|
|
308
|
+
for (const filePath of this.compressList || []) {
|
|
309
|
+
await compressFileWithGzip(filePath);
|
|
310
|
+
await removeFile(filePath);
|
|
311
|
+
}
|
|
312
|
+
await this.nodePages.save();
|
|
278
313
|
await this.writeQueue.finalize();
|
|
279
314
|
await this._createSlpk(tilesetPath);
|
|
280
315
|
}
|
|
@@ -310,77 +345,31 @@ export default class I3SConverter {
|
|
|
310
345
|
this.layers0 = transform(layers0data, layersTemplate());
|
|
311
346
|
}
|
|
312
347
|
|
|
313
|
-
/**
|
|
314
|
-
* Convert and save the layer and embedded tiles
|
|
315
|
-
* @param boundingVolumes - mbs and obb data about node's bounding volume
|
|
316
|
-
* @return 3DNodeIndexDocument data https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md
|
|
317
|
-
*/
|
|
318
|
-
private _formRootNodeIndexDocument(boundingVolumes: BoundingVolumes): Node3DIndexDocument {
|
|
319
|
-
const root0data = {
|
|
320
|
-
version: `{${uuidv4().toUpperCase()}}`,
|
|
321
|
-
id: 'root',
|
|
322
|
-
level: 0,
|
|
323
|
-
lodSelection: [
|
|
324
|
-
{
|
|
325
|
-
metricType: 'maxScreenThresholdSQ',
|
|
326
|
-
maxError: 0
|
|
327
|
-
},
|
|
328
|
-
{
|
|
329
|
-
metricType: 'maxScreenThreshold',
|
|
330
|
-
maxError: 0
|
|
331
|
-
}
|
|
332
|
-
],
|
|
333
|
-
...boundingVolumes,
|
|
334
|
-
children: []
|
|
335
|
-
};
|
|
336
|
-
return transform(root0data, nodeTemplate());
|
|
337
|
-
}
|
|
338
|
-
|
|
339
348
|
/**
|
|
340
349
|
* Form object of 3DSceneLayer https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DSceneLayer.cmn.md
|
|
341
|
-
* @param
|
|
350
|
+
* @param rootNode - 3DNodeIndexDocument of root node https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md
|
|
342
351
|
* @param sourceRootTile - Source (3DTile) tile data
|
|
343
|
-
* @param parentId - node id in node pages
|
|
344
|
-
* @param boundingVolumes - mbs and obb data about node's bounding volume
|
|
345
352
|
*/
|
|
346
353
|
private async _convertNodesTree(
|
|
347
|
-
|
|
348
|
-
sourceRootTile:
|
|
349
|
-
parentId: number,
|
|
350
|
-
boundingVolumes: BoundingVolumes
|
|
354
|
+
rootNode: NodeIndexDocument,
|
|
355
|
+
sourceRootTile: Tile3D
|
|
351
356
|
): Promise<void> {
|
|
352
357
|
await this.sourceTileset!._loadTile(sourceRootTile);
|
|
353
358
|
if (this.isContentSupported(sourceRootTile)) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
href: './1',
|
|
358
|
-
...boundingVolumes
|
|
359
|
-
});
|
|
360
|
-
const [child] = await this._createNode(root0, sourceRootTile, parentId, 0);
|
|
361
|
-
const childPath = join(this.layers0Path, 'nodes', child.path!);
|
|
362
|
-
|
|
363
|
-
if (this.options.slpk) {
|
|
364
|
-
await this.writeQueue.enqueue({
|
|
365
|
-
archiveKey: 'nodes/1/3dNodeIndexDocument.json.gz',
|
|
366
|
-
writePromise: writeFileForSlpk(
|
|
367
|
-
childPath,
|
|
368
|
-
JSON.stringify(child),
|
|
369
|
-
'3dNodeIndexDocument.json'
|
|
370
|
-
)
|
|
371
|
-
});
|
|
372
|
-
} else {
|
|
373
|
-
await this.writeQueue.enqueue({writePromise: writeFile(childPath, JSON.stringify(child))});
|
|
359
|
+
const childNodes = await this._createNode(rootNode, sourceRootTile, 0);
|
|
360
|
+
for (const childNode of childNodes) {
|
|
361
|
+
await childNode.save();
|
|
374
362
|
}
|
|
363
|
+
await rootNode.addChildren(childNodes);
|
|
375
364
|
} else {
|
|
376
365
|
await this._addChildrenWithNeighborsAndWriteFile({
|
|
377
|
-
parentNode:
|
|
366
|
+
parentNode: rootNode,
|
|
378
367
|
sourceTiles: sourceRootTile.children,
|
|
379
|
-
parentId,
|
|
380
368
|
level: 1
|
|
381
369
|
});
|
|
382
370
|
}
|
|
383
371
|
await sourceRootTile.unloadContent();
|
|
372
|
+
await rootNode.save();
|
|
384
373
|
}
|
|
385
374
|
|
|
386
375
|
/**
|
|
@@ -390,34 +379,13 @@ export default class I3SConverter {
|
|
|
390
379
|
if (this.options.slpk) {
|
|
391
380
|
await this.writeQueue.enqueue({
|
|
392
381
|
archiveKey: '3dSceneLayer.json.gz',
|
|
393
|
-
writePromise:
|
|
394
|
-
this.layers0Path,
|
|
395
|
-
JSON.stringify(this.layers0),
|
|
396
|
-
'3dSceneLayer.json'
|
|
397
|
-
)
|
|
382
|
+
writePromise: () =>
|
|
383
|
+
writeFileForSlpk(this.layers0Path, JSON.stringify(this.layers0), '3dSceneLayer.json')
|
|
398
384
|
});
|
|
399
385
|
} else {
|
|
400
386
|
await this.writeQueue.enqueue({
|
|
401
|
-
writePromise: writeFile(this.layers0Path, JSON.stringify(this.layers0))
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Write 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md in file
|
|
408
|
-
*/
|
|
409
|
-
private async _writeNodeIndexDocument(
|
|
410
|
-
root0: Node3DIndexDocument,
|
|
411
|
-
nodePath: string,
|
|
412
|
-
rootPath: string
|
|
413
|
-
): Promise<void> {
|
|
414
|
-
if (this.options.slpk) {
|
|
415
|
-
await this.writeQueue.enqueue({
|
|
416
|
-
archiveKey: `nodes/${nodePath}/3dNodeIndexDocument.json.gz`,
|
|
417
|
-
writePromise: writeFileForSlpk(rootPath, JSON.stringify(root0), '3dNodeIndexDocument.json')
|
|
387
|
+
writePromise: () => writeFile(this.layers0Path, JSON.stringify(this.layers0))
|
|
418
388
|
});
|
|
419
|
-
} else {
|
|
420
|
-
await this.writeQueue.enqueue({writePromise: writeFile(rootPath, JSON.stringify(root0))});
|
|
421
389
|
}
|
|
422
390
|
}
|
|
423
391
|
|
|
@@ -466,50 +434,39 @@ export default class I3SConverter {
|
|
|
466
434
|
/**
|
|
467
435
|
* Add child nodes recursively and write them to files
|
|
468
436
|
* @param data - arguments
|
|
437
|
+
* @param data.parentNode - 3DNodeIndexDocument of parent node
|
|
469
438
|
* @param data.sourceTiles - array of source child nodes
|
|
470
|
-
* @param data.parentNode - 3DNodeIndexDocument of parent node for processing child nodes
|
|
471
|
-
* @param data.parentId - id of parent node in node pages
|
|
472
439
|
* @param data.level - level of node (distanse to root node in the tree)
|
|
473
440
|
*/
|
|
474
441
|
private async _addChildrenWithNeighborsAndWriteFile(data: {
|
|
475
|
-
parentNode:
|
|
476
|
-
sourceTiles:
|
|
477
|
-
parentId: number;
|
|
442
|
+
parentNode: NodeIndexDocument;
|
|
443
|
+
sourceTiles: Tile3D[];
|
|
478
444
|
level: number;
|
|
479
445
|
}): Promise<void> {
|
|
480
|
-
|
|
481
|
-
await
|
|
482
|
-
await this._addNeighborsAndWriteFile(data.parentNode, childNodes);
|
|
446
|
+
await this._addChildren(data);
|
|
447
|
+
await data.parentNode.addNeighbors();
|
|
483
448
|
}
|
|
484
449
|
|
|
485
450
|
/**
|
|
486
451
|
* Convert nested subtree of 3DTiles dataset
|
|
487
452
|
* @param param0
|
|
453
|
+
* @param data.parentNode - 3DNodeIndexDocument of parent node
|
|
488
454
|
* @param param0.sourceTile - source 3DTile data
|
|
489
|
-
* @param param0.parentNode - parent I3S node
|
|
490
|
-
* @param param0.childNodes - child I3S nodes
|
|
491
|
-
* @param param0.parentId - parent node ID
|
|
492
455
|
* @param param0.level - tree level
|
|
493
456
|
*/
|
|
494
457
|
private async convertNestedTileset({
|
|
495
|
-
sourceTile,
|
|
496
458
|
parentNode,
|
|
497
|
-
|
|
498
|
-
parentId,
|
|
459
|
+
sourceTile,
|
|
499
460
|
level
|
|
500
461
|
}: {
|
|
501
|
-
|
|
502
|
-
sourceTile:
|
|
503
|
-
parentNode: Node3DIndexDocument;
|
|
504
|
-
parentId: number;
|
|
462
|
+
parentNode: NodeIndexDocument;
|
|
463
|
+
sourceTile: Tile3D;
|
|
505
464
|
level: number;
|
|
506
465
|
}) {
|
|
507
466
|
await this.sourceTileset!._loadTile(sourceTile);
|
|
508
467
|
await this._addChildren({
|
|
509
468
|
parentNode,
|
|
510
469
|
sourceTiles: sourceTile.children,
|
|
511
|
-
childNodes,
|
|
512
|
-
parentId,
|
|
513
470
|
level: level + 1
|
|
514
471
|
});
|
|
515
472
|
await sourceTile.unloadContent();
|
|
@@ -518,127 +475,62 @@ export default class I3SConverter {
|
|
|
518
475
|
/**
|
|
519
476
|
* Convert 3DTiles tile to I3S node
|
|
520
477
|
* @param param0
|
|
478
|
+
* @param param0.parentNode - 3DNodeIndexDocument of parent node
|
|
521
479
|
* @param param0.sourceTile - source 3DTile data
|
|
522
|
-
* @param param0.parentNode - parent I3S node
|
|
523
|
-
* @param param0.childNodes - child I3S nodes
|
|
524
|
-
* @param param0.parentId - parent node ID
|
|
525
480
|
* @param param0.level - tree level
|
|
526
481
|
*/
|
|
527
482
|
private async convertNode({
|
|
528
|
-
sourceTile,
|
|
529
483
|
parentNode,
|
|
530
|
-
|
|
531
|
-
parentId,
|
|
484
|
+
sourceTile,
|
|
532
485
|
level
|
|
533
486
|
}: {
|
|
534
|
-
|
|
535
|
-
sourceTile:
|
|
536
|
-
parentNode: Node3DIndexDocument;
|
|
537
|
-
parentId: number;
|
|
487
|
+
parentNode: NodeIndexDocument;
|
|
488
|
+
sourceTile: Tile3D;
|
|
538
489
|
level: number;
|
|
539
490
|
}) {
|
|
540
|
-
const
|
|
541
|
-
|
|
542
|
-
for (const child of children) {
|
|
543
|
-
parentNode.children.push({
|
|
544
|
-
id: child.id,
|
|
545
|
-
href: `../${child.path}`,
|
|
546
|
-
obb: child.obb,
|
|
547
|
-
mbs: child.mbs
|
|
548
|
-
});
|
|
549
|
-
childNodes.push(child);
|
|
550
|
-
}
|
|
491
|
+
const childNodes = await this._createNode(parentNode, sourceTile, level);
|
|
492
|
+
await parentNode.addChildren(childNodes);
|
|
551
493
|
}
|
|
552
494
|
|
|
553
495
|
/**
|
|
554
496
|
* Add child nodes recursively and write them to files
|
|
555
|
-
* @param
|
|
556
|
-
* @param
|
|
557
|
-
* @param
|
|
558
|
-
* @param
|
|
559
|
-
* @param data.parentId - id of parent node in node pages
|
|
560
|
-
* @param data.level - level of node (distanse to root node in the tree)
|
|
497
|
+
* @param param0 - arguments
|
|
498
|
+
* @param param0.parentNode - 3DNodeIndexDocument of parent node
|
|
499
|
+
* @param param0.sourceTile - source 3DTile data
|
|
500
|
+
* @param param0.level - tree level
|
|
561
501
|
*/
|
|
562
502
|
private async _addChildren(data: {
|
|
563
|
-
|
|
564
|
-
sourceTiles:
|
|
565
|
-
parentNode: Node3DIndexDocument;
|
|
566
|
-
parentId: number;
|
|
503
|
+
parentNode: NodeIndexDocument;
|
|
504
|
+
sourceTiles: Tile3D[];
|
|
567
505
|
level: number;
|
|
568
506
|
}): Promise<void> {
|
|
569
|
-
const {
|
|
507
|
+
const {sourceTiles, parentNode, level} = data;
|
|
570
508
|
if (this.options.maxDepth && level > this.options.maxDepth) {
|
|
571
509
|
return;
|
|
572
510
|
}
|
|
573
|
-
|
|
574
|
-
const promises: Promise<void>[] = [];
|
|
575
|
-
|
|
576
511
|
for (const sourceTile of sourceTiles) {
|
|
577
512
|
if (sourceTile.type === 'json') {
|
|
578
|
-
|
|
579
|
-
this.convertNestedTileset({sourceTile, parentNode, childNodes, parentId, level})
|
|
580
|
-
);
|
|
513
|
+
await this.convertNestedTileset({parentNode, sourceTile, level});
|
|
581
514
|
} else {
|
|
582
|
-
|
|
515
|
+
await this.convertNode({parentNode, sourceTile, level});
|
|
583
516
|
}
|
|
584
|
-
await Promise.all(promises);
|
|
585
517
|
if (sourceTile.id) {
|
|
586
518
|
console.log(sourceTile.id); // eslint-disable-line
|
|
587
519
|
}
|
|
588
520
|
}
|
|
589
521
|
}
|
|
590
522
|
|
|
591
|
-
/**
|
|
592
|
-
* Add neightbors to 3DNodeIndexDocument and write it in a file
|
|
593
|
-
* @param parentNode - arguments
|
|
594
|
-
* @param childNodes - array of target child nodes
|
|
595
|
-
*/
|
|
596
|
-
private async _addNeighborsAndWriteFile(
|
|
597
|
-
parentNode: Node3DIndexDocument,
|
|
598
|
-
childNodes: Node3DIndexDocument[]
|
|
599
|
-
): Promise<void> {
|
|
600
|
-
for (const node of childNodes) {
|
|
601
|
-
const childPath = join(this.layers0Path, 'nodes', node.path!);
|
|
602
|
-
const nodePath = node.path;
|
|
603
|
-
delete node.path;
|
|
604
|
-
|
|
605
|
-
// Don't do large amount of "neightbors" to avoid big memory consumption
|
|
606
|
-
if (Number(parentNode?.children?.length) < 1000) {
|
|
607
|
-
for (const neighbor of parentNode.children || []) {
|
|
608
|
-
// eslint-disable-next-line max-depth
|
|
609
|
-
if (node.id === neighbor.id) {
|
|
610
|
-
continue; // eslint-disable-line
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
if (node.neighbors) {
|
|
614
|
-
node.neighbors.push({...neighbor});
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
} else {
|
|
618
|
-
// eslint-disable-next-line no-console, no-undef
|
|
619
|
-
console.warn(
|
|
620
|
-
`Node ${node.id}: neighbors attribute is omited because of large number of neigbors`
|
|
621
|
-
);
|
|
622
|
-
delete node.neighbors;
|
|
623
|
-
}
|
|
624
|
-
await this._writeNodeIndexDocument(node, nodePath!, childPath);
|
|
625
|
-
node.neighbors = [];
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
|
|
629
523
|
/**
|
|
630
524
|
* Convert tile to one or more I3S nodes
|
|
631
|
-
* @param
|
|
632
|
-
* @param sourceTile - source
|
|
633
|
-
* @param
|
|
634
|
-
* @param level - level of node (distanse to root node in the tree)
|
|
525
|
+
* @param parentNode - 3DNodeIndexDocument of parent node
|
|
526
|
+
* @param sourceTile - source 3DTile data
|
|
527
|
+
* @param level - tree level
|
|
635
528
|
*/
|
|
636
529
|
private async _createNode(
|
|
637
|
-
|
|
638
|
-
sourceTile:
|
|
639
|
-
parentId: number,
|
|
530
|
+
parentNode: NodeIndexDocument,
|
|
531
|
+
sourceTile: Tile3D,
|
|
640
532
|
level: number
|
|
641
|
-
): Promise<
|
|
533
|
+
): Promise<NodeIndexDocument[]> {
|
|
642
534
|
this._checkAddRefinementTypeForTile(sourceTile);
|
|
643
535
|
|
|
644
536
|
await this._updateTilesetOptions();
|
|
@@ -652,14 +544,20 @@ export default class I3SConverter {
|
|
|
652
544
|
this._convertPropertyTableToNodeAttributes(propertyTable);
|
|
653
545
|
}
|
|
654
546
|
|
|
655
|
-
const resourcesData = await this._convertResources(
|
|
547
|
+
const resourcesData = await this._convertResources(
|
|
548
|
+
sourceTile,
|
|
549
|
+
parentNode.inPageId,
|
|
550
|
+
propertyTable
|
|
551
|
+
);
|
|
656
552
|
|
|
657
|
-
const nodes:
|
|
553
|
+
const nodes: NodeIndexDocument[] = [];
|
|
554
|
+
const nodeIds: number[] = [];
|
|
658
555
|
const nodesInPage: NodeInPage[] = [];
|
|
659
556
|
const emptyResources = {
|
|
660
557
|
geometry: null,
|
|
661
558
|
compressedGeometry: null,
|
|
662
559
|
texture: null,
|
|
560
|
+
hasUvRegions: false,
|
|
663
561
|
sharedResources: null,
|
|
664
562
|
meshMaterial: null,
|
|
665
563
|
vertexCount: null,
|
|
@@ -680,34 +578,37 @@ export default class I3SConverter {
|
|
|
680
578
|
(val) => val.metricType === 'maxScreenThresholdSQ'
|
|
681
579
|
) || {maxError: 0};
|
|
682
580
|
|
|
683
|
-
const nodeInPage = this._updateNodeInNodePages(
|
|
581
|
+
const nodeInPage = await this._updateNodeInNodePages(
|
|
684
582
|
maxScreenThresholdSQ,
|
|
685
583
|
boundingVolumes,
|
|
686
584
|
sourceTile,
|
|
687
|
-
|
|
585
|
+
parentNode.inPageId,
|
|
688
586
|
resources
|
|
689
587
|
);
|
|
690
|
-
|
|
691
|
-
|
|
588
|
+
|
|
589
|
+
const nodeData = await NodeIndexDocument.createNodeIndexDocument(
|
|
590
|
+
parentNode,
|
|
692
591
|
boundingVolumes,
|
|
693
592
|
lodSelection,
|
|
694
593
|
nodeInPage,
|
|
695
594
|
resources
|
|
696
595
|
);
|
|
596
|
+
const node = await new NodeIndexDocument(nodeInPage.index, this).addData(nodeData);
|
|
597
|
+
nodes.push(node);
|
|
697
598
|
|
|
698
599
|
if (nodeInPage.mesh) {
|
|
699
|
-
await this._writeResources(resources, node.
|
|
600
|
+
await this._writeResources(resources, node.id);
|
|
700
601
|
}
|
|
701
602
|
|
|
702
603
|
if (this.validate) {
|
|
703
|
-
this.boundingVolumeWarnings = validateNodeBoundingVolumes(
|
|
604
|
+
this.boundingVolumeWarnings = validateNodeBoundingVolumes(nodeData);
|
|
704
605
|
|
|
705
606
|
if (this.boundingVolumeWarnings && this.boundingVolumeWarnings.length) {
|
|
706
607
|
console.warn('Bounding Volume Warnings: ', ...this.boundingVolumeWarnings); //eslint-disable-line
|
|
707
608
|
}
|
|
708
609
|
}
|
|
709
610
|
|
|
710
|
-
|
|
611
|
+
nodeIds.push(nodeInPage.index);
|
|
711
612
|
nodesInPage.push(nodeInPage);
|
|
712
613
|
}
|
|
713
614
|
|
|
@@ -716,7 +617,6 @@ export default class I3SConverter {
|
|
|
716
617
|
await this._addChildrenWithNeighborsAndWriteFile({
|
|
717
618
|
parentNode: nodes[0],
|
|
718
619
|
sourceTiles: sourceTile.children,
|
|
719
|
-
parentId: nodesInPage[0].index!,
|
|
720
620
|
level: level + 1
|
|
721
621
|
});
|
|
722
622
|
return nodes;
|
|
@@ -727,17 +627,10 @@ export default class I3SConverter {
|
|
|
727
627
|
* @param sourceTile - source tile (3DTile)
|
|
728
628
|
* @param parentId - id of parent node in node pages
|
|
729
629
|
* @param propertyTable - batch table from b3dm / feature properties from EXT_FEATURE_METADATA
|
|
730
|
-
*
|
|
731
|
-
* result.compressedGeometry - ArrayBuffer with compressed (draco) geometry
|
|
732
|
-
* result.texture - texture image
|
|
733
|
-
* result.sharedResources - shared resource data object
|
|
734
|
-
* result.meshMaterial - PBR-like material object
|
|
735
|
-
* result.vertexCount - number of vertices in geometry
|
|
736
|
-
* result.attributes - feature attributes
|
|
737
|
-
* result.featureCount - number of features
|
|
630
|
+
* @returns - converted node resources
|
|
738
631
|
*/
|
|
739
632
|
private async _convertResources(
|
|
740
|
-
sourceTile:
|
|
633
|
+
sourceTile: Tile3D,
|
|
741
634
|
parentId: number,
|
|
742
635
|
propertyTable: FeatureTableJson | null
|
|
743
636
|
): Promise<I3SConvertedResources[] | null> {
|
|
@@ -751,12 +644,13 @@ export default class I3SConverter {
|
|
|
751
644
|
};
|
|
752
645
|
const resourcesData = await convertB3dmToI3sGeometry(
|
|
753
646
|
sourceTile.content,
|
|
754
|
-
() => this.nodePages.push({index: 0, obb: draftObb}, parentId),
|
|
647
|
+
async () => (await this.nodePages.push({index: 0, obb: draftObb}, parentId)).index,
|
|
755
648
|
propertyTable,
|
|
756
649
|
this.featuresHashArray,
|
|
757
650
|
this.layers0?.attributeStorageInfo,
|
|
758
651
|
this.options.draco,
|
|
759
652
|
this.generateBoundingVolumes,
|
|
653
|
+
this.options.mergeMaterials,
|
|
760
654
|
this.geoidHeightModel!,
|
|
761
655
|
this.workerSource
|
|
762
656
|
);
|
|
@@ -775,16 +669,17 @@ export default class I3SConverter {
|
|
|
775
669
|
* @param resources.texture - texture image
|
|
776
670
|
* @param resources.vertexCount - number of vertices in geometry
|
|
777
671
|
* @param resources.featureCount - number of features
|
|
672
|
+
* @param resources.geometry - Uint8Array with geometry attributes
|
|
778
673
|
* @return the node object in node pages
|
|
779
674
|
*/
|
|
780
|
-
private _updateNodeInNodePages(
|
|
675
|
+
private async _updateNodeInNodePages(
|
|
781
676
|
maxScreenThresholdSQ: MaxScreenThresholdSQ,
|
|
782
677
|
boundingVolumes: BoundingVolumes,
|
|
783
|
-
sourceTile:
|
|
678
|
+
sourceTile: Tile3D,
|
|
784
679
|
parentId: number,
|
|
785
680
|
resources: I3SConvertedResources
|
|
786
|
-
): NodeInPage {
|
|
787
|
-
const {meshMaterial, texture, vertexCount, featureCount, geometry} = resources;
|
|
681
|
+
): Promise<NodeInPage> {
|
|
682
|
+
const {meshMaterial, texture, vertexCount, featureCount, geometry, hasUvRegions} = resources;
|
|
788
683
|
const nodeInPage: NodeInPage = {
|
|
789
684
|
index: 0,
|
|
790
685
|
lodThreshold: maxScreenThresholdSQ.maxError,
|
|
@@ -794,7 +689,7 @@ export default class I3SConverter {
|
|
|
794
689
|
if (geometry && this.isContentSupported(sourceTile)) {
|
|
795
690
|
nodeInPage.mesh = {
|
|
796
691
|
geometry: {
|
|
797
|
-
definition: texture
|
|
692
|
+
definition: this.findOrCreateGeometryDefinition(Boolean(texture), hasUvRegions),
|
|
798
693
|
resource: 0
|
|
799
694
|
},
|
|
800
695
|
attribute: {
|
|
@@ -807,89 +702,31 @@ export default class I3SConverter {
|
|
|
807
702
|
}
|
|
808
703
|
|
|
809
704
|
let nodeId = resources.nodeId;
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
this.nodePages.updateResourceInMesh(node);
|
|
705
|
+
let node;
|
|
706
|
+
if (!nodeId) {
|
|
707
|
+
node = await this.nodePages.push(nodeInPage, parentId);
|
|
814
708
|
} else {
|
|
815
|
-
|
|
709
|
+
node = await this.nodePages.getNodeById(nodeId);
|
|
816
710
|
}
|
|
817
711
|
|
|
712
|
+
NodePages.updateAll(node, nodeInPage);
|
|
818
713
|
if (meshMaterial) {
|
|
819
|
-
|
|
714
|
+
NodePages.updateMaterialByNodeId(node, this._findOrCreateMaterial(meshMaterial));
|
|
820
715
|
}
|
|
821
|
-
|
|
822
716
|
if (texture) {
|
|
823
717
|
const texelCountHint = texture.image.height * texture.image.width;
|
|
824
|
-
|
|
718
|
+
NodePages.updateTexelCountHintByNodeId(node, texelCountHint);
|
|
825
719
|
}
|
|
826
|
-
|
|
827
720
|
if (vertexCount) {
|
|
828
721
|
this.vertexCounter += vertexCount;
|
|
829
|
-
|
|
722
|
+
NodePages.updateVertexCountByNodeId(node, vertexCount);
|
|
830
723
|
}
|
|
831
|
-
|
|
724
|
+
NodePages.updateNodeAttributeByNodeId(node);
|
|
832
725
|
if (featureCount) {
|
|
833
|
-
|
|
726
|
+
NodePages.updateFeatureCountByNodeId(node, featureCount);
|
|
834
727
|
}
|
|
835
728
|
|
|
836
|
-
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
/**
|
|
840
|
-
* Create a new node page object in node pages
|
|
841
|
-
* @param parentNode - 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md object of the parent node
|
|
842
|
-
* @param boundingVolumes - Bounding volumes
|
|
843
|
-
* @param lodSelection - Level of Details (LOD) metrics
|
|
844
|
-
* @param nodeInPage - corresponding node object in a node page
|
|
845
|
-
* @param resources - the node resources data
|
|
846
|
-
* @param resources.texture - texture image
|
|
847
|
-
* @param resources.attributes - feature attributes
|
|
848
|
-
* @return 3DNodeIndexDocument https://github.com/Esri/i3s-spec/blob/master/docs/1.7/3DNodeIndexDocument.cmn.md object
|
|
849
|
-
*/
|
|
850
|
-
private _createNodeIndexDocument(
|
|
851
|
-
parentNode: Node3DIndexDocument,
|
|
852
|
-
boundingVolumes: BoundingVolumes,
|
|
853
|
-
lodSelection: LodSelection[],
|
|
854
|
-
nodeInPage: NodeInPage,
|
|
855
|
-
resources: I3SConvertedResources
|
|
856
|
-
): Node3DIndexDocument {
|
|
857
|
-
const {texture, attributes} = resources;
|
|
858
|
-
const nodeId = nodeInPage.index!;
|
|
859
|
-
const nodeData = {
|
|
860
|
-
version: parentNode.version,
|
|
861
|
-
id: nodeId.toString(),
|
|
862
|
-
path: nodeId.toString(),
|
|
863
|
-
level: parentNode.level! + 1,
|
|
864
|
-
...boundingVolumes,
|
|
865
|
-
lodSelection,
|
|
866
|
-
parentNode: {
|
|
867
|
-
id: parentNode.id,
|
|
868
|
-
href: `../${parentNode.id}`,
|
|
869
|
-
mbs: parentNode.mbs,
|
|
870
|
-
obb: parentNode.obb
|
|
871
|
-
},
|
|
872
|
-
children: [],
|
|
873
|
-
neighbors: []
|
|
874
|
-
};
|
|
875
|
-
const node = transform(nodeData, nodeTemplate());
|
|
876
|
-
|
|
877
|
-
if (nodeInPage.mesh) {
|
|
878
|
-
node.geometryData = [{href: './geometries/0'}];
|
|
879
|
-
node.sharedResource = {href: './shared'};
|
|
880
|
-
|
|
881
|
-
if (texture) {
|
|
882
|
-
node.textureData = [{href: './textures/0'}, {href: './textures/1'}];
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
if (attributes && attributes.length && this.layers0?.attributeStorageInfo?.length) {
|
|
886
|
-
node.attributeData = [];
|
|
887
|
-
for (let index = 0; index < attributes.length; index++) {
|
|
888
|
-
const folderName = this.layers0.attributeStorageInfo[index].key;
|
|
889
|
-
node.attributeData.push({href: `./attributes/${folderName}/0`});
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
}
|
|
729
|
+
this.nodePages.saveNode(node);
|
|
893
730
|
|
|
894
731
|
return node;
|
|
895
732
|
}
|
|
@@ -938,12 +775,12 @@ export default class I3SConverter {
|
|
|
938
775
|
const slpkGeometryPath = join(childPath, 'geometries');
|
|
939
776
|
await this.writeQueue.enqueue({
|
|
940
777
|
archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
|
|
941
|
-
writePromise: writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
|
|
778
|
+
writePromise: () => writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
|
|
942
779
|
});
|
|
943
780
|
} else {
|
|
944
781
|
const geometryPath = join(childPath, 'geometries/0/');
|
|
945
782
|
await this.writeQueue.enqueue({
|
|
946
|
-
writePromise: writeFile(geometryPath, geometryBuffer, 'index.bin')
|
|
783
|
+
writePromise: () => writeFile(geometryPath, geometryBuffer, 'index.bin')
|
|
947
784
|
});
|
|
948
785
|
}
|
|
949
786
|
|
|
@@ -952,12 +789,13 @@ export default class I3SConverter {
|
|
|
952
789
|
const slpkCompressedGeometryPath = join(childPath, 'geometries');
|
|
953
790
|
await this.writeQueue.enqueue({
|
|
954
791
|
archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
|
|
955
|
-
writePromise:
|
|
792
|
+
writePromise: () =>
|
|
793
|
+
writeFileForSlpk(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
|
|
956
794
|
});
|
|
957
795
|
} else {
|
|
958
796
|
const compressedGeometryPath = join(childPath, 'geometries/1/');
|
|
959
797
|
await this.writeQueue.enqueue({
|
|
960
|
-
writePromise: writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
|
|
798
|
+
writePromise: () => writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
|
|
961
799
|
});
|
|
962
800
|
}
|
|
963
801
|
}
|
|
@@ -986,11 +824,11 @@ export default class I3SConverter {
|
|
|
986
824
|
const slpkSharedPath = join(childPath, 'shared');
|
|
987
825
|
await this.writeQueue.enqueue({
|
|
988
826
|
archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
|
|
989
|
-
writePromise: writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
|
|
827
|
+
writePromise: () => writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
|
|
990
828
|
});
|
|
991
829
|
} else {
|
|
992
830
|
const sharedPath = join(childPath, 'shared/');
|
|
993
|
-
await this.writeQueue.enqueue({writePromise: writeFile(sharedPath, sharedDataStr)});
|
|
831
|
+
await this.writeQueue.enqueue({writePromise: () => writeFile(sharedPath, sharedDataStr)});
|
|
994
832
|
}
|
|
995
833
|
}
|
|
996
834
|
|
|
@@ -1058,6 +896,7 @@ export default class I3SConverter {
|
|
|
1058
896
|
|
|
1059
897
|
if (!this.layers0!.textureSetDefinitions!.length) {
|
|
1060
898
|
this.layers0!.textureSetDefinitions!.push({formats});
|
|
899
|
+
this.layers0!.textureSetDefinitions!.push({formats, atlas: true});
|
|
1061
900
|
}
|
|
1062
901
|
}
|
|
1063
902
|
}
|
|
@@ -1083,12 +922,13 @@ export default class I3SConverter {
|
|
|
1083
922
|
|
|
1084
923
|
await this.writeQueue.enqueue({
|
|
1085
924
|
archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
|
|
1086
|
-
writePromise:
|
|
925
|
+
writePromise: () =>
|
|
926
|
+
writeFileForSlpk(slpkTexturePath, textureData, `${name}.${format}`, compress)
|
|
1087
927
|
});
|
|
1088
928
|
} else {
|
|
1089
929
|
const texturePath = join(childPath, `textures/${name}/`);
|
|
1090
930
|
await this.writeQueue.enqueue({
|
|
1091
|
-
writePromise: writeFile(texturePath, textureData, `index.${format}`)
|
|
931
|
+
writePromise: () => writeFile(texturePath, textureData, `index.${format}`)
|
|
1092
932
|
});
|
|
1093
933
|
}
|
|
1094
934
|
}
|
|
@@ -1113,12 +953,12 @@ export default class I3SConverter {
|
|
|
1113
953
|
const slpkAttributesPath = join(childPath, 'attributes', folderName);
|
|
1114
954
|
await this.writeQueue.enqueue({
|
|
1115
955
|
archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
|
|
1116
|
-
writePromise: writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
|
|
956
|
+
writePromise: () => writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
|
|
1117
957
|
});
|
|
1118
958
|
} else {
|
|
1119
959
|
const attributesPath = join(childPath, `attributes/${folderName}/0`);
|
|
1120
960
|
await this.writeQueue.enqueue({
|
|
1121
|
-
writePromise: writeFile(attributesPath, fileBuffer, 'index.bin')
|
|
961
|
+
writePromise: () => writeFile(attributesPath, fileBuffer, 'index.bin')
|
|
1122
962
|
});
|
|
1123
963
|
}
|
|
1124
964
|
}
|
|
@@ -1150,13 +990,31 @@ export default class I3SConverter {
|
|
|
1150
990
|
private _findOrCreateMaterial(material: I3SMaterialDefinition): number {
|
|
1151
991
|
const hash = md5(JSON.stringify(material));
|
|
1152
992
|
if (this.materialMap.has(hash)) {
|
|
1153
|
-
return this.materialMap.get(hash);
|
|
993
|
+
return this.materialMap.get(hash) || 0;
|
|
1154
994
|
}
|
|
1155
995
|
const newMaterialId = this.materialDefinitions.push(material) - 1;
|
|
1156
996
|
this.materialMap.set(hash, newMaterialId);
|
|
1157
997
|
return newMaterialId;
|
|
1158
998
|
}
|
|
1159
999
|
|
|
1000
|
+
/**
|
|
1001
|
+
* Get unique geometry configuration index
|
|
1002
|
+
* In the end of conversion configurations will be transformed to geometryDefinitions array
|
|
1003
|
+
* @param hasTexture
|
|
1004
|
+
* @param hasUvRegions
|
|
1005
|
+
* @returns
|
|
1006
|
+
*/
|
|
1007
|
+
private findOrCreateGeometryDefinition(hasTexture: boolean, hasUvRegions: boolean): number {
|
|
1008
|
+
const geometryConfig = {hasTexture, hasUvRegions};
|
|
1009
|
+
const hash = md5(JSON.stringify(geometryConfig));
|
|
1010
|
+
if (this.geometryMap.has(hash)) {
|
|
1011
|
+
return this.geometryMap.get(hash) || 0;
|
|
1012
|
+
}
|
|
1013
|
+
const newGeometryId = this.geometryConfigs.push(geometryConfig) - 1;
|
|
1014
|
+
this.geometryMap.set(hash, newGeometryId);
|
|
1015
|
+
return newGeometryId;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1160
1018
|
/**
|
|
1161
1019
|
* Do conversion of 3DTiles property table to I3s node attributes.
|
|
1162
1020
|
* @param propertyTable - Table with layer meta data.
|
|
@@ -1250,7 +1108,7 @@ export default class I3SConverter {
|
|
|
1250
1108
|
/** Do calculations of all tiles and tiles with "ADD" type of refinement.
|
|
1251
1109
|
* @param tile
|
|
1252
1110
|
*/
|
|
1253
|
-
private _checkAddRefinementTypeForTile(tile:
|
|
1111
|
+
private _checkAddRefinementTypeForTile(tile: Tile3D): void {
|
|
1254
1112
|
const ADD_TILE_REFINEMENT = 1;
|
|
1255
1113
|
|
|
1256
1114
|
if (tile.refine === ADD_TILE_REFINEMENT) {
|