@loaders.gl/tile-converter 4.0.0-alpha.4 → 4.0.0-alpha.5

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 (134) hide show
  1. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +78 -0
  2. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -0
  3. package/dist/3d-tiles-converter/3d-tiles-converter.js +9 -7
  4. package/dist/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  5. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts +78 -18
  6. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -0
  7. package/dist/3d-tiles-converter/helpers/b3dm-converter.js +19 -9
  8. package/dist/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  9. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.d.ts +4 -7
  10. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.d.ts.map +1 -0
  11. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js.map +1 -1
  12. package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts +9 -0
  13. package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts.map +1 -0
  14. package/dist/3d-tiles-converter/helpers/texture-atlas.js +1 -1
  15. package/dist/3d-tiles-converter/helpers/texture-atlas.js.map +1 -1
  16. package/dist/3d-tiles-converter/json-templates/tileset.d.ts +15 -0
  17. package/dist/3d-tiles-converter/json-templates/tileset.d.ts.map +1 -0
  18. package/dist/3d-tiles-converter/json-templates/tileset.js +12 -9
  19. package/dist/3d-tiles-converter/json-templates/tileset.js.map +1 -1
  20. package/dist/bundle.d.ts +2 -0
  21. package/dist/bundle.d.ts.map +1 -0
  22. package/dist/converter.min.js +22 -22
  23. package/dist/deps-installer/deps-installer.d.ts.map +1 -0
  24. package/dist/deps-installer/deps-installer.js +2 -6
  25. package/dist/deps-installer/deps-installer.js.map +1 -1
  26. package/dist/dist.min.js +86527 -0
  27. package/dist/i3s-converter/helpers/coordinate-converter.d.ts +41 -0
  28. package/dist/i3s-converter/helpers/coordinate-converter.d.ts.map +1 -0
  29. package/dist/i3s-converter/helpers/coordinate-converter.js +35 -3
  30. package/dist/i3s-converter/helpers/coordinate-converter.js.map +1 -1
  31. package/dist/i3s-converter/helpers/create-scene-server-path.d.ts +9 -0
  32. package/dist/i3s-converter/helpers/create-scene-server-path.d.ts.map +1 -0
  33. package/dist/i3s-converter/helpers/create-scene-server-path.js +2 -2
  34. package/dist/i3s-converter/helpers/create-scene-server-path.js.map +1 -1
  35. package/dist/i3s-converter/helpers/geometry-attributes.d.ts +23 -0
  36. package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -0
  37. package/dist/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  38. package/dist/i3s-converter/helpers/geometry-converter.d.ts +5 -1
  39. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -0
  40. package/dist/i3s-converter/helpers/geometry-converter.js +88 -42
  41. package/dist/i3s-converter/helpers/geometry-converter.js.map +1 -1
  42. package/dist/i3s-converter/helpers/node-debug.d.ts +2 -0
  43. package/dist/i3s-converter/helpers/node-debug.d.ts.map +1 -0
  44. package/dist/i3s-converter/helpers/node-debug.js +2 -4
  45. package/dist/i3s-converter/helpers/node-debug.js.map +1 -1
  46. package/dist/i3s-converter/helpers/node-pages.d.ts +83 -111
  47. package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -0
  48. package/dist/i3s-converter/helpers/node-pages.js +15 -4
  49. package/dist/i3s-converter/helpers/node-pages.js.map +1 -1
  50. package/dist/i3s-converter/i3s-converter.d.ts +320 -0
  51. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -0
  52. package/dist/i3s-converter/i3s-converter.js +158 -65
  53. package/dist/i3s-converter/i3s-converter.js.map +1 -1
  54. package/dist/i3s-converter/json-templates/layers.d.ts +95 -0
  55. package/dist/i3s-converter/json-templates/layers.d.ts.map +1 -0
  56. package/dist/i3s-converter/json-templates/layers.js +37 -27
  57. package/dist/i3s-converter/json-templates/layers.js.map +1 -1
  58. package/dist/i3s-converter/json-templates/metadata.d.ts +22 -0
  59. package/dist/i3s-converter/json-templates/metadata.d.ts.map +1 -0
  60. package/dist/i3s-converter/json-templates/metadata.js +2 -2
  61. package/dist/i3s-converter/json-templates/metadata.js.map +1 -1
  62. package/dist/i3s-converter/json-templates/node.d.ts +61 -0
  63. package/dist/i3s-converter/json-templates/node.d.ts.map +1 -0
  64. package/dist/i3s-converter/json-templates/node.js +16 -12
  65. package/dist/i3s-converter/json-templates/node.js.map +1 -1
  66. package/dist/i3s-converter/json-templates/scene-server.d.ts +28 -0
  67. package/dist/i3s-converter/json-templates/scene-server.d.ts.map +1 -0
  68. package/dist/i3s-converter/json-templates/scene-server.js +2 -2
  69. package/dist/i3s-converter/json-templates/scene-server.js.map +1 -1
  70. package/dist/i3s-converter/json-templates/shared-resources.d.ts +14 -0
  71. package/dist/i3s-converter/json-templates/shared-resources.d.ts.map +1 -0
  72. package/dist/i3s-converter/json-templates/shared-resources.js +19 -14
  73. package/dist/i3s-converter/json-templates/shared-resources.js.map +1 -1
  74. package/dist/i3s-converter/json-templates/store.d.ts +95 -0
  75. package/dist/i3s-converter/json-templates/store.d.ts.map +1 -0
  76. package/dist/i3s-converter/json-templates/store.js.map +1 -1
  77. package/dist/i3s-converter/types.d.ts +14 -0
  78. package/dist/i3s-converter/types.d.ts.map +1 -0
  79. package/dist/i3s-converter/types.js +2 -0
  80. package/dist/i3s-converter/types.js.map +1 -0
  81. package/dist/i3s-server/app.d.ts +3 -0
  82. package/dist/i3s-server/app.d.ts.map +1 -0
  83. package/dist/i3s-server/controllers/index-controller.d.ts +2 -0
  84. package/dist/i3s-server/controllers/index-controller.d.ts.map +1 -0
  85. package/dist/i3s-server/routes/index.d.ts +3 -0
  86. package/dist/i3s-server/routes/index.d.ts.map +1 -0
  87. package/dist/index.d.ts +5 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/lib/utils/{compress-utils.d.ts → compress-util.d.ts} +0 -0
  90. package/dist/lib/utils/compress-util.d.ts.map +1 -0
  91. package/dist/lib/utils/file-utils.d.ts.map +1 -0
  92. package/dist/lib/utils/lod-conversion-utils.d.ts.map +1 -0
  93. package/dist/lib/utils/statistic-utills.d.ts.map +1 -0
  94. package/dist/pgm-loader.d.ts +6 -0
  95. package/dist/pgm-loader.d.ts.map +1 -0
  96. package/dist/pgm-loader.js +3 -3
  97. package/dist/pgm-loader.js.map +1 -1
  98. package/package.json +21 -19
  99. package/src/3d-tiles-converter/3d-tiles-converter.ts +25 -21
  100. package/src/3d-tiles-converter/helpers/{b3dm-converter.js → b3dm-converter.ts} +35 -11
  101. package/src/3d-tiles-converter/helpers/{i3s-obb-to-3d-tiles-obb.js → i3s-obb-to-3d-tiles-obb.ts} +16 -1
  102. package/src/3d-tiles-converter/helpers/texture-atlas.ts +4 -4
  103. package/src/3d-tiles-converter/json-templates/{tileset.js → tileset.ts} +9 -9
  104. package/src/deps-installer/deps-installer.js +2 -2
  105. package/src/i3s-converter/helpers/coordinate-converter.ts +62 -9
  106. package/src/i3s-converter/helpers/{create-scene-server-path.js → create-scene-server-path.ts} +2 -2
  107. package/src/i3s-converter/helpers/{geometry-attributes.js → geometry-attributes.ts} +4 -4
  108. package/src/i3s-converter/helpers/geometry-converter.d.ts +5 -1
  109. package/src/i3s-converter/helpers/geometry-converter.js +110 -33
  110. package/src/i3s-converter/helpers/{node-debug.js → node-debug.ts} +3 -2
  111. package/src/i3s-converter/helpers/{node-pages.js → node-pages.ts} +41 -26
  112. package/src/i3s-converter/i3s-converter.ts +214 -136
  113. package/src/i3s-converter/json-templates/{layers.js → layers.ts} +29 -27
  114. package/src/i3s-converter/json-templates/{metadata.js → metadata.ts} +2 -2
  115. package/src/i3s-converter/json-templates/{node.js → node.ts} +12 -12
  116. package/src/i3s-converter/json-templates/{scene-server.js → scene-server.ts} +2 -2
  117. package/src/i3s-converter/json-templates/{shared-resources.js → shared-resources.ts} +14 -14
  118. package/src/i3s-converter/json-templates/{store.js → store.ts} +0 -0
  119. package/src/i3s-converter/types.ts +14 -0
  120. package/src/lib/utils/{compress-utils.d.ts → compress-util.d.ts} +0 -0
  121. package/src/pgm-loader.ts +2 -2
  122. package/dist/lib/geoid-height-model.d.ts +0 -41
  123. package/dist/lib/geoid-height-model.js +0 -140
  124. package/dist/lib/geoid-height-model.js.map +0 -1
  125. package/dist/lib/pgm-parser.d.ts +0 -14
  126. package/dist/lib/pgm-parser.js +0 -183
  127. package/dist/lib/pgm-parser.js.map +0 -1
  128. package/src/3d-tiles-converter/helpers/b3dm-converter.d.ts +0 -23
  129. package/src/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.d.ts +0 -16
  130. package/src/i3s-converter/helpers/node-pages.d.ts +0 -144
  131. package/src/lib/geoid-height-model.d.ts +0 -41
  132. package/src/lib/geoid-height-model.js +0 -239
  133. package/src/lib/pgm-parser.d.ts +0 -14
  134. package/src/lib/pgm-parser.js +0 -179
