@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.
Files changed (69) hide show
  1. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +5 -4
  2. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
  3. package/dist/3d-tiles-converter/3d-tiles-converter.js +39 -37
  4. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts +3 -1
  5. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -1
  6. package/dist/3d-tiles-converter/helpers/b3dm-converter.js +4 -2
  7. package/dist/3d-tiles-converter/helpers/load-i3s.d.ts +10 -0
  8. package/dist/3d-tiles-converter/helpers/load-i3s.d.ts.map +1 -0
  9. package/dist/3d-tiles-converter/helpers/load-i3s.js +42 -0
  10. package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts +2 -1
  11. package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts.map +1 -1
  12. package/dist/3d-tiles-converter/helpers/texture-atlas.js +2 -0
  13. package/dist/converter.min.js +71 -71
  14. package/dist/deps-installer/deps-installer.d.ts +3 -2
  15. package/dist/deps-installer/deps-installer.d.ts.map +1 -1
  16. package/dist/deps-installer/deps-installer.js +36 -10
  17. package/dist/dist.min.js +824 -3079
  18. package/dist/es5/3d-tiles-converter/3d-tiles-converter.js +94 -81
  19. package/dist/es5/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  20. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js +6 -4
  21. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  22. package/dist/es5/3d-tiles-converter/helpers/load-i3s.js +63 -0
  23. package/dist/es5/3d-tiles-converter/helpers/load-i3s.js.map +1 -0
  24. package/dist/es5/3d-tiles-converter/helpers/texture-atlas.js.map +1 -1
  25. package/dist/es5/deps-installer/deps-installer.js +112 -38
  26. package/dist/es5/deps-installer/deps-installer.js.map +1 -1
  27. package/dist/es5/i3s-converter/helpers/geometry-converter.js +12 -9
  28. package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
  29. package/dist/es5/i3s-converter/i3s-converter.js +32 -87
  30. package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
  31. package/dist/es5/lib/utils/lod-conversion-utils.js +10 -4
  32. package/dist/es5/lib/utils/lod-conversion-utils.js.map +1 -1
  33. package/dist/es5/pgm-loader.js +1 -1
  34. package/dist/esm/3d-tiles-converter/3d-tiles-converter.js +46 -43
  35. package/dist/esm/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  36. package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js +4 -3
  37. package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  38. package/dist/esm/3d-tiles-converter/helpers/load-i3s.js +32 -0
  39. package/dist/esm/3d-tiles-converter/helpers/load-i3s.js.map +1 -0
  40. package/dist/esm/3d-tiles-converter/helpers/texture-atlas.js.map +1 -1
  41. package/dist/esm/deps-installer/deps-installer.js +37 -11
  42. package/dist/esm/deps-installer/deps-installer.js.map +1 -1
  43. package/dist/esm/i3s-converter/helpers/geometry-converter.js +10 -6
  44. package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
  45. package/dist/esm/i3s-converter/i3s-converter.js +11 -28
  46. package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
  47. package/dist/esm/i3s-server/bin/i3s-server.min.js +72 -72
  48. package/dist/esm/lib/utils/lod-conversion-utils.js +6 -4
  49. package/dist/esm/lib/utils/lod-conversion-utils.js.map +1 -1
  50. package/dist/esm/pgm-loader.js +1 -1
  51. package/dist/i3s-converter/helpers/geometry-converter.d.ts +2 -4
  52. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
  53. package/dist/i3s-converter/helpers/geometry-converter.js +18 -13
  54. package/dist/i3s-converter/i3s-converter.d.ts +0 -1
  55. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  56. package/dist/i3s-converter/i3s-converter.js +10 -22
  57. package/dist/lib/utils/lod-conversion-utils.d.ts +2 -2
  58. package/dist/lib/utils/lod-conversion-utils.d.ts.map +1 -1
  59. package/dist/lib/utils/lod-conversion-utils.js +4 -4
  60. package/dist/slpk-extractor.min.js +38 -38
  61. package/package.json +14 -14
  62. package/src/3d-tiles-converter/3d-tiles-converter.ts +60 -46
  63. package/src/3d-tiles-converter/helpers/b3dm-converter.ts +11 -10
  64. package/src/3d-tiles-converter/helpers/load-i3s.ts +51 -0
  65. package/src/3d-tiles-converter/helpers/texture-atlas.ts +6 -2
  66. package/src/deps-installer/deps-installer.ts +55 -10
  67. package/src/i3s-converter/helpers/geometry-converter.ts +19 -14
  68. package/src/i3s-converter/i3s-converter.ts +12 -28
  69. 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.17",
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.17",
49
- "@loaders.gl/crypto": "4.0.0-alpha.17",
50
- "@loaders.gl/draco": "4.0.0-alpha.17",
51
- "@loaders.gl/gltf": "4.0.0-alpha.17",
52
- "@loaders.gl/i3s": "4.0.0-alpha.17",
53
- "@loaders.gl/images": "4.0.0-alpha.17",
54
- "@loaders.gl/loader-utils": "4.0.0-alpha.17",
55
- "@loaders.gl/polyfills": "4.0.0-alpha.17",
56
- "@loaders.gl/textures": "4.0.0-alpha.17",
57
- "@loaders.gl/tiles": "4.0.0-alpha.17",
58
- "@loaders.gl/worker-utils": "4.0.0-alpha.17",
59
- "@loaders.gl/zip": "4.0.0-alpha.17",
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": "68a743e2460cc89bf89edabfd08b395380d7d10c",
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 {AttributeStorageInfo, FeatureAttribute, NodeReference} from '@loaders.gl/i3s';
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: Tileset3D | null;
35
- attributeStorageInfo: AttributeStorageInfo | null;
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
- const sourceTilesetJson = await load(inputUrl, I3SLoader, {});
93
+ this.sourceTileset = await load(inputUrl, I3SLoader, this.loaderOptions);
78
94
 
