@loaders.gl/tile-converter 3.3.0-alpha.8 → 3.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/dist/3d-tiles-attributes-worker.js +2 -2
  2. package/dist/3d-tiles-attributes-worker.js.map +3 -3
  3. package/dist/converter-cli.js +14 -2
  4. package/dist/converter.min.js +22 -22
  5. package/dist/deps-installer/deps-installer.d.ts.map +1 -1
  6. package/dist/deps-installer/deps-installer.js +8 -0
  7. package/dist/dist.min.js +1167 -848
  8. package/dist/es5/3d-tiles-attributes-worker.js +1 -1
  9. package/dist/es5/3d-tiles-attributes-worker.js.map +1 -1
  10. package/dist/es5/converter-cli.js +14 -2
  11. package/dist/es5/converter-cli.js.map +1 -1
  12. package/dist/es5/deps-installer/deps-installer.js +13 -2
  13. package/dist/es5/deps-installer/deps-installer.js.map +1 -1
  14. package/dist/es5/i3s-attributes-worker.js +1 -1
  15. package/dist/es5/i3s-attributes-worker.js.map +1 -1
  16. package/dist/es5/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  17. package/dist/es5/i3s-converter/helpers/geometry-attributes.js +16 -7
  18. package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  19. package/dist/es5/i3s-converter/helpers/geometry-converter.js +363 -113
  20. package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
  21. package/dist/es5/i3s-converter/helpers/gltf-attributes.js +6 -11
  22. package/dist/es5/i3s-converter/helpers/gltf-attributes.js.map +1 -1
  23. package/dist/es5/i3s-converter/helpers/node-index-document.js +517 -0
  24. package/dist/es5/i3s-converter/helpers/node-index-document.js.map +1 -0
  25. package/dist/es5/i3s-converter/helpers/node-pages.js +455 -173
  26. package/dist/es5/i3s-converter/helpers/node-pages.js.map +1 -1
  27. package/dist/es5/i3s-converter/i3s-converter.js +549 -618
  28. package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
  29. package/dist/es5/i3s-converter/json-templates/geometry-definitions.js +107 -0
  30. package/dist/es5/i3s-converter/json-templates/geometry-definitions.js.map +1 -0
  31. package/dist/es5/i3s-converter/json-templates/layers.js +2 -93
  32. package/dist/es5/i3s-converter/json-templates/layers.js.map +1 -1
  33. package/dist/es5/i3s-converter/json-templates/shared-resources.js +3 -3
  34. package/dist/es5/i3s-converter/json-templates/shared-resources.js.map +1 -1
  35. package/dist/es5/i3s-converter/types.js.map +1 -1
  36. package/dist/es5/lib/utils/file-utils.js +93 -9
  37. package/dist/es5/lib/utils/file-utils.js.map +1 -1
  38. package/dist/es5/lib/utils/write-queue.js +38 -25
  39. package/dist/es5/lib/utils/write-queue.js.map +1 -1
  40. package/dist/es5/pgm-loader.js +1 -1
  41. package/dist/es5/pgm-loader.js.map +1 -1
  42. package/dist/es5/workers/i3s-attributes-worker.js +1 -1
  43. package/dist/es5/workers/i3s-attributes-worker.js.map +1 -1
  44. package/dist/esm/3d-tiles-attributes-worker.js +1 -1
  45. package/dist/esm/3d-tiles-attributes-worker.js.map +1 -1
  46. package/dist/esm/converter-cli.js +14 -2
  47. package/dist/esm/converter-cli.js.map +1 -1
  48. package/dist/esm/deps-installer/deps-installer.js +9 -1
  49. package/dist/esm/deps-installer/deps-installer.js.map +1 -1
  50. package/dist/esm/i3s-attributes-worker.js +1 -1
  51. package/dist/esm/i3s-attributes-worker.js.map +1 -1
  52. package/dist/esm/i3s-converter/helpers/batch-ids-extensions.js.map +1 -1
  53. package/dist/esm/i3s-converter/helpers/geometry-attributes.js +16 -7
  54. package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  55. package/dist/esm/i3s-converter/helpers/geometry-converter.js +150 -40
  56. package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
  57. package/dist/esm/i3s-converter/helpers/gltf-attributes.js +6 -9
  58. package/dist/esm/i3s-converter/helpers/gltf-attributes.js.map +1 -1
  59. package/dist/esm/i3s-converter/helpers/node-index-document.js +202 -0
  60. package/dist/esm/i3s-converter/helpers/node-index-document.js.map +1 -0
  61. package/dist/esm/i3s-converter/helpers/node-pages.js +162 -76
  62. package/dist/esm/i3s-converter/helpers/node-pages.js.map +1 -1
  63. package/dist/esm/i3s-converter/i3s-converter.js +115 -220
  64. package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
  65. package/dist/esm/i3s-converter/json-templates/geometry-definitions.js +89 -0
  66. package/dist/esm/i3s-converter/json-templates/geometry-definitions.js.map +1 -0
  67. package/dist/esm/i3s-converter/json-templates/layers.js +2 -85
  68. package/dist/esm/i3s-converter/json-templates/layers.js.map +1 -1
  69. package/dist/esm/i3s-converter/json-templates/shared-resources.js +3 -3
  70. package/dist/esm/i3s-converter/json-templates/shared-resources.js.map +1 -1
  71. package/dist/esm/i3s-converter/types.js.map +1 -1
  72. package/dist/esm/lib/utils/file-utils.js +44 -3
  73. package/dist/esm/lib/utils/file-utils.js.map +1 -1
  74. package/dist/esm/lib/utils/write-queue.js +19 -10
  75. package/dist/esm/lib/utils/write-queue.js.map +1 -1
  76. package/dist/esm/pgm-loader.js +1 -1
  77. package/dist/esm/pgm-loader.js.map +1 -1
  78. package/dist/esm/workers/i3s-attributes-worker.js +1 -1
  79. package/dist/esm/workers/i3s-attributes-worker.js.map +1 -1
  80. package/dist/i3s-attributes-worker.js +2 -2
  81. package/dist/i3s-attributes-worker.js.map +2 -2
  82. package/dist/i3s-converter/helpers/batch-ids-extensions.d.ts +3 -3
  83. package/dist/i3s-converter/helpers/batch-ids-extensions.js +3 -3
  84. package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
  85. package/dist/i3s-converter/helpers/geometry-attributes.js +16 -10
  86. package/dist/i3s-converter/helpers/geometry-converter.d.ts +8 -4
  87. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
  88. package/dist/i3s-converter/helpers/geometry-converter.js +200 -44
  89. package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -1
  90. package/dist/i3s-converter/helpers/gltf-attributes.js +2 -3
  91. package/dist/i3s-converter/helpers/node-index-document.d.ts +95 -0
  92. package/dist/i3s-converter/helpers/node-index-document.d.ts.map +1 -0
  93. package/dist/i3s-converter/helpers/node-index-document.js +250 -0
  94. package/dist/i3s-converter/helpers/node-pages.d.ts +78 -43
  95. package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -1
  96. package/dist/i3s-converter/helpers/node-pages.js +194 -93
  97. package/dist/i3s-converter/i3s-converter.d.ts +33 -58
  98. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  99. package/dist/i3s-converter/i3s-converter.js +122 -233
  100. package/dist/i3s-converter/json-templates/geometry-definitions.d.ts +7 -0
  101. package/dist/i3s-converter/json-templates/geometry-definitions.d.ts.map +1 -0
  102. package/dist/i3s-converter/json-templates/geometry-definitions.js +87 -0
  103. package/dist/i3s-converter/json-templates/layers.d.ts +1 -30
  104. package/dist/i3s-converter/json-templates/layers.d.ts.map +1 -1
  105. package/dist/i3s-converter/json-templates/layers.js +2 -86
  106. package/dist/i3s-converter/json-templates/shared-resources.js +3 -3
  107. package/dist/i3s-converter/types.d.ts +28 -2
  108. package/dist/i3s-converter/types.d.ts.map +1 -1
  109. package/dist/lib/utils/file-utils.d.ts +17 -1
  110. package/dist/lib/utils/file-utils.d.ts.map +1 -1
  111. package/dist/lib/utils/file-utils.js +64 -7
  112. package/dist/lib/utils/write-queue.d.ts +18 -2
  113. package/dist/lib/utils/write-queue.d.ts.map +1 -1
  114. package/dist/lib/utils/write-queue.js +18 -12
  115. package/dist/workers/i3s-attributes-worker.js +1 -1
  116. package/package.json +25 -20
  117. package/src/converter-cli.ts +22 -2
  118. package/src/deps-installer/deps-installer.ts +9 -0
  119. package/src/i3s-converter/helpers/batch-ids-extensions.ts +3 -3
  120. package/src/i3s-converter/helpers/geometry-attributes.ts +16 -11
  121. package/src/i3s-converter/helpers/geometry-converter.ts +217 -48
  122. package/src/i3s-converter/helpers/gltf-attributes.ts +2 -3
  123. package/src/i3s-converter/helpers/node-index-document.ts +315 -0
  124. package/src/i3s-converter/helpers/node-pages.ts +215 -110
  125. package/src/i3s-converter/i3s-converter.ts +170 -312
  126. package/src/i3s-converter/json-templates/geometry-definitions.ts +83 -0
  127. package/src/i3s-converter/json-templates/layers.ts +2 -91
  128. package/src/i3s-converter/json-templates/shared-resources.ts +3 -3
  129. package/src/i3s-converter/types.ts +29 -2
  130. package/src/lib/utils/file-utils.ts +62 -7
  131. package/src/lib/utils/write-queue.ts +36 -15
  132. package/src/workers/i3s-attributes-worker.ts +2 -1