@@ -1,4 +1,5 @@
1
1
  import {Vector3, Matrix4} from '@math.gl/core';
2
+ import {GeoidHeightModel} from '../../lib/geoid-height-model';
2
3
  /**
3
4
  * Convert binary data from b3dm file to i3s resources
4
5
  *
@@ -25,7 +26,9 @@ export default function convertB3dmToI3sGeometry(
25
26
  nodeId: number,
26
27
  featuresHashArray: any,
27
28
  attributeStorageInfo: any,
28
- draco: boolean
29
+ draco: boolean,
30
+ generateBoundingVolumes: boolean,
31
+ geoidHeightModel: GeoidHeightModel
29
32
  ): Promise<
30
33
  {
31
34
  geometry: ArrayBuffer;
@@ -36,5 +39,6 @@ export default function convertB3dmToI3sGeometry(
36
39
  vertexCount: number;
37
40
  attributes: any;
38
41
  featureCount: number;
42
+ boundingVolumes: any;
39
43
  }[]
40
44
  >;
@@ -6,6 +6,7 @@ import {encode, assert} from '@loaders.gl/core';
6
6
  import {concatenateArrayBuffers, concatenateTypedArrays} from '@loaders.gl/loader-utils';
7
7
  import md5 from 'md5';
8
8
  import {generateAttributes} from './geometry-attributes';
9
+ import {createBoundingVolumesFromGeometry} from './coordinate-converter';
9
10
 
10
11
  const VALUES_PER_VERTEX = 3;
11
12
  const VALUES_PER_TEX_COORD = 2;
@@ -22,15 +23,24 @@ const OBJECT_ID_TYPE = 'Oid32';
22
23
  */