79
- this.sourceTileset = new Tileset3D(sourceTilesetJson, {
80
- loadOptions: {
81
- _nodeWorkers: true,
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
- await this.sourceTileset.tilesetInitializationPromise;
92
- const rootNode = this.sourceTileset.root!;
93
- if (!rootNode.header.obb) {
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 = sourceTilesetJson.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.header.obb, this.geoidHeightModel)
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: Tile3D,
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!._loadTile(sourceChild);
143
- this.vertexCounter += sourceChild.content.vertexCount;
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.header.obb) {
151
- sourceChild.header.obb = createObbFromMbs(sourceChild.header.mbs);
162
+ if (!sourceChild.obb) {
163
+ sourceChild.obb = createObbFromMbs(sourceChild.mbs);
152
164
  }
153
165
 
154
166
  const boundingVolume = {
155
- box: i3sObbTo3dTilesObb(sourceChild.header.obb, this.geoidHeightModel)
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: sourceChild.content,
165
- textureFormat: sourceChild?.header?.textureFormat
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: Tile3D,
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.header.children || []) {
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(parentNode: Tile3D, childNodeInfo: NodeReference): Promise<Tile3D> {
224
+ private async _loadChildNode(
225
+ parentNode: I3STileHeader,
226
+ childNodeInfo: NodeReference
227
+ ): Promise<I3STileHeader> {
213
228
  let header;
214
- if (this.sourceTileset!.tileset.nodePages) {
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!.tileset.nodePagesTile.formTileFromNodePages(
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.sourceTileset!.loadOptions,
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, loader, options);
246
+ header = await load(nodeUrl, I3SLoader, options);
233
247
  }
234
- return new Tile3D(this.sourceTileset!, header, parentNode);
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: Tile3D,
267
- attributeStorageInfo: AttributeStorageInfo
280
+ sourceChild: I3STileHeader,
281
+ attributeStorageInfo: AttributeStorageInfo[]
268
282
  ): Promise<FeatureAttribute> {
269
283
  const promises: any[] = [];
270
- const {attributeUrls} = sourceChild.header;
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: any;
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: Float32Array, uvRegions: Uint16Array): Float32Array {
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: Uint16Array): number[] {
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 = '', workersPath: string = ''): Promise<void> {
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"'); // eslint-disable-line no-console
38
- await this.installWorker('i3s', 'i3s-content-worker-node.js', workersPath);
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"'); // eslint-disable-line no-console
41
- await this.installWorker('draco', 'draco-worker-node.js', workersPath);
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 "Basis Loader worker"'); // eslint-disable-line no-console
44
- await this.installWorker('textures', 'basis-worker-node.js', workersPath);
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 installWorker(module: string, name: string, extraPath: string) {
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(), extraPath, 'modules', module, 'dist');
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 workerSource - source code of used workers
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
- workerSource: {[key: string]: string}
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
- workerSource
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 params.workerSource - source code of used workers
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
- workerSource
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
- workerSource: {[key: string]: string};
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
- workerSource.draco
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 {Number} vertexCount
1455
- * @param {Object} convertedAttributes - get rid of this argument here
1456
- * @param {Object} attributes - geometry attributes to compress
1457
- * @param {string} dracoWorkerSoure - draco worker source code
1458
- * @returns {Promise<object>} - COmpressed geometry.
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
- dracoWorkerSoure: string
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
  }