@@ -4,6 +4,7 @@ import { DracoWriterWorker } from '@loaders.gl/draco';
4
4
  import { assert, encode } from '@loaders.gl/core';
5
5
  import { concatenateArrayBuffers, concatenateTypedArrays } from '@loaders.gl/loader-utils';
6
6
  import md5 from 'md5';
7
+ import { v4 as uuidv4 } from 'uuid';
7
8
  import { generateAttributes } from './geometry-attributes';
8
9
  import { createBoundingVolumesFromGeometry } from './coordinate-converter';
9
10
  import { prepareDataForAttributesConversion } from './gltf-attributes';
@@ -24,47 +25,32 @@ const EXT_FEATURE_METADATA = 'EXT_feature_metadata';
24
25
  const EXT_MESH_FEATURES = 'EXT_mesh_features';
25
26
  let scratchVector = new Vector3();
26
27
 
27
- export default async function convertB3dmToI3sGeometry(tileContent, addNodeToNodePage, propertyTable, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, geoidHeightModel, workerSource) {
28
+ export default async function convertB3dmToI3sGeometry(tileContent, addNodeToNodePage, propertyTable, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, shouldMergeMaterials, geoidHeightModel, workerSource) {
28
29
  var _tileContent$gltf;
29
30
  const useCartesianPositions = generateBoundingVolumes;
30
- const materialAndTextureList = convertMaterials((_tileContent$gltf = tileContent.gltf) === null || _tileContent$gltf === void 0 ? void 0 : _tileContent$gltf.materials);
31
+ const materialAndTextureList = await convertMaterials((_tileContent$gltf = tileContent.gltf) === null || _tileContent$gltf === void 0 ? void 0 : _tileContent$gltf.materials, shouldMergeMaterials);
31
32
  const dataForAttributesConversion = prepareDataForAttributesConversion(tileContent);
32
- const convertedAttributesMap = await convertAttributes(dataForAttributesConversion, useCartesianPositions);
33
+ const convertedAttributesMap = await convertAttributes(dataForAttributesConversion, materialAndTextureList, useCartesianPositions);
33
34
 
34
35
  if (generateBoundingVolumes) {
35
36
  _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeightModel);
36
37
  }
37
- if (convertedAttributesMap.has('default')) {
38
- materialAndTextureList.push({
39
- material: getDefaultMaterial()
40
- });
41
- }
42
38
  const result = [];
43
- let {
44
- materials = []
45
- } = tileContent.gltf || {
46
- materials: []
47
- };
48
- if (!(materials !== null && materials !== void 0 && materials.length)) {
49
- materials.push({
50
- id: 'default'
51
- });
52
- }
53
- for (let i = 0; i < materials.length; i++) {
54
- const sourceMaterial = materials[i];
55
- if (!convertedAttributesMap.has(sourceMaterial.id)) {
39
+ for (const materialAndTexture of materialAndTextureList) {
40
+ const originarMaterialId = materialAndTexture.mergedMaterials[0].originalMaterialId;
41
+ if (!convertedAttributesMap.has(originarMaterialId)) {
56
42
  continue;
57
43
  }
58
44
 
59
- const convertedAttributes = convertedAttributesMap.get(sourceMaterial.id);
45
+ const convertedAttributes = convertedAttributesMap.get(originarMaterialId);
60
46
  if (!convertedAttributes) {
61
47
  continue;
62
48
  }
63
49
  const {
64
50
  material,
65
51
  texture
66
- } = materialAndTextureList[i];
67
- const nodeId = addNodeToNodePage();
52
+ } = materialAndTexture;
53
+ const nodeId = await addNodeToNodePage();
68
54
  result.push(await _makeNodeResources({
69
55
  convertedAttributes,
70
56
  material,
@@ -121,6 +107,7 @@ async function _makeNodeResources(_ref) {
121
107
  positions,
122
108
  normals,
123
109
  colors,
110
+ uvRegions,
124
111
  texCoords,
125
112
  featureCount
126
113
  } = generateAttributes(convertedAttributes);
@@ -130,12 +117,13 @@ async function _makeNodeResources(_ref) {
130
117
  const header = new Uint32Array(2);
131
118
  const typedFeatureIds = generateBigUint64Array(featureIds);
132
119
  header.set([vertexCount, featureCount], 0);
133
- const fileBuffer = new Uint8Array(concatenateArrayBuffers(header.buffer, positions.buffer, normals.buffer, texture ? texCoords.buffer : new ArrayBuffer(0), colors.buffer, typedFeatureIds.buffer, faceRange.buffer));
120
+ const fileBuffer = new Uint8Array(concatenateArrayBuffers(header.buffer, positions.buffer, normals.buffer, texture ? texCoords.buffer : new ArrayBuffer(0), colors.buffer, uvRegions, typedFeatureIds.buffer, faceRange.buffer));
134
121
  const compressedGeometry = draco ? generateCompressedGeometry(vertexCount, convertedAttributes, {
135
122
  positions,
136
123
  normals,
137
124
  texCoords: texture ? texCoords : new Float32Array(0),
138
125
  colors,
126
+ uvRegions,
139
127
  featureIds,
140
128
  faceRange
141
129
  }, workerSource.draco) : null;
@@ -148,6 +136,7 @@ async function _makeNodeResources(_ref) {
148
136
  geometry: fileBuffer,
149
137
  compressedGeometry,
150
138
  texture,
139
+ hasUvRegions: Boolean(uvRegions.length),
151
140
  sharedResources: getSharedResources(((_tileContent$gltf2 = tileContent.gltf) === null || _tileContent$gltf2 === void 0 ? void 0 : _tileContent$gltf2.materials) || [], nodeId),
152
141
  meshMaterial: material,
153
142
  vertexCount,
@@ -157,27 +146,29 @@ async function _makeNodeResources(_ref) {
157
146
  };
158
147
  }
159
148
 
160
- export async function convertAttributes(attributesData, useCartesianPositions) {
149
+ export async function convertAttributes(attributesData, materialAndTextureList, useCartesianPositions) {
161
150
  const {
162
- gltfMaterials,
163
151
  nodes,
164
152
  images,
165
153
  cartographicOrigin,
166
154
  cartesianModelMatrix
167
155
  } = attributesData;
168
156
  const attributesMap = new Map();
169
- for (const material of gltfMaterials || [{
170
- id: 'default'
171
- }]) {
172
- attributesMap.set(material.id, {
157
+ for (const materialAndTexture of materialAndTextureList) {
158
+ const attributes = {
173
159
  positions: new Float32Array(0),
174
160
  normals: new Float32Array(0),
175
161
  texCoords: new Float32Array(0),
176
162
  colors: new Uint8Array(0),
163
+ uvRegions: new Uint16Array(0),
177
164
  featureIndicesGroups: [],
178
165
  featureIndices: [],
179
- boundingVolumes: null
180
- });
166
+ boundingVolumes: null,
167
+ mergedMaterials: materialAndTexture.mergedMaterials
168
+ };
169
+ for (const mergedMaterial of materialAndTexture.mergedMaterials) {
170
+ attributesMap.set(mergedMaterial.originalMaterialId, attributes);
171
+ }
181
172
  }
182
173
  convertNodes(nodes, images, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions);
183
174
  for (const attrKey of attributesMap.keys()) {
@@ -244,10 +235,19 @@ function convertMesh(mesh, images, cartographicOrigin, cartesianModelMatrix, att
244
235
  let useCartesianPositions = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
245
236
  let matrix = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : new Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
246
237
  for (const primitive of mesh.primitives) {
247
- var _primitive$indices, _primitive$indices2, _primitive$indices3, _primitive$indices4, _primitive$indices5;
238
+ var _primitive$indices, _primitive$indices2, _primitive$indices3, _primitive$indices4, _primitive$indices6;
248
239
  let outputAttributes = null;
240
+ let materialUvRegion;
249
241
  if (primitive.material) {
250
- outputAttributes = attributesMap.get(primitive.material.id);
242
+ var _outputAttributes, _outputAttributes$mer;
243
+ outputAttributes = attributesMap.get(primitive.material.uniqueId);
244
+ materialUvRegion = (_outputAttributes = outputAttributes) === null || _outputAttributes === void 0 ? void 0 : (_outputAttributes$mer = _outputAttributes.mergedMaterials.find(_ref2 => {
245
+ var _primitive$material;
246
+ let {
247
+ originalMaterialId
248
+ } = _ref2;
249
+ return originalMaterialId === ((_primitive$material = primitive.material) === null || _primitive$material === void 0 ? void 0 : _primitive$material.uniqueId);
250
+ })) === null || _outputAttributes$mer === void 0 ? void 0 : _outputAttributes$mer.uvRegion;
251
251
  } else if (attributesMap.has('default')) {
252
252
  outputAttributes = attributesMap.get('default');
253
253
  }
@@ -276,8 +276,12 @@ function convertMesh(mesh, images, cartographicOrigin, cartesianModelMatrix, att
276
276
  }));
277
277
  outputAttributes.texCoords = concatenateTypedArrays(outputAttributes.texCoords, flattenTexCoords(attributes.TEXCOORD_0 && attributes.TEXCOORD_0.value, (_primitive$indices3 = primitive.indices) === null || _primitive$indices3 === void 0 ? void 0 : _primitive$indices3.value));
278
278
  outputAttributes.colors = concatenateTypedArrays(outputAttributes.colors, flattenColors(attributes.COLOR_0, (_primitive$indices4 = primitive.indices) === null || _primitive$indices4 === void 0 ? void 0 : _primitive$indices4.value));
279
+ if (materialUvRegion) {
280
+ var _primitive$indices5;
281
+ outputAttributes.uvRegions = concatenateTypedArrays(outputAttributes.uvRegions, createUvRegion(materialUvRegion, (_primitive$indices5 = primitive.indices) === null || _primitive$indices5 === void 0 ? void 0 : _primitive$indices5.value));
282
+ }
279
283
  outputAttributes.featureIndicesGroups = outputAttributes.featureIndicesGroups || [];
280
- outputAttributes.featureIndicesGroups.push(flattenBatchIds(getBatchIds(attributes, primitive, images), (_primitive$indices5 = primitive.indices) === null || _primitive$indices5 === void 0 ? void 0 : _primitive$indices5.value));
284
+ outputAttributes.featureIndicesGroups.push(flattenBatchIds(getBatchIds(attributes, primitive, images), (_primitive$indices6 = primitive.indices) === null || _primitive$indices6 === void 0 ? void 0 : _primitive$indices6.value));
281
285
  }
282
286
  }
283
287
 
@@ -369,6 +373,14 @@ function flattenColors(colorsAttribute, indices) {
369
373
  return newColors;
370
374
  }
371
375
 
376
+ function createUvRegion(materialUvRegion, indices) {
377
+ const result = new Uint16Array(indices.length * 4);
378
+ for (let i = 0; i < result.length; i += 4) {
379
+ result.set(materialUvRegion, i);
380
+ }
381
+ return result;
382
+ }
383
+
372
384
  function flattenBatchIds(batchedIds, indices) {
373
385
  if (!batchedIds.length || !indices.length) {
374
386
  return [];
@@ -395,15 +407,95 @@ function getBatchIds(attributes, primitive, images) {
395
407
  return [];
396
408
  }
397
409
 
398
- function convertMaterials() {
410
+ async function convertMaterials() {
399
411
  let sourceMaterials = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
400
- const result = [];
412
+ let shouldMergeMaterials = arguments.length > 1 ? arguments[1] : undefined;
413
+ let materials = [];
401
414
  for (const sourceMaterial of sourceMaterials) {
402
- result.push(convertMaterial(sourceMaterial));
415
+ materials.push(convertMaterial(sourceMaterial));
416
+ }
417
+ if (shouldMergeMaterials) {
418
+ materials = await mergeAllMaterials(materials);
419
+ }
420
+ return materials;
421
+ }
422
+
423
+ async function mergeAllMaterials(materials) {
424
+ const result = [];
425
+ while (materials.length > 0) {
426
+ let newMaterial = materials.splice(0, 1)[0];
427
+ const mergedIndices = [];
428
+ for (let i = 0; i < materials.length; i++) {
429
+ const material = materials[i];
430
+ if (newMaterial.texture && material.texture || !newMaterial.texture && !material.texture) {
431
+ newMaterial = await mergeMaterials(newMaterial, material);
432
+ mergedIndices.push(i);
433
+ }
434
+ }
435
+ if (newMaterial.texture && mergedIndices.length) {
436
+ var _newMaterial$mergedMa, _newMaterial$mergedMa2;
437
+ const newWidth = (_newMaterial$mergedMa = newMaterial.mergedMaterials) === null || _newMaterial$mergedMa === void 0 ? void 0 : _newMaterial$mergedMa.reduce((accum, _ref3) => {
438
+ let {
439
+ textureSize
440
+ } = _ref3;
441
+ return accum + ((textureSize === null || textureSize === void 0 ? void 0 : textureSize.width) || 0);
442
+ }, 0);
443
+ const newHeight = (_newMaterial$mergedMa2 = newMaterial.mergedMaterials) === null || _newMaterial$mergedMa2 === void 0 ? void 0 : _newMaterial$mergedMa2.reduce((accum, _ref4) => {
444
+ let {
445
+ textureSize
446
+ } = _ref4;
447
+ return Math.max(accum, (textureSize === null || textureSize === void 0 ? void 0 : textureSize.height) || 0);
448
+ }, 0);
449
+ let currentX = -1;
450
+ for (const aTextureMetadata of newMaterial.mergedMaterials) {
451
+ if (aTextureMetadata.textureSize) {
452
+ const newX = currentX + 1 + aTextureMetadata.textureSize.width / newWidth * 2 ** (Uint16Array.BYTES_PER_ELEMENT * 8) - 1;
453
+ aTextureMetadata.uvRegion = new Uint16Array([currentX + 1, 0, newX, aTextureMetadata.textureSize.height / newHeight * 2 ** (Uint16Array.BYTES_PER_ELEMENT * 8) - 1]);
454
+ currentX = newX;
455
+ }
456
+ }
457
+ newMaterial.texture.image.width = newWidth;
458
+ newMaterial.texture.image.height = newHeight;
459
+ }
460
+ for (const index of mergedIndices.reverse()) {
461
+ materials.splice(index, 1);
462
+ }
463
+ result.push(newMaterial);
464
+ }
465
+ if (!result.length) {
466
+ result.push({
467
+ material: getDefaultMaterial(),
468
+ mergedMaterials: [{
469
+ originalMaterialId: 'default'
470
+ }]
471
+ });
403
472
  }
404
473
  return result;
405
474
  }
406
475
 
476
+ async function mergeMaterials(material1, material2) {
477
+ var _material1$texture, _material2$texture;
478
+ if ((_material1$texture = material1.texture) !== null && _material1$texture !== void 0 && _material1$texture.bufferView && (_material2$texture = material2.texture) !== null && _material2$texture !== void 0 && _material2$texture.bufferView && material1.mergedMaterials && material2.mergedMaterials) {
479
+ const buffer1 = Buffer.from(material1.texture.bufferView.data);
480
+ const buffer2 = Buffer.from(material2.texture.bufferView.data);
481
+ try {
482
+ const {
483
+ joinImages
484
+ } = await import('join-images');
485
+ const sharpData = await joinImages([buffer1, buffer2], {
486
+ direction: 'horizontal'
487
+ });
488
+ material1.texture.bufferView.data = await sharpData.toFormat(material1.texture.mimeType === 'image/png' ? 'png' : 'jpeg').toBuffer();
489
+ } catch (error) {
490
+ console.log('Join images into a texture atlas has failed. Consider usage `--split-nodes` option. (See documentation https://loaders.gl/modules/tile-converter/docs/cli-reference/tile-converter)');
491
+ throw error;
492
+ }
493
+ material1.material.pbrMetallicRoughness.baseColorTexture.textureSetDefinitionId = 1;
494
+ }
495
+ material1.mergedMaterials = material1.mergedMaterials.concat(material2.mergedMaterials);
496
+ return material1;
497
+ }
498
+
407
499
  function convertMaterial(sourceMaterial) {
408
500
  var _sourceMaterial$emiss, _sourceMaterial$pbrMe, _sourceMaterial$pbrMe2, _sourceMaterial$pbrMe3;
409
501
  const material = {
@@ -427,14 +519,25 @@ function convertMaterial(sourceMaterial) {
427
519
  textureSetDefinitionId: 0
428
520
  };
429
521
  }
522
+ const uniqueId = uuidv4();
523
+ sourceMaterial.uniqueId = uniqueId;
524
+ let mergedMaterials = [{
525
+ originalMaterialId: uniqueId
526
+ }];
430
527
  if (!texture) {
431
528
  var _sourceMaterial$pbrMe4;
432
529
  const baseColorFactor = sourceMaterial === null || sourceMaterial === void 0 ? void 0 : (_sourceMaterial$pbrMe4 = sourceMaterial.pbrMetallicRoughness) === null || _sourceMaterial$pbrMe4 === void 0 ? void 0 : _sourceMaterial$pbrMe4.baseColorFactor;
433
530
  material.pbrMetallicRoughness.baseColorFactor = baseColorFactor && baseColorFactor.map(c => Math.round(c * 255)) || undefined;
531
+ } else {
532
+ mergedMaterials[0].textureSize = {
533
+ width: texture.image.width,
534
+ height: texture.image.height
535
+ };
434
536
  }
435
537
  return {
436
538
  material,
437
- texture
539
+ texture,
540
+ mergedMaterials
438
541
  };
439
542
  }
440
543
 
@@ -679,6 +782,7 @@ async function generateCompressedGeometry(vertexCount, convertedAttributes, attr
679
782
  normals,
680
783
  texCoords,
681
784
  colors,
785
+ uvRegions,
682
786
  featureIds,
683
787
  faceRange
684
788
  } = attributes;
@@ -703,6 +807,12 @@ async function generateCompressedGeometry(vertexCount, convertedAttributes, attr
703
807
  'i3s-feature-ids': new Int32Array(featureIds)
704
808
  }
705
809
  };
810
+ if (uvRegions.length) {
811
+ compressedAttributes['uv-region'] = uvRegions;
812
+ attributesMetadata['uv-region'] = {
813
+ 'i3s-attribute-type': 'uv-region'
814
+ };
815
+ }
706
816
  return encode({
707
817
  attributes: compressedAttributes,
708
818
  indices