@loaders.gl/tile-converter 4.0.0-alpha.17 → 4.0.0-alpha.19
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 +5 -4
- package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
- package/dist/3d-tiles-converter/3d-tiles-converter.js +39 -37
- package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts +3 -1
- package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -1
- package/dist/3d-tiles-converter/helpers/b3dm-converter.js +4 -2
- package/dist/3d-tiles-converter/helpers/load-i3s.d.ts +10 -0
- package/dist/3d-tiles-converter/helpers/load-i3s.d.ts.map +1 -0
- package/dist/3d-tiles-converter/helpers/load-i3s.js +42 -0
- package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts +2 -1
- package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts.map +1 -1
- package/dist/3d-tiles-converter/helpers/texture-atlas.js +2 -0
- package/dist/converter.min.js +71 -71
- package/dist/deps-installer/deps-installer.d.ts +3 -2
- package/dist/deps-installer/deps-installer.d.ts.map +1 -1
- package/dist/deps-installer/deps-installer.js +36 -10
- package/dist/dist.min.js +824 -3079
- package/dist/es5/3d-tiles-converter/3d-tiles-converter.js +94 -81
- package/dist/es5/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
- package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js +6 -4
- package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
- package/dist/es5/3d-tiles-converter/helpers/load-i3s.js +63 -0
- package/dist/es5/3d-tiles-converter/helpers/load-i3s.js.map +1 -0
- package/dist/es5/3d-tiles-converter/helpers/texture-atlas.js.map +1 -1
- package/dist/es5/deps-installer/deps-installer.js +112 -38
- package/dist/es5/deps-installer/deps-installer.js.map +1 -1
- package/dist/es5/i3s-converter/helpers/geometry-converter.js +12 -9
- package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/es5/i3s-converter/i3s-converter.js +32 -87
- package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/es5/lib/utils/lod-conversion-utils.js +10 -4
- package/dist/es5/lib/utils/lod-conversion-utils.js.map +1 -1
- package/dist/es5/pgm-loader.js +1 -1
- package/dist/esm/3d-tiles-converter/3d-tiles-converter.js +46 -43
- package/dist/esm/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
- package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js +4 -3
- package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
- package/dist/esm/3d-tiles-converter/helpers/load-i3s.js +32 -0
- package/dist/esm/3d-tiles-converter/helpers/load-i3s.js.map +1 -0
- package/dist/esm/3d-tiles-converter/helpers/texture-atlas.js.map +1 -1
- package/dist/esm/deps-installer/deps-installer.js +37 -11
- package/dist/esm/deps-installer/deps-installer.js.map +1 -1
- package/dist/esm/i3s-converter/helpers/geometry-converter.js +10 -6
- package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
- package/dist/esm/i3s-converter/i3s-converter.js +11 -28
- package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
- package/dist/esm/i3s-server/bin/i3s-server.min.js +72 -72
- package/dist/esm/lib/utils/lod-conversion-utils.js +6 -4
- package/dist/esm/lib/utils/lod-conversion-utils.js.map +1 -1
- package/dist/esm/pgm-loader.js +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.d.ts +2 -4
- package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
- package/dist/i3s-converter/helpers/geometry-converter.js +18 -13
- package/dist/i3s-converter/i3s-converter.d.ts +0 -1
- package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
- package/dist/i3s-converter/i3s-converter.js +10 -22
- package/dist/lib/utils/lod-conversion-utils.d.ts +2 -2
- package/dist/lib/utils/lod-conversion-utils.d.ts.map +1 -1
- package/dist/lib/utils/lod-conversion-utils.js +4 -4
- package/dist/slpk-extractor.min.js +38 -38
- package/package.json +14 -14
- package/src/3d-tiles-converter/3d-tiles-converter.ts +60 -46
- package/src/3d-tiles-converter/helpers/b3dm-converter.ts +11 -10
- package/src/3d-tiles-converter/helpers/load-i3s.ts +51 -0
- package/src/3d-tiles-converter/helpers/texture-atlas.ts +6 -2
- package/src/deps-installer/deps-installer.ts +55 -10
- package/src/i3s-converter/helpers/geometry-converter.ts +19 -14
- package/src/i3s-converter/i3s-converter.ts +12 -28
- package/src/lib/utils/lod-conversion-utils.ts +10 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loaders.gl/tile-converter",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.19",
|
|
4
4
|
"description": "Converter",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -45,18 +45,18 @@
|
|
|
45
45
|
"build-i3s-server-bundle": "esbuild src/i3s-server/bin/www.ts --outfile=dist/esm/i3s-server/bin/i3s-server.min.js --platform=node --target=esnext,node14 --external:join-images --minify --bundle --define:__VERSION__=\\\"$npm_package_version\\\""
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@loaders.gl/3d-tiles": "4.0.0-alpha.
|
|
49
|
-
"@loaders.gl/crypto": "4.0.0-alpha.
|
|
50
|
-
"@loaders.gl/draco": "4.0.0-alpha.
|
|
51
|
-
"@loaders.gl/gltf": "4.0.0-alpha.
|
|
52
|
-
"@loaders.gl/i3s": "4.0.0-alpha.
|
|
53
|
-
"@loaders.gl/images": "4.0.0-alpha.
|
|
54
|
-
"@loaders.gl/loader-utils": "4.0.0-alpha.
|
|
55
|
-
"@loaders.gl/polyfills": "4.0.0-alpha.
|
|
56
|
-
"@loaders.gl/textures": "4.0.0-alpha.
|
|
57
|
-
"@loaders.gl/tiles": "4.0.0-alpha.
|
|
58
|
-
"@loaders.gl/worker-utils": "4.0.0-alpha.
|
|
59
|
-
"@loaders.gl/zip": "4.0.0-alpha.
|
|
48
|
+
"@loaders.gl/3d-tiles": "4.0.0-alpha.19",
|
|
49
|
+
"@loaders.gl/crypto": "4.0.0-alpha.19",
|
|
50
|
+
"@loaders.gl/draco": "4.0.0-alpha.19",
|
|
51
|
+
"@loaders.gl/gltf": "4.0.0-alpha.19",
|
|
52
|
+
"@loaders.gl/i3s": "4.0.0-alpha.19",
|
|
53
|
+
"@loaders.gl/images": "4.0.0-alpha.19",
|
|
54
|
+
"@loaders.gl/loader-utils": "4.0.0-alpha.19",
|
|
55
|
+
"@loaders.gl/polyfills": "4.0.0-alpha.19",
|
|
56
|
+
"@loaders.gl/textures": "4.0.0-alpha.19",
|
|
57
|
+
"@loaders.gl/tiles": "4.0.0-alpha.19",
|
|
58
|
+
"@loaders.gl/worker-utils": "4.0.0-alpha.19",
|
|
59
|
+
"@loaders.gl/zip": "4.0.0-alpha.19",
|
|
60
60
|
"@math.gl/core": "^3.5.1",
|
|
61
61
|
"@math.gl/culling": "^3.5.1",
|
|
62
62
|
"@math.gl/geoid": "^3.5.1",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"join-images": "^1.1.3",
|
|
80
80
|
"sharp": "^0.31.3"
|
|
81
81
|
},
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "2ca50ec4e1d312c124eb7c93c60ab6fd17ee833e",
|
|
83
83
|
"devDependencies": {
|
|
84
84
|
"@types/express": "^4.17.17",
|
|
85
85
|
"@types/node": "^20.4.2"
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
AttributeStorageInfo,
|
|
3
|
+
FeatureAttribute,
|
|
4
|
+
NodeReference,
|
|
5
|
+
I3STilesetHeader
|
|
6
|
+
} from '@loaders.gl/i3s';
|
|
2
7
|
import type {Tiles3DTileJSON} from '@loaders.gl/3d-tiles';
|
|
3
8
|
|
|
4
9
|
import {join} from 'path';
|
|
@@ -6,7 +11,6 @@ import process from 'process';
|
|
|
6
11
|
import transform from 'json-map-transform';
|
|
7
12
|
import {load, isBrowser} from '@loaders.gl/core';
|
|
8
13
|
import {I3SLoader, I3SAttributeLoader, COORDINATE_SYSTEM} from '@loaders.gl/i3s';
|
|
9
|
-
import {Tileset3D, Tile3D} from '@loaders.gl/tiles';
|
|
10
14
|
import {Geoid} from '@math.gl/geoid';
|
|
11
15
|
|
|
12
16
|
import {PGMLoader} from '../pgm-loader';
|
|
@@ -19,6 +23,9 @@ import {createObbFromMbs} from '../i3s-converter/helpers/coordinate-converter';
|
|
|
19
23
|
import {WorkerFarm} from '@loaders.gl/worker-utils';
|
|
20
24
|
import {BROWSER_ERROR_MESSAGE} from '../constants';
|
|
21
25
|
import B3dmConverter, {I3SAttributesData} from './helpers/b3dm-converter';
|
|
26
|
+
import {I3STileHeader} from '@loaders.gl/i3s/src/types';
|
|
27
|
+
import {loadI3SContent} from './helpers/load-i3s';
|
|
28
|
+
import {I3SLoaderOptions} from '@loaders.gl/i3s/src/i3s-loader';
|
|
22
29
|
|
|
23
30
|
const I3S = 'I3S';
|
|
24
31
|
|
|
@@ -31,9 +38,18 @@ export default class Tiles3DConverter {
|
|
|
31
38
|
vertexCounter: number;
|
|
32
39
|
conversionStartTime: [number, number];
|
|
33
40
|
geoidHeightModel: Geoid | null;
|
|
34
|
-
sourceTileset:
|
|
35
|
-
attributeStorageInfo
|
|
41
|
+
sourceTileset: I3STilesetHeader | null;
|
|
42
|
+
attributeStorageInfo?: AttributeStorageInfo[] | null;
|
|
36
43
|
workerSource: {[key: string]: string} = {};
|
|
44
|
+
loaderOptions: I3SLoaderOptions = {
|
|
45
|
+
_nodeWorkers: true,
|
|
46
|
+
reuseWorkers: true,
|
|
47
|
+
i3s: {coordinateSystem: COORDINATE_SYSTEM.LNGLAT_OFFSETS, decodeTextures: false},
|
|
48
|
+
// We need to load local fs workers because nodejs can't load workers from the Internet
|
|
49
|
+
'i3s-content': {
|
|
50
|
+
workerUrl: './modules/i3s/dist/i3s-content-worker-node.js'
|
|
51
|
+
}
|
|
52
|
+
};
|
|
37
53
|
|
|
38
54
|
constructor() {
|
|
39
55
|
this.options = {};
|
|
@@ -74,28 +90,19 @@ export default class Tiles3DConverter {
|
|
|
74
90
|
this.geoidHeightModel = await load(egmFilePath, PGMLoader);
|
|
75
91
|
console.log('Loading egm file completed!'); // eslint-disable-line
|
|
76
92
|
|
|
77
|
-
|
|
93
|
+
this.sourceTileset = await load(inputUrl, I3SLoader, this.loaderOptions);
|
|
78
94
|
|
|
79
|
-
this.sourceTileset
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
reuseWorkers: true,
|
|
83
|
-
i3s: {coordinateSystem: COORDINATE_SYSTEM.LNGLAT_OFFSETS, decodeTextures: false},
|
|
84
|
-
// We need to load local fs workers because nodejs can't load workers from the Internet
|
|
85
|
-
'i3s-content': {
|
|
86
|
-
workerUrl: './modules/i3s/dist/i3s-content-worker-node.js'
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
});
|
|
95
|
+
if (!this.sourceTileset) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
90
98
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
rootNode.header.obb = createObbFromMbs(rootNode.header.mbs);
|
|
99
|
+
const rootNode = this.sourceTileset?.root;
|
|
100
|
+
if (!rootNode.obb) {
|
|
101
|
+
rootNode.obb = createObbFromMbs(rootNode.mbs);
|
|
95
102
|
}
|
|
96
103
|
|
|
97
104
|
this.tilesetPath = join(`${outputPath}`, `${tilesetName}`);
|
|
98
|
-
this.attributeStorageInfo =
|
|
105
|
+
this.attributeStorageInfo = this.sourceTileset.attributeStorageInfo;
|
|
99
106
|
// Removing the tilesetPath needed to exclude erroneous files after conversion
|
|
100
107
|
try {
|
|
101
108
|
await removeDir(this.tilesetPath);
|
|
@@ -105,7 +112,7 @@ export default class Tiles3DConverter {
|
|
|
105
112
|
|
|
106
113
|
const rootTile: Tiles3DTileJSON = {
|
|
107
114
|
boundingVolume: {
|
|
108
|
-
box: i3sObbTo3dTilesObb(rootNode.
|
|
115
|
+
box: i3sObbTo3dTilesObb(rootNode.obb, this.geoidHeightModel)
|
|
109
116
|
},
|
|
110
117
|
geometricError: convertScreenThresholdToGeometricError(rootNode),
|
|
111
118
|
children: []
|
|
@@ -131,28 +138,33 @@ export default class Tiles3DConverter {
|
|
|
131
138
|
* @param childNodeInfo child node to convert
|
|
132
139
|
*/
|
|
133
140
|
private async convertChildNode(
|
|
134
|
-
parentSourceNode:
|
|
141
|
+
parentSourceNode: I3STileHeader,
|
|
135
142
|
parentNode: Tiles3DTileJSON,
|
|
136
143
|
level: number,
|
|
137
144
|
childNodeInfo: NodeReference
|
|
138
145
|
): Promise<void> {
|
|
139
146
|
const sourceChild = await this._loadChildNode(parentSourceNode, childNodeInfo);
|
|
140
|
-
parentSourceNode.children.push(sourceChild);
|
|
141
147
|
if (sourceChild.contentUrl) {
|
|
142
|
-
await this.sourceTileset
|
|
143
|
-
|
|
148
|
+
const content = await loadI3SContent(this.sourceTileset, sourceChild, this.loaderOptions);
|
|
149
|
+
|
|
150
|
+
if (!content) {
|
|
151
|
+
await this._addChildren(sourceChild, parentNode, level + 1);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this.vertexCounter += content?.vertexCount || 0;
|
|
144
156
|
|
|
145
157
|
let featureAttributes: FeatureAttribute | null = null;
|
|
146
158
|
if (this.attributeStorageInfo) {
|
|
147
159
|
featureAttributes = await this._loadChildAttributes(sourceChild, this.attributeStorageInfo);
|
|
148
160
|
}
|
|
149
161
|
|
|
150
|
-
if (!sourceChild.
|
|
151
|
-
sourceChild.
|
|
162
|
+
if (!sourceChild.obb) {
|
|
163
|
+
sourceChild.obb = createObbFromMbs(sourceChild.mbs);
|
|
152
164
|
}
|
|
153
165
|
|
|
154
166
|
const boundingVolume = {
|
|
155
|
-
box: i3sObbTo3dTilesObb(sourceChild.
|
|
167
|
+
box: i3sObbTo3dTilesObb(sourceChild.obb, this.geoidHeightModel)
|
|
156
168
|
};
|
|
157
169
|
const child: Tiles3DTileJSON = {
|
|
158
170
|
boundingVolume,
|
|
@@ -161,8 +173,9 @@ export default class Tiles3DConverter {
|
|
|
161
173
|
};
|
|
162
174
|
|
|
163
175
|
const i3sAttributesData: I3SAttributesData = {
|
|
164
|
-
tileContent:
|
|
165
|
-
|
|
176
|
+
tileContent: content,
|
|
177
|
+
box: boundingVolume.box,
|
|
178
|
+
textureFormat: sourceChild.textureFormat
|
|
166
179
|
};
|
|
167
180
|
|
|
168
181
|
const b3dmConverter = new B3dmConverter();
|
|
@@ -175,7 +188,6 @@ export default class Tiles3DConverter {
|
|
|
175
188
|
await writeFile(this.tilesetPath, new Uint8Array(b3dm), `${sourceChild.id}.b3dm`);
|
|
176
189
|
parentNode.children.push(child);
|
|
177
190
|
|
|
178
|
-
sourceChild.unloadContent();
|
|
179
191
|
await this._addChildren(sourceChild, child, level + 1);
|
|
180
192
|
} else {
|
|
181
193
|
await this._addChildren(sourceChild, parentNode, level + 1);
|
|
@@ -189,7 +201,7 @@ export default class Tiles3DConverter {
|
|
|
189
201
|
* @param level a current level of a tree depth
|
|
190
202
|
*/
|
|
191
203
|
private async _addChildren(
|
|
192
|
-
parentSourceNode:
|
|
204
|
+
parentSourceNode: I3STileHeader,
|
|
193
205
|
parentNode: Tiles3DTileJSON,
|
|
194
206
|
level: number
|
|
195
207
|
): Promise<void> {
|
|
@@ -197,7 +209,7 @@ export default class Tiles3DConverter {
|
|
|
197
209
|
return;
|
|
198
210
|
}
|
|
199
211
|
const promises: Promise<void>[] = [];
|
|
200
|
-
for (const childNodeInfo of parentSourceNode.
|
|
212
|
+
for (const childNodeInfo of parentSourceNode.children || []) {
|
|
201
213
|
promises.push(this.convertChildNode(parentSourceNode, parentNode, level, childNodeInfo));
|
|
202
214
|
}
|
|
203
215
|
await Promise.all(promises);
|
|
@@ -209,29 +221,31 @@ export default class Tiles3DConverter {
|
|
|
209
221
|
* @param childNodeInfo child information from 3DNodeIndexDocument
|
|
210
222
|
* (https://github.com/Esri/i3s-spec/blob/master/docs/1.7/nodeReference.cmn.md)
|
|
211
223
|
*/
|
|
212
|
-
private async _loadChildNode(
|
|
224
|
+
private async _loadChildNode(
|
|
225
|
+
parentNode: I3STileHeader,
|
|
226
|
+
childNodeInfo: NodeReference
|
|
227
|
+
): Promise<I3STileHeader> {
|
|
213
228
|
let header;
|
|
214
|
-
if (this.sourceTileset
|
|
229
|
+
if (this.sourceTileset?.nodePagesTile) {
|
|
215
230
|
console.log(`Node conversion: ${childNodeInfo.id}`); // eslint-disable-line no-console,no-undef
|
|
216
|
-
header = await this.sourceTileset
|
|
217
|
-
childNodeInfo.id
|
|
231
|
+
header = await this.sourceTileset.nodePagesTile.formTileFromNodePages(
|
|
232
|
+
parseInt(childNodeInfo.id)
|
|
218
233
|
);
|
|
219
234
|
} else {
|
|
220
|
-
const {loader} = this.sourceTileset!;
|
|
221
235
|
const nodeUrl = this._relativeUrlToFullUrl(parentNode.url, childNodeInfo.href!);
|
|
222
236
|
// load metadata
|
|
223
237
|
const options = {
|
|
224
238
|
i3s: {
|
|
225
|
-
...this.
|
|
239
|
+
...this.loaderOptions,
|
|
226
240
|
isTileHeader: true,
|
|
227
241
|
loadContent: false
|
|
228
242
|
}
|
|
229
243
|
};
|
|
230
244
|
|
|
231
245
|
console.log(`Node conversion: ${nodeUrl}`); // eslint-disable-line no-console,no-undef
|
|
232
|
-
header = await load(nodeUrl,
|
|
246
|
+
header = await load(nodeUrl, I3SLoader, options);
|
|
233
247
|
}
|
|
234
|
-
return
|
|
248
|
+
return header;
|
|
235
249
|
}
|
|
236
250
|
|
|
237
251
|
/**
|
|
@@ -239,7 +253,7 @@ export default class Tiles3DConverter {
|
|
|
239
253
|
* @param baseUrl the base url. A resulting url will be related from this url
|
|
240
254
|
* @param relativeUrl a realtive url of a resource
|
|
241
255
|
*/
|
|
242
|
-
private _relativeUrlToFullUrl(baseUrl: string, relativeUrl: string): string {
|
|
256
|
+
private _relativeUrlToFullUrl(baseUrl: string = '', relativeUrl: string): string {
|
|
243
257
|
let resultArray = baseUrl.split('/');
|
|
244
258
|
const relativeUrlArray = relativeUrl.split('/');
|
|
245
259
|
for (const folder of relativeUrlArray) {
|
|
@@ -263,11 +277,11 @@ export default class Tiles3DConverter {
|
|
|
263
277
|
* @returns Promise of attributes object.
|
|
264
278
|
*/
|
|
265
279
|
private async _loadChildAttributes(
|
|
266
|
-
sourceChild:
|
|
267
|
-
attributeStorageInfo: AttributeStorageInfo
|
|
280
|
+
sourceChild: I3STileHeader,
|
|
281
|
+
attributeStorageInfo: AttributeStorageInfo[]
|
|
268
282
|
): Promise<FeatureAttribute> {
|
|
269
283
|
const promises: any[] = [];
|
|
270
|
-
const {attributeUrls} = sourceChild
|
|
284
|
+
const {attributeUrls = []} = sourceChild;
|
|
271
285
|
|
|
272
286
|
for (let index = 0; index < attributeUrls.length; index++) {
|
|
273
287
|
const inputUrl = attributeUrls[index];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type {I3STileContent} from '@loaders.gl/i3s';
|
|
1
2
|
import {encodeSync} from '@loaders.gl/core';
|
|
2
3
|
import {GLTFScenegraph, GLTFWriter} from '@loaders.gl/gltf';
|
|
3
4
|
import {Tile3DWriter} from '@loaders.gl/3d-tiles';
|
|
@@ -10,7 +11,8 @@ const Z_UP_TO_Y_UP_MATRIX = new Matrix4([1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0,
|
|
|
10
11
|
const scratchVector = new Vector3();
|
|
11
12
|
|
|
12
13
|
export type I3SAttributesData = {
|
|
13
|
-
tileContent:
|
|
14
|
+
tileContent: I3STileContent;
|
|
15
|
+
box: number[];
|
|
14
16
|
textureFormat: string;
|
|
15
17
|
};
|
|
16
18
|
|
|
@@ -53,15 +55,8 @@ export default class B3dmConverter {
|
|
|
53
55
|
i3sAttributesData: I3SAttributesData,
|
|
54
56
|
featureAttributes: any
|
|
55
57
|
): Promise<ArrayBuffer> {
|
|
56
|
-
const {tileContent, textureFormat} = i3sAttributesData;
|
|
57
|
-
const {
|
|
58
|
-
material,
|
|
59
|
-
attributes,
|
|
60
|
-
indices: originalIndices,
|
|
61
|
-
cartesianOrigin,
|
|
62
|
-
cartographicOrigin,
|
|
63
|
-
modelMatrix
|
|
64
|
-
} = tileContent;
|
|
58
|
+
const {tileContent, textureFormat, box} = i3sAttributesData;
|
|
59
|
+
const {material, attributes, indices: originalIndices, modelMatrix} = tileContent;
|
|
65
60
|
const gltfBuilder = new GLTFScenegraph();
|
|
66
61
|
|
|
67
62
|
const textureIndex = await this._addI3sTextureToGltf(tileContent, textureFormat, gltfBuilder);
|
|
@@ -78,6 +73,12 @@ export default class B3dmConverter {
|
|
|
78
73
|
);
|
|
79
74
|
}
|
|
80
75
|
|
|
76
|
+
const cartesianOrigin = new Vector3(box);
|
|
77
|
+
const cartographicOrigin = Ellipsoid.WGS84.cartesianToCartographic(
|
|
78
|
+
cartesianOrigin,
|
|
79
|
+
new Vector3()
|
|
80
|
+
);
|
|
81
|
+
|
|
81
82
|
attributes.positions.value = this._normalizePositions(
|
|
82
83
|
positionsValue,
|
|
83
84
|
cartesianOrigin,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {load} from '@loaders.gl/core';
|
|
2
|
+
import {
|
|
3
|
+
I3STileContent,
|
|
4
|
+
I3STileHeader,
|
|
5
|
+
I3STilesetHeader,
|
|
6
|
+
I3SLoader,
|
|
7
|
+
I3SLoaderOptions
|
|
8
|
+
} from '@loaders.gl/i3s';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Load I3S node content
|
|
12
|
+
* @param sourceTileset - source layer JSON
|
|
13
|
+
* @param sourceTile - source I3S node metadata
|
|
14
|
+
* @param tilesetLoadOptions - load options for Tiles3DLoader
|
|
15
|
+
* @returns - 3DTiles tile content or null
|
|
16
|
+
*/
|
|
17
|
+
export const loadI3SContent = async (
|
|
18
|
+
sourceTileset: I3STilesetHeader | null,
|
|
19
|
+
sourceTile: I3STileHeader,
|
|
20
|
+
tilesetLoadOptions: I3SLoaderOptions
|
|
21
|
+
): Promise<I3STileContent | null> => {
|
|
22
|
+
if (!sourceTileset || !sourceTile.contentUrl) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const loadOptions = {
|
|
27
|
+
...tilesetLoadOptions,
|
|
28
|
+
i3s: {
|
|
29
|
+
...tilesetLoadOptions.i3s,
|
|
30
|
+
isTileset: false,
|
|
31
|
+
isTileHeader: false,
|
|
32
|
+
_tileOptions: {
|
|
33
|
+
attributeUrls: sourceTile.attributeUrls,
|
|
34
|
+
textureUrl: sourceTile.textureUrl,
|
|
35
|
+
textureFormat: sourceTile.textureFormat,
|
|
36
|
+
textureLoaderOptions: sourceTile.textureLoaderOptions,
|
|
37
|
+
materialDefinition: sourceTile.materialDefinition,
|
|
38
|
+
isDracoGeometry: sourceTile.isDracoGeometry,
|
|
39
|
+
mbs: sourceTile.mbs
|
|
40
|
+
},
|
|
41
|
+
_tilesetOptions: {
|
|
42
|
+
store: sourceTileset.store,
|
|
43
|
+
attributeStorageInfo: sourceTileset.attributeStorageInfo,
|
|
44
|
+
fields: sourceTileset.fields
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const tileContent = await load(sourceTile.contentUrl, I3SLoader, loadOptions);
|
|
49
|
+
|
|
50
|
+
return tileContent;
|
|
51
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type {TypedArray} from '@loaders.gl/loader-utils';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Apply uvRegions to texture coordinates.
|
|
3
5
|
* Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.7/geometryUVRegion.cmn.md
|
|
@@ -5,7 +7,7 @@
|
|
|
5
7
|
* @param texCoords
|
|
6
8
|
* @param uvRegions
|
|
7
9
|
*/
|
|
8
|
-
export function convertTextureAtlas(texCoords:
|
|
10
|
+
export function convertTextureAtlas(texCoords: TypedArray, uvRegions: TypedArray): Float32Array {
|
|
9
11
|
const convertedTexCoords = new Float32Array(texCoords.length);
|
|
10
12
|
const normalisedRegions = normalizeRegions(uvRegions);
|
|
11
13
|
|
|
@@ -43,7 +45,9 @@ function fract(uv: [number, number]): [number, number] {
|
|
|
43
45
|
* Normalize uvRegions by dividing by the maximum Uint16 value
|
|
44
46
|
* @param regions
|
|
45
47
|
*/
|
|
46
|
-
function normalizeRegions(regions:
|
|
48
|
+
function normalizeRegions(regions: TypedArray): number[] {
|
|
49
|
+
// The code is for Uint16Array because it is the spec requirement
|
|
50
|
+
// https://github.com/Esri/i3s-spec/blob/master/docs/1.8/geometryUVRegion.cmn.md
|
|
47
51
|
const MAX_UINT_16_VALUE = 65535;
|
|
48
52
|
const normalizedRegions: number[] = [];
|
|
49
53
|
|
|
@@ -3,6 +3,8 @@ import {ZipLoader} from '@loaders.gl/zip';
|
|
|
3
3
|
import {writeFile} from '../lib/utils/file-utils';
|
|
4
4
|
import {join} from 'path';
|
|
5
5
|
import {ChildProcessProxy} from '@loaders.gl/worker-utils';
|
|
6
|
+
import {DRACO_EXTERNAL_LIBRARIES, DRACO_EXTERNAL_LIBRARY_URLS} from '@loaders.gl/draco';
|
|
7
|
+
import {BASIS_EXTERNAL_LIBRARIES} from '@loaders.gl/textures';
|
|
6
8
|
|
|
7
9
|
// @ts-ignore TS2304: Cannot find name '__VERSION__'.
|
|
8
10
|
const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'beta';
|
|
@@ -23,7 +25,7 @@ export class DepsInstaller {
|
|
|
23
25
|
* This path is '' by default and is not used by tile-converter.
|
|
24
26
|
* It is used in tests to prevent rewriting actual workers during tests running
|
|
25
27
|
*/
|
|
26
|
-
async install(path: string = ''
|
|
28
|
+
async install(path: string = ''): Promise<void> {
|
|
27
29
|
console.log('Installing "EGM2008-5" model...'); // eslint-disable-line no-console
|
|
28
30
|
const fileMap = await load(PGM_LINK, ZipLoader, {});
|
|
29
31
|
|
|
@@ -34,14 +36,47 @@ export class DepsInstaller {
|
|
|
34
36
|
|
|
35
37
|
await writeFile(depsPath, new Uint8Array(fileMap['geoids/egm2008-5.pgm']), 'egm2008-5.pgm');
|
|
36
38
|
|
|
37
|
-
console.log('Installing "I3S Content Loader worker
|
|
38
|
-
await this.
|
|
39
|
+
console.log('Installing "I3S Content Loader" worker'); // eslint-disable-line no-console
|
|
40
|
+
await this.installFromNpm('i3s', 'i3s-content-worker-node.js');
|
|
39
41
|
|
|
40
|
-
console.log('Installing "Draco Loader worker
|
|
41
|
-
await this.
|
|
42
|
+
console.log('Installing "Draco Loader" worker'); // eslint-disable-line no-console
|
|
43
|
+
await this.installFromNpm('draco', 'draco-worker-node.js');
|
|
42
44
|
|
|
43
|
-
console.log('Installing "
|
|
44
|
-
await this.
|
|
45
|
+
console.log('Installing "Draco Writer" worker'); // eslint-disable-line no-console
|
|
46
|
+
await this.installFromNpm('draco', 'draco-writer-worker-node.js');
|
|
47
|
+
|
|
48
|
+
console.log('Installing "Basis Loader" worker'); // eslint-disable-line no-console
|
|
49
|
+
await this.installFromNpm('textures', 'basis-worker-node.js');
|
|
50
|
+
|
|
51
|
+
console.log('Installing "KTX2 Basis Writer" worker'); // eslint-disable-line no-console
|
|
52
|
+
await this.installFromNpm('textures', 'ktx2-basis-writer-worker-node.js');
|
|
53
|
+
|
|
54
|
+
console.log('Installing "Draco decoder" library'); // eslint-disable-line no-console
|
|
55
|
+
await this.installFromUrl(
|
|
56
|
+
DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER],
|
|
57
|
+
'draco',
|
|
58
|
+
DRACO_EXTERNAL_LIBRARIES.DECODER
|
|
59
|
+
);
|
|
60
|
+
await this.installFromUrl(
|
|
61
|
+
DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.DECODER_WASM],
|
|
62
|
+
'draco',
|
|
63
|
+
DRACO_EXTERNAL_LIBRARIES.DECODER_WASM
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
console.log('Installing "Draco encoder" library'); // eslint-disable-line no-console
|
|
67
|
+
await this.installFromUrl(
|
|
68
|
+
DRACO_EXTERNAL_LIBRARY_URLS[DRACO_EXTERNAL_LIBRARIES.ENCODER],
|
|
69
|
+
'draco',
|
|
70
|
+
DRACO_EXTERNAL_LIBRARIES.ENCODER
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
console.log('Installing "Basis transcoder" library'); // eslint-disable-line no-console
|
|
74
|
+
await this.installFromNpm('textures', BASIS_EXTERNAL_LIBRARIES.TRANSCODER, 'libs');
|
|
75
|
+
await this.installFromNpm('textures', BASIS_EXTERNAL_LIBRARIES.TRANSCODER_WASM, 'libs');
|
|
76
|
+
|
|
77
|
+
console.log('Installing "Basis encoder" library'); // eslint-disable-line no-console
|
|
78
|
+
await this.installFromNpm('textures', BASIS_EXTERNAL_LIBRARIES.ENCODER, 'libs');
|
|
79
|
+
await this.installFromNpm('textures', BASIS_EXTERNAL_LIBRARIES.ENCODER_WASM, 'libs');
|
|
45
80
|
|
|
46
81
|
console.log('Installing "join-images" npm package');
|
|
47
82
|
const childProcess = new ChildProcessProxy();
|
|
@@ -58,15 +93,25 @@ export class DepsInstaller {
|
|
|
58
93
|
console.log('All dependencies were installed succesfully.'); // eslint-disable-line no-console
|
|
59
94
|
}
|
|
60
95
|
|
|
61
|
-
private async
|
|
96
|
+
private async installFromNpm(module: string, name: string, extraPath: string = '') {
|
|
62
97
|
const fileResponse = await fetchFile(
|
|
63
|
-
`https://unpkg.com/@loaders.gl/${module}@${VERSION}/dist/${name}`
|
|
98
|
+
`https://unpkg.com/@loaders.gl/${module}@${VERSION}/dist/${extraPath}/${name}`
|
|
64
99
|
);
|
|
65
100
|
const fileData = await fileResponse.arrayBuffer();
|
|
66
101
|
if (!fileData) {
|
|
67
102
|
return;
|
|
68
103
|
}
|
|
69
|
-
const path = join(process.cwd(),
|
|
104
|
+
const path = join(process.cwd(), 'modules', module, 'dist', extraPath);
|
|
105
|
+
await writeFile(path, fileData, name);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private async installFromUrl(url: string, module: string, name: string) {
|
|
109
|
+
const fileResponse = await fetchFile(url);
|
|
110
|
+
const fileData = await fileResponse.arrayBuffer();
|
|
111
|
+
if (!fileData) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const path = join(process.cwd(), 'modules', module, 'dist', 'libs');
|
|
70
115
|
await writeFile(path, fileData, name);
|
|
71
116
|
}
|
|
72
117
|
}
|
|
@@ -87,7 +87,7 @@ let scratchVector = new Vector3();
|
|
|
87
87
|
* @param generateBoundingVolumes - is converter should create accurate bounding voulmes from geometry attributes
|
|
88
88
|
* @param shouldMergeMaterials - Try to merge similar materials to be able to merge meshes into one node
|
|
89
89
|
* @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
|
|
90
|
-
* @param
|
|
90
|
+
* @param libraries - dynamicaly loaded 3rd-party libraries
|
|
91
91
|
* @returns Array of node resources to create one or more i3s nodes
|
|
92
92
|
*/
|
|
93
93
|
export default async function convertB3dmToI3sGeometry(
|
|
@@ -102,7 +102,7 @@ export default async function convertB3dmToI3sGeometry(
|
|
|
102
102
|
generateBoundingVolumes: boolean,
|
|
103
103
|
shouldMergeMaterials: boolean,
|
|
104
104
|
geoidHeightModel: Geoid,
|
|
105
|
-
|
|
105
|
+
libraries: Record<string, string>
|
|
106
106
|
): Promise<I3SConvertedResources[] | null> {
|
|
107
107
|
const useCartesianPositions = generateBoundingVolumes;
|
|
108
108
|
const materialAndTextureList: I3SMaterialWithTexture[] = await convertMaterials(
|
|
@@ -156,7 +156,7 @@ export default async function convertB3dmToI3sGeometry(
|
|
|
156
156
|
propertyTable,
|
|
157
157
|
attributeStorageInfo,
|
|
158
158
|
draco,
|
|
159
|
-
|
|
159
|
+
libraries
|
|
160
160
|
})
|
|
161
161
|
);
|
|
162
162
|
}
|
|
@@ -208,7 +208,7 @@ function _generateBoundingVolumesFromGeometry(
|
|
|
208
208
|
* @param params.propertyTable - batch table (corresponding to feature attributes data)
|
|
209
209
|
* @param params.attributeStorageInfo - attributes metadata from 3DSceneLayer json
|
|
210
210
|
* @param params.draco - is converter should create draco compressed geometry
|
|
211
|
-
* @param
|
|
211
|
+
* @param libraries - dynamicaly loaded 3rd-party libraries
|
|
212
212
|
* @returns Array of I3S node resources
|
|
213
213
|
*/
|
|
214
214
|
async function _makeNodeResources({
|
|
@@ -221,7 +221,7 @@ async function _makeNodeResources({
|
|
|
221
221
|
propertyTable,
|
|
222
222
|
attributeStorageInfo,
|
|
223
223
|
draco,
|
|
224
|
-
|
|
224
|
+
libraries
|
|
225
225
|
}: {
|
|
226
226
|
convertedAttributes: ConvertedAttributes;
|
|
227
227
|
material: I3SMaterialDefinition;
|
|
@@ -232,7 +232,7 @@ async function _makeNodeResources({
|
|
|
232
232
|
propertyTable: FeatureTableJson | null;
|
|
233
233
|
attributeStorageInfo?: AttributeStorageInfo[];
|
|
234
234
|
draco: boolean;
|
|
235
|
-
|
|
235
|
+
libraries: Record<string, string>;
|
|
236
236
|
}): Promise<I3SConvertedResources> {
|
|
237
237
|
const boundingVolumes = convertedAttributes.boundingVolumes;
|
|
238
238
|
const vertexCount = convertedAttributes.positions.length / VALUES_PER_VERTEX;
|
|
@@ -277,7 +277,7 @@ async function _makeNodeResources({
|
|
|
277
277
|
featureIds,
|
|
278
278
|
faceRange
|
|
279
279
|
},
|
|
280
|
-
|
|
280
|
+
libraries
|
|
281
281
|
)
|
|
282
282
|
: null;
|
|
283
283
|
|
|
@@ -1451,17 +1451,17 @@ function generateBigUint64Array(featureIds: any[]): BigUint64Array {
|
|
|
1451
1451
|
|
|
1452
1452
|
/**
|
|
1453
1453
|
* Generates draco compressed geometry
|
|
1454
|
-
* @param
|
|
1455
|
-
* @param
|
|
1456
|
-
* @param
|
|
1457
|
-
* @param
|
|
1458
|
-
* @returns
|
|
1454
|
+
* @param vertexCount
|
|
1455
|
+
* @param convertedAttributes - get rid of this argument here
|
|
1456
|
+
* @param attributes - geometry attributes to compress
|
|
1457
|
+
* @param libraries - dynamicaly loaded 3rd-party libraries
|
|
1458
|
+
* @returns - Compressed geometry.
|
|
1459
1459
|
*/
|
|
1460
1460
|
async function generateCompressedGeometry(
|
|
1461
1461
|
vertexCount: number,
|
|
1462
1462
|
convertedAttributes: Record<string, any>,
|
|
1463
1463
|
attributes: Record<string, any>,
|
|
1464
|
-
|
|
1464
|
+
libraries: Record<string, string>
|
|
1465
1465
|
): Promise<ArrayBuffer> {
|
|
1466
1466
|
const {positions, normals, texCoords, colors, uvRegions, featureIds, faceRange} = attributes;
|
|
1467
1467
|
const indices = new Uint32Array(vertexCount);
|
|
@@ -1510,12 +1510,17 @@ async function generateCompressedGeometry(
|
|
|
1510
1510
|
|
|
1511
1511
|
return encode({attributes: compressedAttributes, indices}, DracoWriterWorker, {
|
|
1512
1512
|
...DracoWriterWorker.options,
|
|
1513
|
-
source: dracoWorkerSoure,
|
|
1514
1513
|
reuseWorkers: true,
|
|
1515
1514
|
_nodeWorkers: true,
|
|
1515
|
+
modules: libraries,
|
|
1516
|
+
useLocalLibraries: true,
|
|
1516
1517
|
draco: {
|
|
1517
1518
|
method: 'MESH_SEQUENTIAL_ENCODING',
|
|
1518
1519
|
attributesMetadata
|
|
1520
|
+
},
|
|
1521
|
+
['draco-writer']: {
|
|
1522
|
+
// We need to load local fs workers because nodejs can't load workers from the Internet
|
|
1523
|
+
workerUrl: './modules/draco/dist/draco-writer-worker-node.js'
|
|
1519
1524
|
}
|
|
1520
1525
|
});
|
|
1521
1526
|
}
|