@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
@@ -1,9 +1,9 @@
1
1
  import { GLTFAccessorPostprocessed, GLTFImagePostprocessed, GLTFMeshPrimitivePostprocessed } from '@loaders.gl/gltf';
2
2
  /**
3
3
  * Getting batchIds from 3DTilesNext extensions.
4
- * @param attributes
5
- * @param primitive
6
- * @param textures
4
+ * @param attributes - gltf accessors
5
+ * @param primitive - gltf primitive data
6
+ * @param images - gltf texture images
7
7
  */
8
8
  export declare function handleBatchIdsExtensions(attributes: {
9
9
  [key: string]: GLTFAccessorPostprocessed;
@@ -5,9 +5,9 @@ const EXT_MESH_FEATURES = 'EXT_mesh_features';
5
5
  const EXT_FEATURE_METADATA = 'EXT_feature_metadata';
6
6
  /**
7
7
  * Getting batchIds from 3DTilesNext extensions.
8
- * @param attributes
9
- * @param primitive
10
- * @param textures
8
+ * @param attributes - gltf accessors
9
+ * @param primitive - gltf primitive data
10
+ * @param images - gltf texture images
11
11
  */
12
12
  function handleBatchIdsExtensions(attributes, primitive, images) {
13
13
  const extensions = primitive?.extensions;
@@ -1 +1 @@
1
- {"version":3,"file":"geometry-attributes.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAE,mBAAmB,EAA+B,MAAM,UAAU,CAAC;AAMpG;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,mBAAmB,GAAG,kBAAkB,CAwBtF"}
1
+ {"version":3,"file":"geometry-attributes.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAE,mBAAmB,EAA+B,MAAM,UAAU,CAAC;AAMpG;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,mBAAmB,GAAG,kBAAkB,CAyBtF"}
@@ -10,7 +10,7 @@ const POSITIONS_AND_NORMALS_PER_TRIANGLE = 9;
10
10
  * @returns attirbutes with featureCount, featureIds and changed faceRange.
11
11
  */
12
12
  function generateAttributes(attributes) {
13
- const { positions, normals, texCoords, colors, featureIndices } = attributes;
13
+ const { positions, normals, texCoords, colors, uvRegions, featureIndices } = attributes;
14
14
  const triangleCount = positions.length / POSITIONS_AND_NORMALS_PER_TRIANGLE;
15
15
  if (!featureIndices.length) {
16
16
  return {
@@ -20,7 +20,8 @@ function generateAttributes(attributes) {
20
20
  positions,
21
21
  normals,
22
22
  texCoords,
23
- colors
23
+ colors,
24
+ uvRegions
24
25
  };
25
26
  }
26
27
  const data = calculateFaceRangesAndFeaturesCount(featureIndices);
@@ -87,32 +88,34 @@ function getFrequentValue(values) {
87
88
  * @returns sorted list of attribute objects.
88
89
  */
89
90
  function makeAttributeObjects(attributes) {
90
- const { featureIds, positions, normals, colors, texCoords, faceRange = new Uint32Array(0) } = attributes;
91
+ const { featureIds, positions, normals, colors, uvRegions, texCoords, faceRange = new Uint32Array(0) } = attributes;
91
92
  const groupedData = [];
92
93
  let positionsList = new Float32Array(positions);
93
94
  let normalsList = new Float32Array(normals);
94
95
  let colorsList = new Uint8Array(colors);
95
96
  let texCoordsList = new Float32Array(texCoords);
96
- let faceRangeIndex = 0;
97
+ let uvRegionsList = new Uint16Array(uvRegions);
97
98
  for (let index = 0; index < featureIds.length; index++) {
98
- const startIndex = faceRange[index + faceRangeIndex];
99
- const endIndex = faceRange[index + faceRangeIndex + 1];
99
+ const startIndex = faceRange[index * 2];
100
+ const endIndex = faceRange[index * 2 + 1];
100
101
  const positionsCount = getSliceAttributeCount('positions', startIndex, endIndex);
101
102
  const normalsCount = getSliceAttributeCount('normals', startIndex, endIndex);
102
103
  const colorsCount = getSliceAttributeCount('colors', startIndex, endIndex);
104
+ const uvRegionsCount = getSliceAttributeCount('uvRegions', startIndex, endIndex);
103
105
  const texCoordsCount = getSliceAttributeCount('texCoords', startIndex, endIndex);
104
106
  groupedData.push({
105
107
  featureId: featureIds[index],
106
108
  positions: positionsList.slice(0, positionsCount),
107
109
  normals: normalsList.slice(0, normalsCount),
108
110
  colors: colorsList.slice(0, colorsCount),
111
+ uvRegions: uvRegionsList.slice(0, uvRegionsCount),
109
112
  texCoords: texCoordsList.slice(0, texCoordsCount)
110
113
  });
111
114
  positionsList = positionsList.slice(positionsCount);
112
115
  normalsList = normalsList.slice(normalsCount);
113
116
  colorsList = colorsList.slice(colorsCount);
117
+ uvRegionsList = uvRegionsList.slice(uvRegionsCount);
114
118
  texCoordsList = texCoordsList.slice(texCoordsCount);
115
- faceRangeIndex += 1;
116
119
  }
117
120
  return groupedData.sort((first, second) => first.featureId - second.featureId);
118
121
  }
@@ -124,7 +127,7 @@ function makeAttributeObjects(attributes) {
124
127
  * @returns sliced count
125
128
  */
126
129
  function getSliceAttributeCount(attributeName, startIndex, endIndex) {
127
- const colorsPerVertex = 4;
130
+ const itemsPerVertex4 = 4;
128
131
  const texCoordsPerVertex = 2;
129
132
  const trianglesCount = endIndex - startIndex + 1;
130
133
  const vertexCount = trianglesCount * 3;
@@ -133,7 +136,8 @@ function getSliceAttributeCount(attributeName, startIndex, endIndex) {
133
136
  case 'normals':
134
137
  return trianglesCount * POSITIONS_AND_NORMALS_PER_TRIANGLE;
135
138
  case 'colors':
136
- return vertexCount * colorsPerVertex;
139
+ case 'uvRegions':
140
+ return vertexCount * itemsPerVertex4;
137
141
  case 'texCoords':
138
142
  return vertexCount * texCoordsPerVertex;
139
143
  default:
@@ -173,6 +177,7 @@ function groupAttributesAndRangesByFeatureId(unifiedObjects, featureCount) {
173
177
  let positions = new Float32Array(firstAttributeObject.positions);
174
178
  let normals = new Float32Array(firstAttributeObject.normals);
175
179
  let colors = new Uint8Array(firstAttributeObject.colors);
180
+ let uvRegions = new Uint16Array(firstAttributeObject.uvRegions);
176
181
  let texCoords = new Float32Array(firstAttributeObject.texCoords);
177
182
  const range = [0];
178
183
  let objIndex = 0;
@@ -183,6 +188,7 @@ function groupAttributesAndRangesByFeatureId(unifiedObjects, featureCount) {
183
188
  positions = (0, loader_utils_1.concatenateTypedArrays)(positions, currentAttributesObject.positions);
184
189
  normals = (0, loader_utils_1.concatenateTypedArrays)(normals, currentAttributesObject.normals);
185
190
  colors = (0, loader_utils_1.concatenateTypedArrays)(colors, currentAttributesObject.colors);
191
+ uvRegions = (0, loader_utils_1.concatenateTypedArrays)(uvRegions, currentAttributesObject.uvRegions);
186
192
  texCoords = (0, loader_utils_1.concatenateTypedArrays)(texCoords, currentAttributesObject.texCoords);
187
193
  const groupedObject = unifiedObjects[objIndex];
188
194
  range.push(groupedObject.positions.length / POSITIONS_AND_NORMALS_PER_TRIANGLE - 1 + sum);
@@ -192,5 +198,5 @@ function groupAttributesAndRangesByFeatureId(unifiedObjects, featureCount) {
192
198
  }
193
199
  range.push(positions.length / POSITIONS_AND_NORMALS_PER_TRIANGLE - 1);
194
200
  const faceRange = new Uint32Array(range);
195
- return { faceRange, featureIds, positions, normals, colors, texCoords, featureCount };
201
+ return { faceRange, featureIds, positions, normals, colors, uvRegions, texCoords, featureCount };
196
202
  }
@@ -1,5 +1,5 @@
1
1
  import type { B3DMContent, FeatureTableJson } from '@loaders.gl/3d-tiles';
2
- import { ConvertedAttributes, I3SConvertedResources } from '../types';
2
+ import { ConvertedAttributes, I3SConvertedResources, I3SMaterialWithTexture } from '../types';
3
3
  import { AttributeStorageInfo } from '@loaders.gl/i3s';
4
4
  import { Geoid } from '@math.gl/geoid';
5
5
  /** Usage of worker here brings more overhead than advantage */
@@ -9,24 +9,28 @@ import { B3DMAttributesData } from '../../i3s-attributes-worker';
9
9
  *
10
10
  * @param tileContent - 3d tile content
11
11
  * @param addNodeToNodePage - function to add new node to node pages
12
+ * @param propertyTable - batch table (corresponding to feature attributes data)
12
13
  * @param featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
13
14
  * @param attributeStorageInfo - attributes metadata from 3DSceneLayer json
14
15
  * @param draco - is converter should create draco compressed geometry
15
16
  * @param generateBoundingVolumes - is converter should create accurate bounding voulmes from geometry attributes
17
+ * @param shouldMergeMaterials - Try to merge similar materials to be able to merge meshes into one node
16
18
  * @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
19
+ * @param workerSource - source code of used workers
17
20
  * @returns Array of node resources to create one or more i3s nodes
18
21
  */
19
- export default function convertB3dmToI3sGeometry(tileContent: B3DMContent, addNodeToNodePage: () => number, propertyTable: FeatureTableJson | null, featuresHashArray: string[], attributeStorageInfo: AttributeStorageInfo[] | undefined, draco: boolean, generateBoundingVolumes: boolean, geoidHeightModel: Geoid, workerSource: {
22
+ export default function convertB3dmToI3sGeometry(tileContent: B3DMContent, addNodeToNodePage: () => Promise<number>, propertyTable: FeatureTableJson | null, featuresHashArray: string[], attributeStorageInfo: AttributeStorageInfo[] | undefined, draco: boolean, generateBoundingVolumes: boolean, shouldMergeMaterials: boolean, geoidHeightModel: Geoid, workerSource: {
20
23
  [key: string]: string;
21
24
  }): Promise<I3SConvertedResources[] | null>;
22
25
  /**
23
26
  * Convert attributes from the gltf nodes tree to i3s plain geometry
24
- * @param tileContent - 3d tile content
27
+ * @param attributesData - geometry attributes from gltf
28
+ * @param materialAndTextureList - array of data about materials and textures of the content
25
29
  * @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
26
30
  * Cartesian coordinates will be required for creating bounding voulmest from geometry positions
27
31
  * @returns map of converted geometry attributes
28
32
  */
29
- export declare function convertAttributes(attributesData: B3DMAttributesData, useCartesianPositions: boolean): Promise<Map<string, ConvertedAttributes>>;
33
+ export declare function convertAttributes(attributesData: B3DMAttributesData, materialAndTextureList: I3SMaterialWithTexture[], useCartesianPositions: boolean): Promise<Map<string, ConvertedAttributes>>;
30
34
  /**
31
35
  * Find property table in tile
32
36
  * For example it can be batchTable for b3dm files or property table in gLTF extension.
@@ -1 +1 @@
1
- {"version":3,"file":"geometry-converter.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-converter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAE,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAqBxE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EAGtB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,oBAAoB,EAIrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAC,KAAK,EAAC,MAAM,gBAAgB,CAAC;AACrC,+DAA+D;AAC/D,OAAO,EAAC,kBAAkB,EAAsC,MAAM,6BAA6B,CAAC;AA6BpG;;;;;;;;;;;GAWG;AACH,wBAA8B,wBAAwB,CACpD,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,MAAM,MAAM,EAC/B,aAAa,EAAE,gBAAgB,GAAG,IAAI,EACtC,iBAAiB,EAAE,MAAM,EAAE,EAC3B,oBAAoB,EAAE,oBAAoB,EAAE,GAAG,SAAS,EACxD,KAAK,EAAE,OAAO,EACd,uBAAuB,EAAE,OAAO,EAChC,gBAAgB,EAAE,KAAK,EACvB,YAAY,EAAE;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAC,GACpC,OAAO,CAAC,qBAAqB,EAAE,GAAG,IAAI,CAAC,CAmEzC;AAwID;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,cAAc,EAAE,kBAAkB,EAClC,qBAAqB,EAAE,OAAO,GAC7B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CA2C3C;AA87BD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,GAAG,gBAAgB,GAAG,IAAI,CAoBlF"}
1
+ {"version":3,"file":"geometry-converter.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/geometry-converter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAE,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAsBxE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EAGvB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,oBAAoB,EAIrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAC,KAAK,EAAC,MAAM,gBAAgB,CAAC;AACrC,+DAA+D;AAC/D,OAAO,EAAC,kBAAkB,EAAsC,MAAM,6BAA6B,CAAC;AA6BpG;;;;;;;;;;;;;;GAcG;AACH,wBAA8B,wBAAwB,CACpD,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EACxC,aAAa,EAAE,gBAAgB,GAAG,IAAI,EACtC,iBAAiB,EAAE,MAAM,EAAE,EAC3B,oBAAoB,EAAE,oBAAoB,EAAE,GAAG,SAAS,EACxD,KAAK,EAAE,OAAO,EACd,uBAAuB,EAAE,OAAO,EAChC,oBAAoB,EAAE,OAAO,EAC7B,gBAAgB,EAAE,KAAK,EACvB,YAAY,EAAE;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAC,GACpC,OAAO,CAAC,qBAAqB,EAAE,GAAG,IAAI,CAAC,CA0DzC;AA6ID;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,cAAc,EAAE,kBAAkB,EAClC,sBAAsB,EAAE,sBAAsB,EAAE,EAChD,qBAAqB,EAAE,OAAO,GAC7B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAgD3C;AA8lCD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,GAAG,gBAAgB,GAAG,IAAI,CAoBlF"}
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
@@ -10,6 +33,7 @@ const draco_1 = require("@loaders.gl/draco");
10
33
  const core_2 = require("@loaders.gl/core");
11
34
  const loader_utils_1 = require("@loaders.gl/loader-utils");
12
35
  const md5_1 = __importDefault(require("md5"));
36
+ const uuid_1 = require("uuid");
13
37
  const geometry_attributes_1 = require("./geometry-attributes");
14
38
  const coordinate_converter_1 = require("./coordinate-converter");
15
39
  const gltf_attributes_1 = require("./gltf-attributes");
@@ -39,18 +63,21 @@ let scratchVector = new core_1.Vector3();
39
63
  *
40
64
  * @param tileContent - 3d tile content
41
65
  * @param addNodeToNodePage - function to add new node to node pages
66
+ * @param propertyTable - batch table (corresponding to feature attributes data)
42
67
  * @param featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
43
68
  * @param attributeStorageInfo - attributes metadata from 3DSceneLayer json
44
69
  * @param draco - is converter should create draco compressed geometry
45
70
  * @param generateBoundingVolumes - is converter should create accurate bounding voulmes from geometry attributes
71
+ * @param shouldMergeMaterials - Try to merge similar materials to be able to merge meshes into one node
46
72
  * @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
73
+ * @param workerSource - source code of used workers
47
74
  * @returns Array of node resources to create one or more i3s nodes
48
75
  */
49
- async function convertB3dmToI3sGeometry(tileContent, addNodeToNodePage, propertyTable, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, geoidHeightModel, workerSource) {
76
+ async function convertB3dmToI3sGeometry(tileContent, addNodeToNodePage, propertyTable, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, shouldMergeMaterials, geoidHeightModel, workerSource) {
50
77
  const useCartesianPositions = generateBoundingVolumes;
51
- const materialAndTextureList = convertMaterials(tileContent.gltf?.materials);
78
+ const materialAndTextureList = await convertMaterials(tileContent.gltf?.materials, shouldMergeMaterials);
52
79
  const dataForAttributesConversion = (0, gltf_attributes_1.prepareDataForAttributesConversion)(tileContent);
53
- const convertedAttributesMap = await convertAttributes(dataForAttributesConversion, useCartesianPositions);
80
+ const convertedAttributesMap = await convertAttributes(dataForAttributesConversion, materialAndTextureList, useCartesianPositions);
54
81
  /** Usage of worker here brings more overhead than advantage */
55
82
  // const convertedAttributesMap: Map<string, ConvertedAttributes> =
56
83
  // await transformI3SAttributesOnWorker(dataForAttributesConversion, {
@@ -62,27 +89,18 @@ async function convertB3dmToI3sGeometry(tileContent, addNodeToNodePage, property
62
89
  if (generateBoundingVolumes) {
63
90
  _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeightModel);
64
91
  }
65
- if (convertedAttributesMap.has('default')) {
66
- materialAndTextureList.push({
67
- material: getDefaultMaterial()
68
- });
69
- }
70
92
  const result = [];
71
- let { materials = [] } = tileContent.gltf || { materials: [] };
72
- if (!materials?.length) {
73
- materials.push({ id: 'default' });
74
- }
75
- for (let i = 0; i < materials.length; i++) {
76
- const sourceMaterial = materials[i];
77
- if (!convertedAttributesMap.has(sourceMaterial.id)) {
93
+ for (const materialAndTexture of materialAndTextureList) {
94
+ const originarMaterialId = materialAndTexture.mergedMaterials[0].originalMaterialId;
95
+ if (!convertedAttributesMap.has(originarMaterialId)) {
78
96
  continue; // eslint-disable-line no-continue
79
97
  }
80
- const convertedAttributes = convertedAttributesMap.get(sourceMaterial.id);
98
+ const convertedAttributes = convertedAttributesMap.get(originarMaterialId);
81
99
  if (!convertedAttributes) {
82
100
  continue;
83
101
  }
84
- const { material, texture } = materialAndTextureList[i];
85
- const nodeId = addNodeToNodePage();
102
+ const { material, texture } = materialAndTexture;
103
+ const nodeId = await addNodeToNodePage();
86
104
  result.push(await _makeNodeResources({
87
105
  convertedAttributes,
88
106
  material,
@@ -131,27 +149,30 @@ function _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeigh
131
149
  * @param params.tileContent - B3DM decoded content
132
150
  * @param params.nodeId - new node ID
133
151
  * @param params.featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
134
- * @param params.attributesStorageInfo - attributes metadata from 3DSceneLayer json
152
+ * @param params.propertyTable - batch table (corresponding to feature attributes data)
153
+ * @param params.attributeStorageInfo - attributes metadata from 3DSceneLayer json
135
154
  * @param params.draco - is converter should create draco compressed geometry
155
+ * @param params.workerSource - source code of used workers
136
156
  * @returns Array of I3S node resources
137
157
  */
138
158
  async function _makeNodeResources({ convertedAttributes, material, texture, tileContent, nodeId, featuresHashArray, propertyTable, attributeStorageInfo, draco, workerSource }) {
139
159
  const boundingVolumes = convertedAttributes.boundingVolumes;
140
160
  const vertexCount = convertedAttributes.positions.length / VALUES_PER_VERTEX;
141
- const { faceRange, featureIds, positions, normals, colors, texCoords, featureCount } = (0, geometry_attributes_1.generateAttributes)(convertedAttributes);
161
+ const { faceRange, featureIds, positions, normals, colors, uvRegions, texCoords, featureCount } = (0, geometry_attributes_1.generateAttributes)(convertedAttributes);
142
162
  if (tileContent.batchTableJson) {
143
163
  makeFeatureIdsUnique(featureIds, convertedAttributes.featureIndices, featuresHashArray, tileContent.batchTableJson);
144
164
  }
145
165
  const header = new Uint32Array(2);
146
166
  const typedFeatureIds = generateBigUint64Array(featureIds);
147
167
  header.set([vertexCount, featureCount], 0);
148
- const fileBuffer = new Uint8Array((0, loader_utils_1.concatenateArrayBuffers)(header.buffer, positions.buffer, normals.buffer, texture ? texCoords.buffer : new ArrayBuffer(0), colors.buffer, typedFeatureIds.buffer, faceRange.buffer));
168
+ const fileBuffer = new Uint8Array((0, loader_utils_1.concatenateArrayBuffers)(header.buffer, positions.buffer, normals.buffer, texture ? texCoords.buffer : new ArrayBuffer(0), colors.buffer, uvRegions, typedFeatureIds.buffer, faceRange.buffer));
149
169
  const compressedGeometry = draco
150
170
  ? generateCompressedGeometry(vertexCount, convertedAttributes, {
151
171
  positions,
152
172
  normals,
153
173
  texCoords: texture ? texCoords : new Float32Array(0),
154
174
  colors,
175
+ uvRegions,
155
176
  featureIds,
156
177
  faceRange
157
178
  }, workerSource.draco)
@@ -165,6 +186,7 @@ async function _makeNodeResources({ convertedAttributes, material, texture, tile
165
186
  geometry: fileBuffer,
166
187
  compressedGeometry,
167
188
  texture,
189
+ hasUvRegions: Boolean(uvRegions.length),
168
190
  sharedResources: getSharedResources(tileContent.gltf?.materials || [], nodeId),
169
191
  meshMaterial: material,
170
192
  vertexCount,
@@ -175,24 +197,30 @@ async function _makeNodeResources({ convertedAttributes, material, texture, tile
175
197
  }
176
198
  /**
177
199
  * Convert attributes from the gltf nodes tree to i3s plain geometry
178
- * @param tileContent - 3d tile content
200
+ * @param attributesData - geometry attributes from gltf
201
+ * @param materialAndTextureList - array of data about materials and textures of the content
179
202
  * @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
180
203
  * Cartesian coordinates will be required for creating bounding voulmest from geometry positions
181
204
  * @returns map of converted geometry attributes
182
205
  */
183
- async function convertAttributes(attributesData, useCartesianPositions) {
184
- const { gltfMaterials, nodes, images, cartographicOrigin, cartesianModelMatrix } = attributesData;
206
+ async function convertAttributes(attributesData, materialAndTextureList, useCartesianPositions) {
207
+ const { nodes, images, cartographicOrigin, cartesianModelMatrix } = attributesData;
185
208
  const attributesMap = new Map();
186
- for (const material of gltfMaterials || [{ id: 'default' }]) {
187
- attributesMap.set(material.id, {
209
+ for (const materialAndTexture of materialAndTextureList) {
210
+ const attributes = {
188
211
  positions: new Float32Array(0),
189
212
  normals: new Float32Array(0),
190
213
  texCoords: new Float32Array(0),
191
214
  colors: new Uint8Array(0),
215
+ uvRegions: new Uint16Array(0),
192
216
  featureIndicesGroups: [],
193
217
  featureIndices: [],
194
- boundingVolumes: null
195
- });
218
+ boundingVolumes: null,
219
+ mergedMaterials: materialAndTexture.mergedMaterials
220
+ };
221
+ for (const mergedMaterial of materialAndTexture.mergedMaterials) {
222
+ attributesMap.set(mergedMaterial.originalMaterialId, attributes);
223
+ }
196
224
  }
197
225
  convertNodes(nodes, images, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions);
198
226
  for (const attrKey of attributesMap.keys()) {
@@ -217,7 +245,8 @@ exports.convertAttributes = convertAttributes;
217
245
  * The goal is applying tranformation matrix for all children. Functions "convertNodes" and "convertNode" work together recursively.
218
246
  * @param nodes - gltf nodes array
219
247
  * @param images - gltf images array
220
- * @param tileContent - 3d tile content
248
+ * @param cartographicOrigin - cartographic origin of bounding volume
249
+ * @param cartesianModelMatrix - cartesian model matrix to convert coordinates to cartographic
221
250
  * @param attributesMap - for recursive concatenation of attributes
222
251
  * @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
223
252
  * Cartesian coordinates will be required for creating bounding voulmest from geometry positions
@@ -258,7 +287,8 @@ function getCompositeTransformationMatrix(node, matrix) {
258
287
  * Convert all primitives of node and all children nodes
259
288
  * @param node - gltf node
260
289
  * @param images - gltf images array
261
- * @param {Object} tileContent - 3d tile content
290
+ * @param cartographicOrigin - cartographic origin of bounding volume
291
+ * @param cartesianModelMatrix - cartesian model matrix to convert coordinates to cartographic
262
292
  * @param {Map} attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
263
293
  * attributes
264
294
  * @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
@@ -274,9 +304,13 @@ function convertNode(node, images, cartographicOrigin, cartesianModelMatrix, att
274
304
  convertNodes(node.children || [], images, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions, transformationMatrix);
275
305
  }
276
306
  /**
277
- * Convert all primitives of node and all children nodes
278
- * @param mesh - gltf node
279
- * @param content - 3d tile content
307
+ * Convert all primitives of the mesh
308
+ * @param mesh - gltf mesh data
309
+ * @param images - gltf images array
310
+ * @param cartographicOrigin - cartographic origin of bounding volume
311
+ * @param cartesianModelMatrix - cartesian model matrix to convert coordinates to cartographic
312
+ * @param attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
313
+ * attributes
280
314
  * @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
281
315
  * Cartesian coordinates will be required for creating bounding voulmest from geometry positions
282
316
  * @param attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
@@ -287,8 +321,10 @@ function convertNode(node, images, cartographicOrigin, cartesianModelMatrix, att
287
321
  function convertMesh(mesh, images, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions = false, matrix = new core_1.Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])) {
288
322
  for (const primitive of mesh.primitives) {
289
323
  let outputAttributes = null;
324
+ let materialUvRegion;
290
325
  if (primitive.material) {
291
- outputAttributes = attributesMap.get(primitive.material.id);
326
+ outputAttributes = attributesMap.get(primitive.material.uniqueId);
327
+ materialUvRegion = outputAttributes?.mergedMaterials.find(({ originalMaterialId }) => originalMaterialId === primitive.material?.uniqueId)?.uvRegion;
292
328
  }
293
329
  else if (attributesMap.has('default')) {
294
330
  outputAttributes = attributesMap.get('default');
@@ -318,6 +354,9 @@ function convertMesh(mesh, images, cartographicOrigin, cartesianModelMatrix, att
318
354
  }));
319
355
  outputAttributes.texCoords = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.texCoords, flattenTexCoords(attributes.TEXCOORD_0 && attributes.TEXCOORD_0.value, primitive.indices?.value));
320
356
  outputAttributes.colors = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.colors, flattenColors(attributes.COLOR_0, primitive.indices?.value));
357
+ if (materialUvRegion) {
358
+ outputAttributes.uvRegions = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.uvRegions, createUvRegion(materialUvRegion, primitive.indices?.value));
359
+ }
321
360
  outputAttributes.featureIndicesGroups = outputAttributes.featureIndicesGroups || [];
322
361
  outputAttributes.featureIndicesGroups.push(flattenBatchIds(getBatchIds(attributes, primitive, images), primitive.indices?.value));
323
362
  }
@@ -438,6 +477,19 @@ function flattenColors(colorsAttribute, indices) {
438
477
  }
439
478
  return newColors;
440
479
  }
480
+ /**
481
+ * Create per-vertex uv-region array
482
+ * @param materialUvRegion - uv-region fragment for a single vertex
483
+ * @param indices - geometry indices data
484
+ * @returns - uv-region array
485
+ */
486
+ function createUvRegion(materialUvRegion, indices) {
487
+ const result = new Uint16Array(indices.length * 4);
488
+ for (let i = 0; i < result.length; i += 4) {
489
+ result.set(materialUvRegion, i);
490
+ }
491
+ return result;
492
+ }
441
493
  /**
442
494
  * Flatten batchedIds list based on indices to right ordered array, compatible with i3s
443
495
  * @param batchedIds - gltf primitive
@@ -457,9 +509,9 @@ function flattenBatchIds(batchedIds, indices) {
457
509
  }
458
510
  /**
459
511
  * Get batchIds for featureIds creation
460
- * @param attributes
461
- * @param primitive
462
- * @param textures
512
+ * @param attributes - gltf accessors
513
+ * @param primitive - gltf primitive data
514
+ * @param images - gltf texture images
463
515
  */
464
516
  function getBatchIds(attributes, primitive, images) {
465
517
  const batchIds = (0, batch_ids_extensions_1.handleBatchIdsExtensions)(attributes, primitive, images);
@@ -478,15 +530,107 @@ function getBatchIds(attributes, primitive, images) {
478
530
  /**
479
531
  * Convert GLTF material to I3S material definitions and textures
480
532
  * @param sourceMaterials Source GLTF materials
533
+ * @param shouldMergeMaterials - if true - the converter will try to merge similar materials
534
+ * to be able to merge primitives having those materials
481
535
  * @returns Array of Couples I3SMaterialDefinition + texture content
482
536
  */
483
- function convertMaterials(sourceMaterials = []) {
484
- const result = [];
537
+ async function convertMaterials(sourceMaterials = [], shouldMergeMaterials) {
538
+ let materials = [];
485
539
  for (const sourceMaterial of sourceMaterials) {
486
- result.push(convertMaterial(sourceMaterial));
540
+ materials.push(convertMaterial(sourceMaterial));
541
+ }
542
+ if (shouldMergeMaterials) {
543
+ materials = await mergeAllMaterials(materials);
544
+ }
545
+ return materials;
546
+ }
547
+ /**
548
+ * Merge materials when possible
549
+ * @param materials materials array
550
+ * @returns merged materials array
551
+ */
552
+ async function mergeAllMaterials(materials) {
553
+ const result = [];
554
+ while (materials.length > 0) {
555
+ let newMaterial = materials.splice(0, 1)[0];
556
+ const mergedIndices = [];
557
+ for (let i = 0; i < materials.length; i++) {
558
+ const material = materials[i];
559
+ if ((newMaterial.texture && material.texture) ||
560
+ (!newMaterial.texture && !material.texture)) {
561
+ newMaterial = await mergeMaterials(newMaterial, material);
562
+ mergedIndices.push(i);
563
+ }
564
+ }
565
+ if (newMaterial.texture && mergedIndices.length) {
566
+ const newWidth = newMaterial.mergedMaterials?.reduce((accum, { textureSize }) => accum + (textureSize?.width || 0), 0);
567
+ const newHeight = newMaterial.mergedMaterials?.reduce((accum, { textureSize }) => Math.max(accum, textureSize?.height || 0), 0);
568
+ let currentX = -1;
569
+ for (const aTextureMetadata of newMaterial.mergedMaterials) {
570
+ if (aTextureMetadata.textureSize) {
571
+ const newX = currentX +
572
+ 1 +
573
+ (aTextureMetadata.textureSize.width / newWidth) *
574
+ 2 ** (Uint16Array.BYTES_PER_ELEMENT * 8) -
575
+ 1;
576
+ aTextureMetadata.uvRegion = new Uint16Array([
577
+ currentX + 1,
578
+ 0,
579
+ newX,
580
+ (aTextureMetadata.textureSize.height / newHeight) *
581
+ 2 ** (Uint16Array.BYTES_PER_ELEMENT * 8) -
582
+ 1
583
+ ]);
584
+ currentX = newX;
585
+ }
586
+ }
587
+ newMaterial.texture.image.width = newWidth;
588
+ newMaterial.texture.image.height = newHeight;
589
+ }
590
+ for (const index of mergedIndices.reverse()) {
591
+ materials.splice(index, 1);
592
+ }
593
+ result.push(newMaterial);
594
+ }
595
+ if (!result.length) {
596
+ result.push({
597
+ material: getDefaultMaterial(),
598
+ mergedMaterials: [{ originalMaterialId: 'default' }]
599
+ });
487
600
  }
488
601
  return result;
489
602
  }
603
+ /**
604
+ * Merge 2 materials including texture
605
+ * @param material1
606
+ * @param material2
607
+ * @returns
608
+ */
609
+ async function mergeMaterials(material1, material2) {
610
+ if (material1.texture?.bufferView &&
611
+ material2.texture?.bufferView &&
612
+ material1.mergedMaterials &&
613
+ material2.mergedMaterials) {
614
+ const buffer1 = Buffer.from(material1.texture.bufferView.data);
615
+ const buffer2 = Buffer.from(material2.texture.bufferView.data);
616
+ try {
617
+ // @ts-ignore
618
+ const { joinImages } = await Promise.resolve().then(() => __importStar(require('join-images')));
619
+ const sharpData = await joinImages([buffer1, buffer2], { direction: 'horizontal' });
620
+ material1.texture.bufferView.data = await sharpData
621
+ .toFormat(material1.texture.mimeType === 'image/png' ? 'png' : 'jpeg')
622
+ .toBuffer();
623
+ }
624
+ catch (error) {
625
+ 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)');
626
+ throw error;
627
+ }
628
+ // @ts-ignore
629
+ material1.material.pbrMetallicRoughness.baseColorTexture.textureSetDefinitionId = 1;
630
+ }
631
+ material1.mergedMaterials = material1.mergedMaterials.concat(material2.mergedMaterials);
632
+ return material1;
633
+ }
490
634
  /**
491
635
  * Convert texture and material from gltf 2.0 material object
492
636
  * @param sourceMaterial - material object
@@ -518,6 +662,9 @@ function convertMaterial(sourceMaterial) {
518
662
  textureSetDefinitionId: 0
519
663
  };
520
664
  }
665
+ const uniqueId = (0, uuid_1.v4)();
666
+ sourceMaterial.uniqueId = uniqueId;
667
+ let mergedMaterials = [{ originalMaterialId: uniqueId }];
521
668
  if (!texture) {
522
669
  // Should use default baseColorFactor if it is not present in source material
523
670
  // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#reference-pbrmetallicroughness
@@ -525,7 +672,10 @@ function convertMaterial(sourceMaterial) {
525
672
  material.pbrMetallicRoughness.baseColorFactor =
526
673
  (baseColorFactor && baseColorFactor.map((c) => Math.round(c * 255))) || undefined;
527
674
  }
528
- return { material, texture };
675
+ else {
676
+ mergedMaterials[0].textureSize = { width: texture.image.width, height: texture.image.height };
677
+ }
678
+ return { material, texture, mergedMaterials };
529
679
  }
530
680
  /**
531
681
  * Converts from `alphaMode` material property from GLTF to I3S format
@@ -663,7 +813,7 @@ function extractSharedResourcesTextureInfo(texture, nodeId) {
663
813
  };
664
814
  }
665
815
  /**
666
- * Formula for counting imageId:
816
+ * Formula for calculating imageId:
667
817
  * https://github.com/Esri/i3s-spec/blob/0a6366a9249b831db8436c322f8d27521e86cf07/format/Indexed%203d%20Scene%20Layer%20Format%20Specification.md#generating-image-ids
668
818
  * @param texture - texture image info
669
819
  * @param nodeId - I3S node ID
@@ -754,8 +904,8 @@ function replaceIndicesByUnique(indicesArray, featureMap) {
754
904
  }
755
905
  /**
756
906
  * Convert property table data to attribute buffers.
757
- * @param {Object} propertyTable - table with metadata for particular feature.
758
907
  * @param {Array} featureIds
908
+ * @param {Object} propertyTable - table with metadata for particular feature.
759
909
  * @param {Array} attributeStorageInfo
760
910
  * @returns {Array} - Array of file buffers.
761
911
  */
@@ -873,7 +1023,7 @@ function generateBigUint64Array(featureIds) {
873
1023
  * @returns {Promise<object>} - COmpressed geometry.
874
1024
  */
875
1025
  async function generateCompressedGeometry(vertexCount, convertedAttributes, attributes, dracoWorkerSoure) {
876
- const { positions, normals, texCoords, colors, featureIds, faceRange } = attributes;
1026
+ const { positions, normals, texCoords, colors, uvRegions, featureIds, faceRange } = attributes;
877
1027
  const indices = new Uint32Array(vertexCount);
878
1028
  for (let index = 0; index < indices.length; index++) {
879
1029
  indices.set([index], index);
@@ -895,6 +1045,12 @@ async function generateCompressedGeometry(vertexCount, convertedAttributes, attr
895
1045
  'i3s-feature-ids': new Int32Array(featureIds)
896
1046
  }
897
1047
  };
1048
+ if (uvRegions.length) {
1049
+ compressedAttributes['uv-region'] = uvRegions;
1050
+ attributesMetadata['uv-region'] = {
1051
+ 'i3s-attribute-type': 'uv-region'
1052
+ };
1053
+ }
898
1054
  return (0, core_2.encode)({ attributes: compressedAttributes, indices }, draco_1.DracoWriterWorker, {
899
1055
  ...draco_1.DracoWriterWorker.options,
900
1056
  source: dracoWorkerSoure,
@@ -1 +1 @@
1
- {"version":3,"file":"gltf-attributes.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/gltf-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,6BAA6B,CAAC;AAsBpE;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,WAAW,EAAE,WAAW,GAAG,kBAAkB,CA2C/F"}
1
+ {"version":3,"file":"gltf-attributes.d.ts","sourceRoot":"","sources":["../../../src/i3s-converter/helpers/gltf-attributes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,6BAA6B,CAAC;AAsBpE;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,WAAW,EAAE,WAAW,GAAG,kBAAkB,CAyC/F"}
@@ -20,7 +20,6 @@ function getB3DMAttributesWithoutBufferView(attributes) {
20
20
  * @returns
21
21
  */
22
22
  function prepareDataForAttributesConversion(tileContent) {
23
- const gltfMaterials = tileContent.gltf?.materials?.map((material) => ({ id: material.id }));
24
23
  let nodes = tileContent.gltf?.scene?.nodes ||
25
24
  tileContent.gltf?.scenes?.[0]?.nodes ||
26
25
  tileContent.gltf?.nodes ||
@@ -51,7 +50,6 @@ function prepareDataForAttributesConversion(tileContent) {
51
50
  const cartographicOrigin = tileContent.cartographicOrigin;
52
51
  const cartesianModelMatrix = tileContent.cartesianModelMatrix;
53
52
  return {
54
- gltfMaterials,
55
53
  nodes,
56
54
  images,
57
55
  cartographicOrigin,
@@ -76,7 +74,8 @@ function prepareNodes(nodes) {
76
74
  indices: { value: primitive?.indices?.value },
77
75
  attributes: getB3DMAttributesWithoutBufferView(primitive.attributes),
78
76
  material: {
79
- id: primitive?.material?.id
77
+ id: primitive?.material?.id,
78
+ uniqueId: primitive?.material?.uniqueId
80
79
  }
81
80
  }))
82
81
  }