23
24
  const BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES = ['CUSTOM_ATTRIBUTE_2', '_BATCHID', 'BATCHID'];
24
25
 
26
+ let scratchVector = new Vector3();
27
+
25
28
  export default async function convertB3dmToI3sGeometry(
26
29
  tileContent,
27
30
  nodeId,
28
31
  featuresHashArray,
29
32
  attributeStorageInfo,
30
- draco
33
+ draco,
34
+ generateBoundingVolumes,
35
+ geoidHeightModel
31
36
  ) {
37
+ const useCartesianPositions = generateBoundingVolumes;
32
38
  const materialAndTextureList = convertMaterials(tileContent);
33
- const convertedAttributesMap = convertAttributes(tileContent);
39
+ const convertedAttributesMap = convertAttributes(tileContent, useCartesianPositions);
40
+
41
+ if (generateBoundingVolumes) {
42
+ _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeightModel);
43
+ }
34
44
 
35
45
  if (convertedAttributesMap.has('default')) {
36
46
  materialAndTextureList.push({
@@ -41,7 +51,7 @@ export default async function convertB3dmToI3sGeometry(
41
51
  const result = [];
42
52
  let nodesCounter = nodeId;
43
53
  let {materials = []} = tileContent.gltf;
44
- if (!materials.length === 0) {
54
+ if (!materials?.length) {
45
55
  materials.push({id: 'default'});
46
56
  }
47
57
  for (let i = 0; i < materials.length; i++) {
@@ -72,6 +82,32 @@ export default async function convertB3dmToI3sGeometry(
72
82
  return result;
73
83
  }
74
84
 
85
+ /**
86
+ * Create bounding volumes based on positions
87
+ * @param convertedAttributesMap
88
+ * @param geoidHeightModel
89
+ */
90
+ function _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeightModel) {
91
+ for (const attributes of convertedAttributesMap.values()) {
92
+ const boundingVolumes = createBoundingVolumesFromGeometry(
93
+ attributes.positions,
94
+ geoidHeightModel
95
+ );
96
+
97
+ attributes.boundingVolumes = boundingVolumes;
98
+ const cartographicOrigin = boundingVolumes.obb.center;
99
+
100
+ for (let index = 0; index < attributes.positions.length; index += VALUES_PER_VERTEX) {
101
+ const vertex = attributes.positions.subarray(index, index + VALUES_PER_VERTEX);
102
+ Ellipsoid.WGS84.cartesianToCartographic(Array.from(vertex), scratchVector);
103
+ scratchVector[2] =
104
+ scratchVector[2] - geoidHeightModel.getHeight(scratchVector[1], scratchVector[0]);
105
+ scratchVector = scratchVector.subtract(cartographicOrigin);
106
+ attributes.positions.set(scratchVector, index);
107
+ }
108
+ }
109
+ }
110
+
75
111
  async function _makeNodeResources({
76
112
  convertedAttributes,
77
113
  material,
@@ -82,6 +118,7 @@ async function _makeNodeResources({
82
118
  attributeStorageInfo,
83
119
  draco
84
120
  }) {
121
+ const boundingVolumes = convertedAttributes.boundingVolumes;
85
122
  const vertexCount = convertedAttributes.positions.length / VALUES_PER_VERTEX;
86
123
  const triangleCount = vertexCount / 3;
87
124
  const {faceRange, featureIds, positions, normals, colors, texCoords, featureCount} =
@@ -136,7 +173,8 @@ async function _makeNodeResources({
136
173
  meshMaterial: material,
137
174
  vertexCount,
138
175
  attributes,
139
- featureCount
176
+ featureCount,
177
+ boundingVolumes
140
178
  };
141
179
  }
142
180
 
@@ -152,7 +190,7 @@ async function _makeNodeResources({
152
190
  * }>
153
191
  * @todo implement colors support (if applicable for gltf format)
154
192
  */
155
- function convertAttributes(tileContent) {
193
+ function convertAttributes(tileContent, useCartesianPositions) {
156
194
  const attributesMap = new Map();
157
195
 
158
196
  for (const material of tileContent.gltf.materials || [{id: 'default'}]) {
@@ -161,12 +199,13 @@ function convertAttributes(tileContent) {
161
199
  normals: new Float32Array(0),
162
200
  texCoords: new Float32Array(0),
163
201
  colors: new Uint8Array(0),
164
- featureIndices: []
202
+ featureIndices: [],
203
+ boundingVolumes: null
165
204
  });
166
205
  }
167
206
 
168
207
  const nodes = (tileContent.gltf.scene || tileContent.gltf.scenes?.[0] || tileContent.gltf).nodes;
169
- convertNodes(nodes, tileContent, attributesMap);
208
+ convertNodes(nodes, tileContent, attributesMap, useCartesianPositions);
170
209
 
171
210
  for (const attrKey of attributesMap.keys()) {
172
211
  const attributes = attributesMap.get(attrKey);
@@ -174,19 +213,6 @@ function convertAttributes(tileContent) {
174
213
  attributesMap.delete(attrKey);
175
214
  continue; // eslint-disable-line no-continue
176
215
  }
177
- const vertexCount = attributes.positions.length / VALUES_PER_VERTEX;
178
- if (!attributes.colors.length) {
179
- attributes.colors = new Uint8Array(vertexCount * VALUES_PER_COLOR_ELEMENT);
180
- for (let index = 0; index < attributes.colors.length; index += 4) {
181
- attributes.colors.set([255, 255, 255, 255], index);
182
- }
183
- }
184
- if (!attributes.texCoords.length) {
185
- attributes.texCoords = new Float32Array(vertexCount * VALUES_PER_TEX_COORD);
186
- for (let index = 0; index < attributes.texCoords.length; index += 2) {
187
- attributes.texCoords.set([1, 1], index);
188
- }
189
- }
190
216
  attributes.featureIndices = attributes.featureIndices.reduce((acc, value) => acc.concat(value));
191
217
  }
192
218
 
@@ -207,15 +233,46 @@ function convertNodes(
207
233
  nodes,
208
234
  tileContent,
209
235
  attributesMap,
236
+ useCartesianPositions,
210
237
  matrix = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
211
238
  ) {
212
239
  if (nodes) {
213
240
  for (const node of nodes) {
214
- convertNode(node, tileContent, attributesMap, matrix);
241
+ convertNode(node, tileContent, attributesMap, useCartesianPositions, matrix);
215
242
  }
216
243
  }
217
244
  }
218
245
 
246
+ /**
247
+ * Generate transformation matrix for node
248
+ * Aapply all gltf transformations to initial transformation matrix.
249
+ * @param node
250
+ * @param matrix
251
+ */
252
+ function getCompositeTransformationMatrix(node, matrix) {
253
+ let transformationMatrix = matrix;
254
+
255
+ const {matrix: nodeMatrix, rotation, scale, translation} = node;
256
+
257
+ if (nodeMatrix) {
258
+ transformationMatrix = matrix.multiplyRight(nodeMatrix);
259
+ }
260
+
261
+ if (rotation) {
262
+ transformationMatrix = transformationMatrix.rotateXYZ(rotation);
263
+ }
264
+
265
+ if (scale) {
266
+ transformationMatrix = transformationMatrix.scale(scale);
267
+ }
268
+
269
+ if (translation) {
270
+ transformationMatrix = transformationMatrix.translate(translation);
271
+ }
272
+
273
+ return transformationMatrix;
274
+ }
275
+
219
276
  /**
220
277
  * Convert all primitives of node and all children nodes
221
278
  * @param {Object} node - gltf node
@@ -229,17 +286,23 @@ function convertNode(
229
286
  node,
230
287
  tileContent,
231
288
  attributesMap,
289
+ useCartesianPositions,
232
290
  matrix = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
233
291
  ) {
234
- const nodeMatrix = node.matrix;
235
- const compositeMatrix = nodeMatrix ? matrix.multiplyRight(nodeMatrix) : matrix;
292
+ const transformationMatrix = getCompositeTransformationMatrix(node, matrix);
236
293
 
237
294
  const mesh = node.mesh;
238
295
  if (mesh) {
239
- convertMesh(mesh, tileContent, attributesMap, compositeMatrix);
296
+ convertMesh(mesh, tileContent, attributesMap, useCartesianPositions, transformationMatrix);
240
297
  }
241
298
 
242
- convertNodes(node.children, tileContent, attributesMap, compositeMatrix);
299
+ convertNodes(
300
+ node.children,
301
+ tileContent,
302
+ attributesMap,
303
+ useCartesianPositions,
304
+ transformationMatrix
305
+ );
243
306
  }
244
307
 
245
308
  /**
@@ -255,6 +318,7 @@ function convertMesh(
255
318
  mesh,
256
319
  content,
257
320
  attributesMap,
321
+ useCartesianPositions = false,
258
322
  matrix = new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
259
323
  ) {
260
324
  for (const primitive of mesh.primitives) {
@@ -275,7 +339,8 @@ function convertMesh(
275
339
  cartesianModelMatrix: content.cartesianModelMatrix,
276
340
  nodeMatrix: matrix,
277
341
  indices: primitive.indices.value,
278
- attributeSpecificTransformation: transformVertexPositions
342
+ attributeSpecificTransformation: transformVertexPositions,
343
+ useCartesianPositions
279
344
  })
280
345
  );
281
346
  outputAttributes.normals = concatenateTypedArrays(
@@ -286,7 +351,8 @@ function convertMesh(
286
351
  cartesianModelMatrix: content.cartesianModelMatrix,
287
352
  nodeMatrix: matrix,
288
353
  indices: primitive.indices.value,
289
- attributeSpecificTransformation: transformVertexNormals
354
+ attributeSpecificTransformation: transformVertexNormals,
355
+ useCartesianPositions: false
290
356
  })
291
357
  );
292
358
  outputAttributes.texCoords = concatenateTypedArrays(
@@ -317,6 +383,7 @@ function convertMesh(
317
383
  * @param {Matrix4} args.nodeMatrix - a gltf node transformation matrix - cumulative transformation matrix formed from all parent node matrices
318
384
  * @param {Uint8Array} args.indices - gltf primitive indices
319
385
  * @param {Function} args.attributeSpecificTransformation - function to do attribute - specific transformations
386
+ * @param {Boolean} args.useCartesianPositions - use coordinates as it is.
320
387
  * @returns {Float32Array}
321
388
  */
322
389
  function transformVertexArray(args) {
@@ -340,13 +407,18 @@ function transformVertexArray(args) {
340
407
  }
341
408
 
342
409
  function transformVertexPositions(vertexVector, calleeArgs) {
343
- const {cartesianModelMatrix, cartographicOrigin, nodeMatrix} = calleeArgs;
410
+ const {cartesianModelMatrix, cartographicOrigin, nodeMatrix, useCartesianPositions} = calleeArgs;
344
411
 
345
412
  if (nodeMatrix) {
346
413
  vertexVector = vertexVector.transform(nodeMatrix);
347
414
  }
348
415
 
349
416
  vertexVector = vertexVector.transform(cartesianModelMatrix);
417
+
418
+ if (useCartesianPositions) {
419
+ return vertexVector;
420
+ }
421
+
350
422
  Ellipsoid.WGS84.cartesianToCartographic(
351
423
  [vertexVector[0], vertexVector[1], vertexVector[2]],
352
424
  vertexVector
@@ -373,10 +445,13 @@ function transformVertexNormals(vertexVector, calleeArgs) {
373
445
  * @returns {Float32Array}
374
446
  */
375
447
  function flattenTexCoords(texCoords, indices) {
448
+ const newTexCoords = new Float32Array(indices.length * VALUES_PER_TEX_COORD);
376
449
  if (!texCoords) {
377
- return new Float32Array(0);
450
+ // We need dummy UV0s because it is required in 1.6
451
+ // https://github.com/Esri/i3s-spec/blob/master/docs/1.6/vertexAttribute.cmn.md
452
+ newTexCoords.fill(1);
453
+ return newTexCoords;
378
454
  }
379
- const newTexCoords = new Float32Array(indices.length * VALUES_PER_TEX_COORD);
380
455
  for (let i = 0; i < indices.length; i++) {
381
456
  const coordIndex = indices[i] * VALUES_PER_TEX_COORD;
382
457
  const texCoord = texCoords.subarray(coordIndex, coordIndex + VALUES_PER_TEX_COORD);
@@ -393,12 +468,14 @@ function flattenTexCoords(texCoords, indices) {
393
468
  * @returns {Uint8Array}
394
469
  */
395
470
  function flattenColors(colorsAttribute, indices) {
471
+ const components = colorsAttribute?.components || VALUES_PER_COLOR_ELEMENT;
472
+ const newColors = new Uint8Array(indices.length * components);
396
473
  if (!colorsAttribute) {
397
- return new Uint8Array(0);
474
+ // Vertex color multiplies by material color so it must be normalized 1 by default
475
+ newColors.fill(255);
476
+ return newColors;
398
477
  }
399
- const components = colorsAttribute.components;
400
478
  const colors = colorsAttribute.value;
401
- const newColors = new Uint8Array(indices.length * components);
402
479
  for (let i = 0; i < indices.length; i++) {
403
480
  const colorIndex = indices[i] * components;
404
481
  const color = colors.subarray(colorIndex, colorIndex + components);
@@ -6,7 +6,7 @@ import {Ellipsoid} from '@math.gl/geospatial';
6
6
  // TODO Unite Tile validation logic in i3s-17-and-debug with this code.
7
7
  export function validateNodeBoundingVolumes(node) {
8
8
  if (!node.parentNode.obb || !node.parentNode.mbs) {
9
- return null;
9
+ return [];
10
10
  }
11
11
  const tileWarnings = [];
12
12
 
@@ -53,7 +53,7 @@ function createBoundingBoxFromTileObb(obb) {
53
53
  function getTileObbVertices(node) {
54
54
  const geometry = new CubeGeometry();
55
55
  const halfSize = node.obb.halfSize;
56
- const {attributes} = geometry;
56
+ const attributes = geometry.getAttributes();
57
57
  const positions = new Float32Array(attributes.POSITION.value);
58
58
  const obbCenterCartesian = Ellipsoid.WGS84.cartographicToCartesian(node.obb.center);
59
59
 
@@ -68,6 +68,7 @@ function getTileObbVertices(node) {
68
68
  const rotatedPositions = positionsVector
69
69
  .transformByQuaternion(node.obb.quaternion)
70
70
  .add(obbCenterCartesian);
71
+ // @ts-expect-error
71
72
  vertices = vertices.concat(rotatedPositions);
72
73
  }
73
74
 
@@ -1,7 +1,9 @@
1
1
  import {join} from 'path';
2
2
  import transform from 'json-map-transform';
3
3
  import {METADATA as metadataTemplate} from '../json-templates/metadata';
4
+ import {NodeInPage} from '@loaders.gl/i3s';
4
5
 
6
+ // @ts-nocheck
5
7
  /**
6
8
  * class NodePages - wrapper of nodePages array
7
9
  *
@@ -35,6 +37,11 @@ import {METADATA as metadataTemplate} from '../json-templates/metadata';
35
37
  * await this.nodePages.save(layers0path);
36
38
  */
37
39
  export default class NodePages {
40
+ readonly nodesPerPage: number;
41
+ nodesCounter: number;
42
+ writeFile: Function;
43
+ readonly nodePages: {nodes: NodeInPage[]}[];
44
+
38
45
  /**
39
46
  * @constructs
40
47
  * Create a nodePages instance.
@@ -44,21 +51,26 @@ export default class NodePages {
44
51
  constructor(writeFileFunc, nodesPerPage) {
45
52
  this.nodesPerPage = nodesPerPage;
46
53
  this.nodesCounter = 0;
54
+ // @ts-expect-error
47
55
  this.nodePages = [{}];
48
56
  this.nodePages[0].nodes = [];
49
57
  this.writeFile = writeFileFunc;
50
58
  }
51
59
 
52
- useWriteFunction(func) {
60
+ /**
61
+ * Setup function to save node pages
62
+ * @param func - function which should be used to save node pages
63
+ */
64
+ useWriteFunction(func: Function): void {
53
65
  this.writeFile = func;
54
66
  }
55
67
 
56
68
  /**
57
69
  * Get the node by its end-to-end index
58
- * @param {number} id - end-to-end index of the node
59
- * @return {object} the node object
70
+ * @param id - end-to-end index of the node
71
+ * @return the node object
60
72
  */
61
- getNodeById(id) {
73
+ getNodeById(id: number): NodeInPage {
62
74
  const pageIndex = Math.floor(id / this.nodesPerPage);
63
75
  const nodeIndex = id % this.nodesPerPage;
64
76
  return this.nodePages[pageIndex].nodes[nodeIndex];
@@ -69,7 +81,7 @@ export default class NodePages {
69
81
  * @param id - end-to-end index of the node
70
82
  * @param materialId - id from scene layer materialDefinitions
71
83
  */
72
- updateMaterialByNodeId(id, materialId) {
84
+ updateMaterialByNodeId(id: number, materialId: number): void {
73
85
  const node = this.getNodeById(id);
74
86
  if (!node.mesh) {
75
87
  return;
@@ -85,7 +97,7 @@ export default class NodePages {
85
97
  * @param id - end-to-end index of the node
86
98
  * @param vertexCount - vertex count for particular node
87
99
  */
88
- updateVertexCountByNodeId(id, vertexCount) {
100
+ updateVertexCountByNodeId(id: number, vertexCount: number): void {
89
101
  const node = this.getNodeById(id);
90
102
  if (!node.mesh) {
91
103
  return;
@@ -97,7 +109,7 @@ export default class NodePages {
97
109
  * Update resource in node.mesh.attribute object by node id
98
110
  * @param id - end-to-end index of the node
99
111
  */
100
- updateNodeAttributeByNodeId(id) {
112
+ updateNodeAttributeByNodeId(id: number): void {
101
113
  const node = this.getNodeById(id);
102
114
  if (!node.mesh) {
103
115
  return;
@@ -110,7 +122,7 @@ export default class NodePages {
110
122
  * @param id - end-to-end index of the node
111
123
  * @param featureCount - features count of the node
112
124
  */
113
- updateFeatureCountByNodeId(id, featureCount) {
125
+ updateFeatureCountByNodeId(id: number, featureCount: number): void {
114
126
  const node = this.getNodeById(id);
115
127
  if (!node.mesh) {
116
128
  return;
@@ -118,7 +130,12 @@ export default class NodePages {
118
130
  node.mesh.geometry.featureCount = featureCount;
119
131
  }
120
132
 
121
- updateTexelCountHintByNodeId(id, texelCountHint) {
133
+ /**
134
+ * Update texelCountHint in node.mesh.material object by node id
135
+ * @param id - end-to-end index of the node
136
+ * @param texelCountHint - texelCountHint of particular node
137
+ */
138
+ updateTexelCountHintByNodeId(id: number, texelCountHint: number): void {
122
139
  const node = this.getNodeById(id);
123
140
  if (!node.mesh || !node.mesh.material) {
124
141
  return;
@@ -128,24 +145,22 @@ export default class NodePages {
128
145
 
129
146
  /**
130
147
  * Add a child id into the parent node.children array
131
- * @param {number | null} parentId - end-to-end parent node index
132
- * @param {number} childId - end-to-end child node index
133
- * @return {void}
148
+ * @param parentId - end-to-end parent node index
149
+ * @param childId - end-to-end child node index
134
150
  */
135
- addChildRelation(parentId, childId) {
136
- if (parentId === null) {
151
+ addChildRelation(parentId: number | undefined, childId: number): void {
152
+ if (parentId === null || parentId === undefined) {
137
153
  return;
138
154
  }
139
155
  const parentNode = this.getNodeById(parentId);
140
- parentNode.children.push(childId);
156
+ parentNode.children?.push(childId);
141
157
  }
142
158
 
143
159
  /**
144
160
  * Update resource index in node.mesh object
145
- * @param {object} node - node object
146
- * @return {void}
161
+ * @param node - node object
147
162
  */
148
- updateResourceInMesh(node) {
163
+ updateResourceInMesh(node: NodeInPage): void {
149
164
  if (node.mesh) {
150
165
  node.mesh.geometry.resource = node.index;
151
166
  }
@@ -153,11 +168,11 @@ export default class NodePages {
153
168
 
154
169
  /**
155
170
  * Put new node in nodePages array
156
- * @param {object} node - node object
157
- * @param {number | null} parentId - index of parent node
158
- * @return {number}
171
+ * @param node - node object
172
+ * @param parentId - index of parent node
173
+ * @return
159
174
  */
160
- push(node, parentId = null) {
175
+ push(node: NodeInPage, parentId?: number): number {
161
176
  let currentNodePage = this.nodePages[this.nodePages.length - 1];
162
177
  if (currentNodePage.nodes.length === this.nodesPerPage) {
163
178
  currentNodePage = {nodes: []};
@@ -174,12 +189,12 @@ export default class NodePages {
174
189
  * Save all the node pages
175
190
  * Run this method when all nodes is pushed in nodePages
176
191
  * @param {string} layers0Path - path of layer
177
- * @param {Object} fileMap
192
+ * @param {Object} fileMap - fileMap which keep info for slpk archive
178
193
  * @param {boolean} slpk
179
194
  * @return {promise}
180
195
  */
181
- async save(layers0Path, fileMap, slpk = false) {
182
- const promises = [];
196
+ async save(layers0Path: string, fileMap: Object, slpk: boolean = false): Promise<void> {
197
+ const promises: Promise<any>[] = [];
183
198
  if (slpk) {
184
199
  for (const [index, nodePage] of this.nodePages.entries()) {
185
200
  const nodePageStr = JSON.stringify(nodePage);
@@ -187,7 +202,7 @@ export default class NodePages {
187
202
  promises.push(this.writeFile(slpkPath, nodePageStr, `${index.toString()}.json`));
188
203
  fileMap[`nodePages/${index.toString()}.json.gz`] = `${slpkPath}.json.gz`;
189
204
  }
190
- const metadata = transform({nodeCount: this.nodesCounter}, metadataTemplate);
205
+ const metadata = transform({nodeCount: this.nodesCounter}, metadataTemplate());
191
206
  const compress = false;
192
207
  fileMap['metadata.json'] = await this.writeFile(
193
208
  layers0Path,