@loaders.gl/tile-converter 3.2.0-alpha.1 → 3.2.0-alpha.4

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 (203) hide show
  1. package/dist/3d-tiles-attributes-worker.d.ts +28 -0
  2. package/dist/3d-tiles-attributes-worker.d.ts.map +1 -0
  3. package/dist/3d-tiles-attributes-worker.js +4 -0
  4. package/dist/3d-tiles-attributes-worker.js.map +7 -0
  5. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts +5 -1
  6. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -1
  7. package/dist/3d-tiles-converter/3d-tiles-converter.js +34 -3
  8. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts +5 -4
  9. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -1
  10. package/dist/3d-tiles-converter/helpers/b3dm-converter.js +10 -10
  11. package/dist/constants.d.ts +2 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/constants.js +4 -0
  14. package/dist/converter-cli.d.ts +2 -0
  15. package/dist/converter-cli.d.ts.map +1 -0
  16. package/dist/converter-cli.js +232 -0
  17. package/dist/converter.min.js +68 -68
  18. package/dist/deps-installer/deps-installer.d.ts +11 -1
  19. package/dist/deps-installer/deps-installer.d.ts.map +1 -1
  20. package/dist/deps-installer/deps-installer.js +10 -0
  21. package/dist/dist.min.js +910 -790
  22. package/dist/es5/3d-tiles-attributes-worker.js +29 -0
  23. package/dist/es5/3d-tiles-attributes-worker.js.map +1 -0
  24. package/dist/es5/3d-tiles-converter/3d-tiles-converter.js +116 -46
  25. package/dist/es5/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  26. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js +21 -23
  27. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  28. package/dist/es5/constants.js +9 -0
  29. package/dist/es5/constants.js.map +1 -0
  30. package/dist/es5/converter-cli.js +306 -0
  31. package/dist/es5/converter-cli.js.map +1 -0
  32. package/dist/es5/deps-installer/deps-installer.js.map +1 -1
  33. package/dist/es5/i3s-attributes-worker.js +29 -0
  34. package/dist/es5/i3s-attributes-worker.js.map +1 -0
  35. package/dist/es5/i3s-converter/helpers/coordinate-converter.js +19 -11
  36. package/dist/es5/i3s-converter/helpers/coordinate-converter.js.map +1 -1
  37. package/dist/es5/i3s-converter/helpers/geometry-attributes.js +2 -2
  38. package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  39. package/dist/es5/i3s-converter/helpers/geometry-converter.js +271 -182
  40. package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
  41. package/dist/es5/i3s-converter/helpers/gltf-attributes.js +71 -0
  42. package/dist/es5/i3s-converter/helpers/gltf-attributes.js.map +1 -0
  43. package/dist/es5/i3s-converter/helpers/node-pages.js +47 -99
  44. package/dist/es5/i3s-converter/helpers/node-pages.js.map +1 -1
  45. package/dist/es5/i3s-converter/i3s-converter.js +293 -223
  46. package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
  47. package/dist/es5/i3s-converter/json-templates/layers.js +29 -0
  48. package/dist/es5/i3s-converter/json-templates/layers.js.map +1 -1
  49. package/dist/es5/index.js +0 -16
  50. package/dist/es5/index.js.map +1 -1
  51. package/dist/es5/lib/utils/compress-util.js +14 -17
  52. package/dist/es5/lib/utils/compress-util.js.map +1 -1
  53. package/dist/es5/lib/utils/file-utils.js +39 -14
  54. package/dist/es5/lib/utils/file-utils.js.map +1 -1
  55. package/dist/es5/lib/utils/lod-conversion-utils.js.map +1 -1
  56. package/dist/es5/lib/utils/queue.js +61 -0
  57. package/dist/es5/lib/utils/queue.js.map +1 -0
  58. package/dist/es5/lib/utils/statistic-utills.js.map +1 -1
  59. package/dist/es5/lib/utils/write-queue.js +225 -0
  60. package/dist/es5/lib/utils/write-queue.js.map +1 -0
  61. package/dist/es5/pgm-loader.js +1 -1
  62. package/dist/es5/workers/3d-tiles-attributes-worker.js +37 -0
  63. package/dist/es5/workers/3d-tiles-attributes-worker.js.map +1 -0
  64. package/dist/es5/workers/i3s-attributes-worker.js +40 -0
  65. package/dist/es5/workers/i3s-attributes-worker.js.map +1 -0
  66. package/dist/esm/3d-tiles-attributes-worker.js +16 -0
  67. package/dist/esm/3d-tiles-attributes-worker.js.map +1 -0
  68. package/dist/esm/3d-tiles-converter/3d-tiles-converter.js +36 -4
  69. package/dist/esm/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  70. package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js +16 -18
  71. package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  72. package/dist/esm/constants.js +2 -0
  73. package/dist/esm/constants.js.map +1 -0
  74. package/dist/esm/converter-cli.js +230 -0
  75. package/dist/esm/converter-cli.js.map +1 -0
  76. package/dist/esm/deps-installer/deps-installer.js.map +1 -1
  77. package/dist/esm/i3s-attributes-worker.js +16 -0
  78. package/dist/esm/i3s-attributes-worker.js.map +1 -0
  79. package/dist/esm/i3s-converter/helpers/coordinate-converter.js +19 -11
  80. package/dist/esm/i3s-converter/helpers/coordinate-converter.js.map +1 -1
  81. package/dist/esm/i3s-converter/helpers/geometry-attributes.js +2 -2
  82. package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  83. package/dist/esm/i3s-converter/helpers/geometry-converter.js +121 -62
  84. package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
  85. package/dist/esm/i3s-converter/helpers/gltf-attributes.js +54 -0
  86. package/dist/esm/i3s-converter/helpers/gltf-attributes.js.map +1 -0
  87. package/dist/esm/i3s-converter/helpers/node-pages.js +12 -4
  88. package/dist/esm/i3s-converter/helpers/node-pages.js.map +1 -1
  89. package/dist/esm/i3s-converter/i3s-converter.js +157 -52
  90. package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
  91. package/dist/esm/i3s-converter/json-templates/layers.js +25 -0
  92. package/dist/esm/i3s-converter/json-templates/layers.js.map +1 -1
  93. package/dist/esm/index.js +0 -2
  94. package/dist/esm/index.js.map +1 -1
  95. package/dist/esm/lib/utils/compress-util.js +6 -8
  96. package/dist/esm/lib/utils/compress-util.js.map +1 -1
  97. package/dist/esm/lib/utils/file-utils.js +11 -1
  98. package/dist/esm/lib/utils/file-utils.js.map +1 -1
  99. package/dist/esm/lib/utils/lod-conversion-utils.js.map +1 -1
  100. package/dist/esm/lib/utils/queue.js +19 -0
  101. package/dist/esm/lib/utils/queue.js.map +1 -0
  102. package/dist/esm/lib/utils/statistic-utills.js.map +1 -1
  103. package/dist/esm/lib/utils/write-queue.js +88 -0
  104. package/dist/esm/lib/utils/write-queue.js.map +1 -0
  105. package/dist/esm/pgm-loader.js +1 -1
  106. package/dist/esm/workers/3d-tiles-attributes-worker.js +5 -0
  107. package/dist/esm/workers/3d-tiles-attributes-worker.js.map +1 -0
  108. package/dist/esm/workers/i3s-attributes-worker.js +4 -0
  109. package/dist/esm/workers/i3s-attributes-worker.js.map +1 -0
  110. package/dist/i3s-attributes-worker.d.ts +33 -0
  111. package/dist/i3s-attributes-worker.d.ts.map +1 -0
  112. package/dist/i3s-attributes-worker.js +10 -0
  113. package/dist/i3s-attributes-worker.js.map +7 -0
  114. package/dist/i3s-converter/helpers/coordinate-converter.d.ts +7 -7
  115. package/dist/i3s-converter/helpers/coordinate-converter.d.ts.map +1 -1
  116. package/dist/i3s-converter/helpers/coordinate-converter.js +25 -21
  117. package/dist/i3s-converter/helpers/geometry-attributes.d.ts +2 -2
  118. package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -1
  119. package/dist/i3s-converter/helpers/geometry-attributes.js +2 -1
  120. package/dist/i3s-converter/helpers/geometry-converter.d.ts +28 -11
  121. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -1
  122. package/dist/i3s-converter/helpers/geometry-converter.js +223 -113
  123. package/dist/i3s-converter/helpers/gltf-attributes.d.ts +9 -0
  124. package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -0
  125. package/dist/i3s-converter/helpers/gltf-attributes.js +56 -0
  126. package/dist/i3s-converter/helpers/node-pages.d.ts +6 -5
  127. package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -1
  128. package/dist/i3s-converter/helpers/node-pages.js +13 -8
  129. package/dist/i3s-converter/i3s-converter.d.ts +7 -5
  130. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -1
  131. package/dist/i3s-converter/i3s-converter.js +126 -40
  132. package/dist/i3s-converter/json-templates/layers.d.ts +4 -0
  133. package/dist/i3s-converter/json-templates/layers.d.ts.map +1 -1
  134. package/dist/i3s-converter/json-templates/layers.js +24 -0
  135. package/dist/i3s-converter/types.d.ts +83 -8
  136. package/dist/i3s-converter/types.d.ts.map +1 -1
  137. package/dist/index.d.ts +0 -2
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/index.js +1 -5
  140. package/dist/lib/utils/compress-util.d.ts +44 -5
  141. package/dist/lib/utils/compress-util.d.ts.map +1 -1
  142. package/dist/lib/utils/compress-util.js +73 -6
  143. package/dist/lib/utils/file-utils.d.ts +34 -5
  144. package/dist/lib/utils/file-utils.d.ts.map +1 -1
  145. package/dist/lib/utils/file-utils.js +40 -1
  146. package/dist/lib/utils/lod-conversion-utils.d.ts +25 -4
  147. package/dist/lib/utils/lod-conversion-utils.d.ts.map +1 -1
  148. package/dist/lib/utils/lod-conversion-utils.js +21 -2
  149. package/dist/lib/utils/queue.d.ts +7 -0
  150. package/dist/lib/utils/queue.d.ts.map +1 -0
  151. package/dist/lib/utils/queue.js +18 -0
  152. package/dist/lib/utils/statistic-utills.d.ts +2 -2
  153. package/dist/lib/utils/statistic-utills.d.ts.map +1 -1
  154. package/dist/lib/utils/write-queue.d.ts +22 -0
  155. package/dist/lib/utils/write-queue.d.ts.map +1 -0
  156. package/dist/lib/utils/write-queue.js +62 -0
  157. package/dist/workers/3d-tiles-attributes-worker.d.ts +2 -0
  158. package/dist/workers/3d-tiles-attributes-worker.d.ts.map +1 -0
  159. package/dist/workers/3d-tiles-attributes-worker.js +9 -0
  160. package/dist/workers/i3s-attributes-worker.d.ts +2 -0
  161. package/dist/workers/i3s-attributes-worker.d.ts.map +1 -0
  162. package/dist/workers/i3s-attributes-worker.js +5 -0
  163. package/package.json +23 -18
  164. package/src/3d-tiles-attributes-worker.ts +43 -0
  165. package/src/3d-tiles-converter/3d-tiles-converter.ts +50 -5
  166. package/src/3d-tiles-converter/helpers/b3dm-converter.ts +15 -13
  167. package/src/constants.ts +2 -0
  168. package/src/converter-cli.ts +310 -0
  169. package/src/deps-installer/{deps-installer.js → deps-installer.ts} +11 -1
  170. package/src/i3s-attributes-worker.ts +46 -0
  171. package/src/i3s-converter/helpers/coordinate-converter.ts +29 -24
  172. package/src/i3s-converter/helpers/geometry-attributes.ts +4 -3
  173. package/src/i3s-converter/helpers/{geometry-converter.js → geometry-converter.ts} +425 -179
  174. package/src/i3s-converter/helpers/gltf-attributes.ts +68 -0
  175. package/src/i3s-converter/helpers/node-pages.ts +25 -17
  176. package/src/i3s-converter/i3s-converter.ts +150 -90
  177. package/src/i3s-converter/json-templates/layers.ts +25 -0
  178. package/src/i3s-converter/types.ts +90 -8
  179. package/src/index.ts +0 -4
  180. package/src/lib/utils/{compress-util.js → compress-util.ts} +105 -18
  181. package/src/lib/utils/file-utils.ts +84 -0
  182. package/src/lib/utils/{lod-conversion-utils.js → lod-conversion-utils.ts} +27 -5
  183. package/src/lib/utils/queue.ts +17 -0
  184. package/src/lib/utils/{statistic-utills.js → statistic-utills.ts} +0 -0
  185. package/src/lib/utils/write-queue.ts +75 -0
  186. package/src/workers/3d-tiles-attributes-worker.ts +6 -0
  187. package/src/workers/i3s-attributes-worker.ts +6 -0
  188. package/dist/es5/deps-installer/deps-installer.d.ts +0 -10
  189. package/dist/es5/i3s-converter/helpers/geometry-converter.d.ts +0 -44
  190. package/dist/es5/lib/utils/compress-util.d.ts +0 -53
  191. package/dist/es5/lib/utils/file-utils.d.ts +0 -43
  192. package/dist/es5/lib/utils/lod-conversion-utils.d.ts +0 -32
  193. package/dist/esm/deps-installer/deps-installer.d.ts +0 -10
  194. package/dist/esm/i3s-converter/helpers/geometry-converter.d.ts +0 -44
  195. package/dist/esm/lib/utils/compress-util.d.ts +0 -53
  196. package/dist/esm/lib/utils/file-utils.d.ts +0 -43
  197. package/dist/esm/lib/utils/lod-conversion-utils.d.ts +0 -32
  198. package/src/deps-installer/deps-installer.d.ts +0 -10
  199. package/src/i3s-converter/helpers/geometry-converter.d.ts +0 -44
  200. package/src/lib/utils/compress-util.d.ts +0 -53
  201. package/src/lib/utils/file-utils.d.ts +0 -43
  202. package/src/lib/utils/file-utils.js +0 -38
  203. package/src/lib/utils/lod-conversion-utils.d.ts +0 -32
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.convertAttributes = void 0;
6
7
  const core_1 = require("@math.gl/core");
7
8
  const geospatial_1 = require("@math.gl/geospatial");
8
9
  const draco_1 = require("@loaders.gl/draco");
@@ -11,6 +12,7 @@ const loader_utils_1 = require("@loaders.gl/loader-utils");
11
12
  const md5_1 = __importDefault(require("md5"));
12
13
  const geometry_attributes_1 = require("./geometry-attributes");
13
14
  const coordinate_converter_1 = require("./coordinate-converter");
15
+ const gltf_attributes_1 = require("./gltf-attributes");
14
16
  // Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.7/pbrMetallicRoughness.cmn.md
15
17
  const DEFAULT_ROUGHNESS_FACTOR = 1;
16
18
  const DEFAULT_METALLIC_FACTOR = 1;
@@ -28,10 +30,31 @@ const OBJECT_ID_TYPE = 'Oid32';
28
30
  */
29
31
  const BATCHED_ID_POSSIBLE_ATTRIBUTE_NAMES = ['CUSTOM_ATTRIBUTE_2', '_BATCHID', 'BATCHID'];
30
32
  let scratchVector = new core_1.Vector3();
31
- async function convertB3dmToI3sGeometry(tileContent, nodeId, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, geoidHeightModel) {
33
+ /**
34
+ * Convert binary data from b3dm file to i3s resources
35
+ *
36
+ * @param tileContent - 3d tile content
37
+ * @param nodeId - target nodeId. If a few nodes will be created - ids will be nodeId+n where n - index in the resulting array
38
+ * @param featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
39
+ * @param attributeStorageInfo - attributes metadata from 3DSceneLayer json
40
+ * @param draco - is converter should create draco compressed geometry
41
+ * @param generateBoundingVolumes - is converter should create accurate bounding voulmes from geometry attributes
42
+ * @param geoidHeightModel - model to convert elevation from elipsoidal to geoid
43
+ * @returns Array of node resources to create one or more i3s nodes
44
+ */
45
+ async function convertB3dmToI3sGeometry(tileContent, nodeId, featuresHashArray, attributeStorageInfo, draco, generateBoundingVolumes, geoidHeightModel, workerSource) {
32
46
  const useCartesianPositions = generateBoundingVolumes;
33
- const materialAndTextureList = convertMaterials(tileContent);
34
- const convertedAttributesMap = convertAttributes(tileContent, useCartesianPositions);
47
+ const materialAndTextureList = convertMaterials(tileContent.gltf?.materials);
48
+ const dataForAttributesConversion = (0, gltf_attributes_1.prepareDataForAttributesConversion)(tileContent);
49
+ const convertedAttributesMap = await convertAttributes(dataForAttributesConversion, useCartesianPositions);
50
+ // TODO uncomment it when worker will be published on CDN.
51
+ /*
52
+ const convertedAttributesMap: Map<string, ConvertedAttributes> =
53
+ await transformI3SAttributesOnWorker(dataForAttributesConversion, {
54
+ useCartesianPositions,
55
+ source: workerSource.I3SAttributes
56
+ });
57
+ */
35
58
  if (generateBoundingVolumes) {
36
59
  _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeightModel);
37
60
  }
@@ -42,7 +65,7 @@ async function convertB3dmToI3sGeometry(tileContent, nodeId, featuresHashArray,
42
65
  }
43
66
  const result = [];
44
67
  let nodesCounter = nodeId;
45
- let { materials = [] } = tileContent.gltf;
68
+ let { materials = [] } = tileContent.gltf || { materials: [] };
46
69
  if (!materials?.length) {
47
70
  materials.push({ id: 'default' });
48
71
  }
@@ -52,6 +75,9 @@ async function convertB3dmToI3sGeometry(tileContent, nodeId, featuresHashArray,
52
75
  continue; // eslint-disable-line no-continue
53
76
  }
54
77
  const convertedAttributes = convertedAttributesMap.get(sourceMaterial.id);
78
+ if (!convertedAttributes) {
79
+ continue;
80
+ }
55
81
  const { material, texture } = materialAndTextureList[i];
56
82
  result.push(await _makeNodeResources({
57
83
  convertedAttributes,
@@ -61,7 +87,8 @@ async function convertB3dmToI3sGeometry(tileContent, nodeId, featuresHashArray,
61
87
  nodeId: nodesCounter,
62
88
  featuresHashArray,
63
89
  attributeStorageInfo,
64
- draco
90
+ draco,
91
+ workerSource
65
92
  }));
66
93
  nodesCounter++;
67
94
  }
@@ -73,8 +100,8 @@ async function convertB3dmToI3sGeometry(tileContent, nodeId, featuresHashArray,
73
100
  exports.default = convertB3dmToI3sGeometry;
74
101
  /**
75
102
  * Create bounding volumes based on positions
76
- * @param convertedAttributesMap
77
- * @param geoidHeightModel
103
+ * @param convertedAttributesMap - geometry attributes map
104
+ * @param geoidHeightModel - geoid height model to convert elevation from elipsoidal to geoid
78
105
  */
79
106
  function _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeightModel) {
80
107
  for (const attributes of convertedAttributesMap.values()) {
@@ -91,11 +118,23 @@ function _generateBoundingVolumesFromGeometry(convertedAttributesMap, geoidHeigh
91
118
  }
92
119
  }
93
120
  }
94
- async function _makeNodeResources({ convertedAttributes, material, texture, tileContent, nodeId, featuresHashArray, attributeStorageInfo, draco }) {
121
+ /**
122
+ *
123
+ * @param params
124
+ * @param params.convertedAttributes - Converted geometry attributes
125
+ * @param params.material - I3S PBR-like material definition
126
+ * @param params.texture - texture content
127
+ * @param params.tileContent - B3DM decoded content
128
+ * @param params.nodeId - new node ID
129
+ * @param params.featuresHashArray - hash array of features that is needed to not to mix up same features in parent and child nodes
130
+ * @param params.attributesStorageInfo - attributes metadata from 3DSceneLayer json
131
+ * @param params.draco - is converter should create draco compressed geometry
132
+ * @returns Array of I3S node resources
133
+ */
134
+ async function _makeNodeResources({ convertedAttributes, material, texture, tileContent, nodeId, featuresHashArray, attributeStorageInfo, draco, workerSource }) {
95
135
  const boundingVolumes = convertedAttributes.boundingVolumes;
96
136
  const vertexCount = convertedAttributes.positions.length / VALUES_PER_VERTEX;
97
- const triangleCount = vertexCount / 3;
98
- const { faceRange, featureIds, positions, normals, colors, texCoords, featureCount } = (0, geometry_attributes_1.generateAttributes)({ triangleCount, ...convertedAttributes });
137
+ const { faceRange, featureIds, positions, normals, colors, texCoords, featureCount } = (0, geometry_attributes_1.generateAttributes)(convertedAttributes);
99
138
  if (tileContent.batchTableJson) {
100
139
  makeFeatureIdsUnique(featureIds, convertedAttributes.featureIndices, featuresHashArray, tileContent.batchTableJson);
101
140
  }
@@ -104,21 +143,21 @@ async function _makeNodeResources({ convertedAttributes, material, texture, tile
104
143
  header.set([vertexCount, featureCount], 0);
105
144
  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));
106
145
  const compressedGeometry = draco
107
- ? await generateCompressedGeometry(vertexCount, convertedAttributes, {
146
+ ? generateCompressedGeometry(vertexCount, convertedAttributes, {
108
147
  positions,
109
148
  normals,
110
149
  texCoords: texture ? texCoords : new Float32Array(0),
111
150
  colors,
112
151
  featureIds,
113
152
  faceRange
114
- })
153
+ }, workerSource.draco)
115
154
  : null;
116
155
  const attributes = convertBatchTableToAttributeBuffers(tileContent.batchTableJson, featureIds, attributeStorageInfo);
117
156
  return {
118
157
  geometry: fileBuffer,
119
158
  compressedGeometry,
120
159
  texture,
121
- sharedResources: getSharedResources(tileContent, nodeId),
160
+ sharedResources: getSharedResources(tileContent.gltf?.materials || [], nodeId),
122
161
  meshMaterial: material,
123
162
  vertexCount,
124
163
  attributes,
@@ -128,54 +167,58 @@ async function _makeNodeResources({ convertedAttributes, material, texture, tile
128
167
  }
129
168
  /**
130
169
  * Convert attributes from the gltf nodes tree to i3s plain geometry
131
- * @param {Object} tileContent - 3d tile content
132
- * @returns {Map}
133
- * Map<{
134
- * positions: Float32Array,
135
- * normals: Float32Array,
136
- * colors: Uint8Array,
137
- * texCoords: Float32Array
138
- * }>
139
- * @todo implement colors support (if applicable for gltf format)
140
- */
141
- function convertAttributes(tileContent, useCartesianPositions) {
170
+ * @param tileContent - 3d tile content
171
+ * @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
172
+ * Cartesian coordinates will be required for creating bounding voulmest from geometry positions
173
+ * @returns map of converted geometry attributes
174
+ */
175
+ async function convertAttributes(attributesData, useCartesianPositions) {
176
+ const { gltfMaterials, nodes, cartographicOrigin, cartesianModelMatrix } = attributesData;
142
177
  const attributesMap = new Map();
143
- for (const material of tileContent.gltf.materials || [{ id: 'default' }]) {
178
+ for (const material of gltfMaterials || [{ id: 'default' }]) {
144
179
  attributesMap.set(material.id, {
145
180
  positions: new Float32Array(0),
146
181
  normals: new Float32Array(0),
147
182
  texCoords: new Float32Array(0),
148
183
  colors: new Uint8Array(0),
184
+ featureIndicesGroups: [],
149
185
  featureIndices: [],
150
186
  boundingVolumes: null
151
187
  });
152
188
  }
153
- const nodes = (tileContent.gltf.scene || tileContent.gltf.scenes?.[0] || tileContent.gltf).nodes;
154
- convertNodes(nodes, tileContent, attributesMap, useCartesianPositions);
189
+ convertNodes(nodes, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions);
155
190
  for (const attrKey of attributesMap.keys()) {
156
191
  const attributes = attributesMap.get(attrKey);
192
+ if (!attributes) {
193
+ continue;
194
+ }
157
195
  if (attributes.positions.length === 0) {
158
196
  attributesMap.delete(attrKey);
159
197
  continue; // eslint-disable-line no-continue
160
198
  }
161
- attributes.featureIndices = attributes.featureIndices.reduce((acc, value) => acc.concat(value));
199
+ if (attributes.featureIndicesGroups) {
200
+ attributes.featureIndices = attributes.featureIndicesGroups.reduce((acc, value) => acc.concat(value));
201
+ delete attributes.featureIndicesGroups;
202
+ }
162
203
  }
163
204
  return attributesMap;
164
205
  }
206
+ exports.convertAttributes = convertAttributes;
165
207
  /**
166
208
  * Gltf has hierarchical structure of nodes. This function converts nodes starting from those which are in gltf scene object.
167
209
  * The goal is applying tranformation matrix for all children. Functions "convertNodes" and "convertNode" work together recursively.
168
- * @param {Object[]} nodes - gltf nodes array
169
- * @param {Object} tileContent - 3d tile content
170
- * @param {Map} attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: UInt8Array, featureIndices: Array}> - for recursive concatenation of
171
- * attributes
172
- * @param {Matrix4} matrix - transformation matrix - cumulative transformation matrix formed from all parent node matrices
210
+ * @param nodes - gltf nodes array
211
+ * @param tileContent - 3d tile content
212
+ * @param attributesMap - for recursive concatenation of attributes
213
+ * @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
214
+ * Cartesian coordinates will be required for creating bounding voulmest from geometry positions
215
+ * @param matrix - transformation matrix - cumulative transformation matrix formed from all parent node matrices
173
216
  * @returns {void}
174
217
  */
175
- function convertNodes(nodes, tileContent, attributesMap, useCartesianPositions, matrix = new core_1.Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])) {
218
+ function convertNodes(nodes, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions, matrix = new core_1.Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])) {
176
219
  if (nodes) {
177
220
  for (const node of nodes) {
178
- convertNode(node, tileContent, attributesMap, useCartesianPositions, matrix);
221
+ convertNode(node, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions, matrix);
179
222
  }
180
223
  }
181
224
  }
@@ -191,44 +234,47 @@ function getCompositeTransformationMatrix(node, matrix) {
191
234
  if (nodeMatrix) {
192
235
  transformationMatrix = matrix.multiplyRight(nodeMatrix);
193
236
  }
237
+ if (translation) {
238
+ transformationMatrix = transformationMatrix.translate(translation);
239
+ }
194
240
  if (rotation) {
195
241
  transformationMatrix = transformationMatrix.rotateXYZ(rotation);
196
242
  }
197
243
  if (scale) {
198
244
  transformationMatrix = transformationMatrix.scale(scale);
199
245
  }
200
- if (translation) {
201
- transformationMatrix = transformationMatrix.translate(translation);
202
- }
203
246
  return transformationMatrix;
204
247
  }
205
248
  /**
206
249
  * Convert all primitives of node and all children nodes
207
- * @param {Object} node - gltf node
250
+ * @param node - gltf node
208
251
  * @param {Object} tileContent - 3d tile content
209
252
  * @param {Map} attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
210
253
  * attributes
254
+ * @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
255
+ * Cartesian coordinates will be required for creating bounding voulmest from geometry positions
211
256
  * @param {Matrix4} matrix - transformation matrix - cumulative transformation matrix formed from all parent node matrices
212
- * @todo: optimize arrays concatenation
213
257
  */
214
- function convertNode(node, tileContent, attributesMap, useCartesianPositions, matrix = new core_1.Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])) {
258
+ function convertNode(node, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions, matrix = new core_1.Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])) {
215
259
  const transformationMatrix = getCompositeTransformationMatrix(node, matrix);
216
260
  const mesh = node.mesh;
217
261
  if (mesh) {
218
- convertMesh(mesh, tileContent, attributesMap, useCartesianPositions, transformationMatrix);
262
+ convertMesh(mesh, cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions, transformationMatrix);
219
263
  }
220
- convertNodes(node.children, tileContent, attributesMap, useCartesianPositions, transformationMatrix);
264
+ convertNodes(node.children || [], cartographicOrigin, cartesianModelMatrix, attributesMap, useCartesianPositions, transformationMatrix);
221
265
  }
222
266
  /**
223
267
  * Convert all primitives of node and all children nodes
224
- * @param {Object} mesh - gltf node
225
- * @param {Object} content - 3d tile content
226
- * @param {Map} attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
268
+ * @param mesh - gltf node
269
+ * @param content - 3d tile content
270
+ * @param useCartesianPositions - convert positions to absolute cartesian coordinates instead of cartographic offsets.
271
+ * Cartesian coordinates will be required for creating bounding voulmest from geometry positions
272
+ * @param attributesMap Map<{positions: Float32Array, normals: Float32Array, texCoords: Float32Array, colors: Uint8Array, featureIndices: Array}> - for recursive concatenation of
227
273
  * attributes
274
+
228
275
  * @param {Matrix4} matrix - transformation matrix - cumulative transformation matrix formed from all parent node matrices
229
- * @todo: optimize arrays concatenation
230
276
  */
231
- function convertMesh(mesh, content, attributesMap, useCartesianPositions = false, matrix = new core_1.Matrix4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])) {
277
+ function convertMesh(mesh, 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])) {
232
278
  for (const primitive of mesh.primitives) {
233
279
  let outputAttributes = null;
234
280
  if (primitive.material) {
@@ -239,39 +285,43 @@ function convertMesh(mesh, content, attributesMap, useCartesianPositions = false
239
285
  }
240
286
  (0, core_2.assert)(outputAttributes !== null, 'Primitive - material mapping failed');
241
287
  const attributes = primitive.attributes;
288
+ if (!outputAttributes) {
289
+ continue;
290
+ }
242
291
  outputAttributes.positions = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.positions, transformVertexArray({
243
292
  vertices: attributes.POSITION.value,
244
- cartographicOrigin: content.cartographicOrigin,
245
- cartesianModelMatrix: content.cartesianModelMatrix,
293
+ cartographicOrigin,
294
+ cartesianModelMatrix,
246
295
  nodeMatrix: matrix,
247
- indices: primitive.indices.value,
296
+ indices: primitive.indices?.value,
248
297
  attributeSpecificTransformation: transformVertexPositions,
249
298
  useCartesianPositions
250
299
  }));
251
300
  outputAttributes.normals = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.normals, transformVertexArray({
252
301
  vertices: attributes.NORMAL && attributes.NORMAL.value,
253
- cartographicOrigin: content.cartographicOrigin,
254
- cartesianModelMatrix: content.cartesianModelMatrix,
302
+ cartographicOrigin,
303
+ cartesianModelMatrix,
255
304
  nodeMatrix: matrix,
256
- indices: primitive.indices.value,
305
+ indices: primitive.indices?.value,
257
306
  attributeSpecificTransformation: transformVertexNormals,
258
307
  useCartesianPositions: false
259
308
  }));
260
- outputAttributes.texCoords = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.texCoords, flattenTexCoords(attributes.TEXCOORD_0 && attributes.TEXCOORD_0.value, primitive.indices.value));
261
- outputAttributes.colors = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.colors, flattenColors(attributes.COLOR_0, primitive.indices.value));
262
- outputAttributes.featureIndices.push(flattenBatchIds(getBatchIdsByAttributeName(attributes), primitive.indices.value));
309
+ outputAttributes.texCoords = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.texCoords, flattenTexCoords(attributes.TEXCOORD_0 && attributes.TEXCOORD_0.value, primitive.indices?.value));
310
+ outputAttributes.colors = (0, loader_utils_1.concatenateTypedArrays)(outputAttributes.colors, flattenColors(attributes.COLOR_0, primitive.indices?.value));
311
+ outputAttributes.featureIndicesGroups = outputAttributes.featureIndicesGroups || [];
312
+ outputAttributes.featureIndicesGroups.push(flattenBatchIds(getBatchIdsByAttributeName(attributes), primitive.indices?.value));
263
313
  }
264
314
  }
265
315
  /**
266
316
  * Convert vertices attributes (POSITIONS or NORMALS) to i3s compatible format
267
- * @param {object} args - source tile (3DTile)
268
- * @param {Float32Array} args.vertices - gltf primitive POSITION or NORMAL attribute
269
- * @param {Object} args.cartographicOrigin - cartographic origin coordinates
270
- * @param {Object} args.cartesianModelMatrix - a cartesian model matrix to transform coordnates from cartesian to cartographic format
271
- * @param {Matrix4} args.nodeMatrix - a gltf node transformation matrix - cumulative transformation matrix formed from all parent node matrices
272
- * @param {Uint8Array} args.indices - gltf primitive indices
273
- * @param {Function} args.attributeSpecificTransformation - function to do attribute - specific transformations
274
- * @param {Boolean} args.useCartesianPositions - use coordinates as it is.
317
+ * @param args
318
+ * @param args.vertices - gltf primitive POSITION or NORMAL attribute
319
+ * @param args.cartographicOrigin - cartographic origin coordinates
320
+ * @param args.cartesianModelMatrix - a cartesian model matrix to transform coordnates from cartesian to cartographic format
321
+ * @param args.nodeMatrix - a gltf node transformation matrix - cumulative transformation matrix formed from all parent node matrices
322
+ * @param args.indices - gltf primitive indices
323
+ * @param args.attributeSpecificTransformation - function to do attribute - specific transformations
324
+ * @param args.useCartesianPositions - use coordinates as it is.
275
325
  * @returns {Float32Array}
276
326
  */
277
327
  function transformVertexArray(args) {
@@ -291,6 +341,16 @@ function transformVertexArray(args) {
291
341
  }
292
342
  return newVertices;
293
343
  }
344
+ /**
345
+ * Trasform positions vector with the attribute specific transformations
346
+ * @param vertexVector - source positions vector to transform
347
+ * @param calleeArgs
348
+ * @param calleeArgs.cartesianModelMatrix - a cartesian model matrix to transform coordnates from cartesian to cartographic format
349
+ * @param calleeArgs.cartographicOrigin - cartographic origin coordinates
350
+ * @param calleeArgs.nodeMatrix - a gltf node transformation matrix - cumulative transformation matrix formed from all parent node matrices
351
+ * @param calleeArgs.useCartesianPositions - use coordinates as it is.
352
+ * @returns transformed positions vector
353
+ */
294
354
  function transformVertexPositions(vertexVector, calleeArgs) {
295
355
  const { cartesianModelMatrix, cartographicOrigin, nodeMatrix, useCartesianPositions } = calleeArgs;
296
356
  if (nodeMatrix) {
@@ -304,6 +364,14 @@ function transformVertexPositions(vertexVector, calleeArgs) {
304
364
  vertexVector = vertexVector.subtract(cartographicOrigin);
305
365
  return vertexVector;
306
366
  }
367
+ /**
368
+ * Trasform normals vector with the attribute specific transformations
369
+ * @param vertexVector - source normals vector to transform
370
+ * @param calleeArgs
371
+ * @param calleeArgs.cartesianModelMatrix - a cartesian model matrix to transform coordnates from cartesian to cartographic format
372
+ * @param calleeArgs.nodeMatrix - a gltf node transformation matrix - cumulative transformation matrix formed from all parent node matrices
373
+ * @returns transformed normals vector
374
+ */
307
375
  function transformVertexNormals(vertexVector, calleeArgs) {
308
376
  const { cartesianModelMatrix, nodeMatrix } = calleeArgs;
309
377
  if (nodeMatrix) {
@@ -314,9 +382,9 @@ function transformVertexNormals(vertexVector, calleeArgs) {
314
382
  }
315
383
  /**
316
384
  * Convert uv0 (texture coordinates) from coords based on indices to plain arrays, compatible with i3s
317
- * @param {Float32Array} texCoords - gltf primitive TEXCOORD_0 attribute
318
- * @param {Uint8Array} indices - gltf primitive indices
319
- * @returns {Float32Array}
385
+ * @param texCoords - gltf primitive TEXCOORD_0 attribute
386
+ * @param indices - gltf primitive indices
387
+ * @returns flattened texture coordinates
320
388
  */
321
389
  function flattenTexCoords(texCoords, indices) {
322
390
  const newTexCoords = new Float32Array(indices.length * VALUES_PER_TEX_COORD);
@@ -336,9 +404,9 @@ function flattenTexCoords(texCoords, indices) {
336
404
  }
337
405
  /**
338
406
  * Convert color from COLOR_0 based on indices to plain arrays, compatible with i3s
339
- * @param {object} colorsAttribute - gltf primitive COLOR_0 attribute
340
- * @param {Uint8Array} indices - gltf primitive indices
341
- * @returns {Uint8Array}
407
+ * @param colorsAttribute - gltf primitive COLOR_0 attribute
408
+ * @param indices - gltf primitive indices
409
+ * @returns flattened colors attribute
342
410
  */
343
411
  function flattenColors(colorsAttribute, indices) {
344
412
  const components = colorsAttribute?.components || VALUES_PER_COLOR_ELEMENT;
@@ -362,9 +430,9 @@ function flattenColors(colorsAttribute, indices) {
362
430
  }
363
431
  /**
364
432
  * Flatten batchedIds list based on indices to right ordered array, compatible with i3s
365
- * @param {Array} batchedIds - gltf primitive
366
- * @param {Uint8Array} indices - gltf primitive indices
367
- * @returns {Array}
433
+ * @param batchedIds - gltf primitive
434
+ * @param indices - gltf primitive indices
435
+ * @returns flattened batch ids
368
436
  */
369
437
  function flattenBatchIds(batchedIds, indices) {
370
438
  if (!batchedIds.length || !indices.length) {
@@ -379,8 +447,8 @@ function flattenBatchIds(batchedIds, indices) {
379
447
  }
380
448
  /**
381
449
  * Return batchIds based on possible attribute names for different kind of maps.
382
- * @param {Object} attributes {attributeName: Float32Array}
383
- * @returns {Array}
450
+ * @param attributes - the gltf primitive attributes
451
+ * @returns batch ids attribute
384
452
  */
385
453
  function getBatchIdsByAttributeName(attributes) {
386
454
  let batchIds = [];
@@ -394,9 +462,13 @@ function getBatchIdsByAttributeName(attributes) {
394
462
  }
395
463
  return batchIds;
396
464
  }
397
- function convertMaterials(tileContent) {
465
+ /**
466
+ * Convert GLTF material to I3S material definitions and textures
467
+ * @param sourceMaterials Source GLTF materials
468
+ * @returns Array of Couples I3SMaterialDefinition + texture content
469
+ */
470
+ function convertMaterials(sourceMaterials = []) {
398
471
  const result = [];
399
- const sourceMaterials = tileContent.gltf.materials || [];
400
472
  for (const sourceMaterial of sourceMaterials) {
401
473
  result.push(convertMaterial(sourceMaterial));
402
474
  }
@@ -404,16 +476,16 @@ function convertMaterials(tileContent) {
404
476
  }
405
477
  /**
406
478
  * Convert texture and material from gltf 2.0 material object
407
- * @param {Object} sourceMaterial - material object
408
- * @returns {Object}
479
+ * @param sourceMaterial - material object
480
+ * @returns I3S material definition and texture
409
481
  */
410
482
  function convertMaterial(sourceMaterial) {
411
483
  const material = {
412
484
  doubleSided: sourceMaterial.doubleSided,
413
- emissiveFactor: sourceMaterial.emissiveFactor.map((c) => Math.round(c * 255)),
485
+ emissiveFactor: sourceMaterial.emissiveFactor?.map((c) => Math.round(c * 255)),
414
486
  // It is in upper case in GLTF: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#alpha-coverage
415
487
  // But it is in lower case in I3S: https://github.com/Esri/i3s-spec/blob/master/docs/1.7/materialDefinitions.cmn.md
416
- alphaMode: (sourceMaterial.alphaMode || 'OPAQUE').toLowerCase(),
488
+ alphaMode: convertAlphaMode(sourceMaterial.alphaMode),
417
489
  pbrMetallicRoughness: {
418
490
  roughnessFactor: sourceMaterial?.pbrMetallicRoughness?.roughnessFactor || DEFAULT_ROUGHNESS_FACTOR,
419
491
  metallicFactor: sourceMaterial?.pbrMetallicRoughness?.metallicFactor || DEFAULT_METALLIC_FACTOR
@@ -442,20 +514,44 @@ function convertMaterial(sourceMaterial) {
442
514
  }
443
515
  return { material, texture };
444
516
  }
517
+ /**
518
+ * Converts from `alphaMode` material property from GLTF to I3S format
519
+ * @param gltfAlphaMode Gltf material `alphaMode` property
520
+ * @returns I3SMaterialDefinition.alphaMode property
521
+ */
522
+ function convertAlphaMode(gltfAlphaMode) {
523
+ switch (gltfAlphaMode) {
524
+ case 'OPAQUE':
525
+ return 'opaque';
526
+ case 'MASK':
527
+ return 'mask';
528
+ case 'BLEND':
529
+ return 'blend';
530
+ default:
531
+ return 'opaque';
532
+ }
533
+ }
534
+ /**
535
+ * Form default I3SMaterialDefinition
536
+ * @returns I3S material definition
537
+ */
445
538
  function getDefaultMaterial() {
446
539
  return {
447
540
  alphaMode: 'opaque',
448
- pbrMetallicRoughness: {}
541
+ pbrMetallicRoughness: {
542
+ metallicFactor: 1,
543
+ roughnessFactor: 1
544
+ }
449
545
  };
450
546
  }
451
547
  /**
452
548
  * Form "sharedResources" from gltf materials array
453
- * @param {Object} tileContent - 3d tile content
454
- * @returns {Object} {materialDefinitionInfos: Object[], textureDefinitionInfos: Object[]} -
549
+ * @param gltfMaterials - GLTF materials array
550
+ * @param nodeId - I3S node ID
551
+ * @returns {materialDefinitionInfos: Object[], textureDefinitionInfos: Object[]} -
455
552
  * 2 arrays in format of i3s sharedResources data https://github.com/Esri/i3s-spec/blob/master/docs/1.7/sharedResource.cmn.md
456
553
  */
457
- function getSharedResources(tileContent, nodeId) {
458
- const gltfMaterials = tileContent.gltf.materials;
554
+ function getSharedResources(gltfMaterials, nodeId) {
459
555
  const i3sResources = {};
460
556
  if (!gltfMaterials || !gltfMaterials.length) {
461
557
  return i3sResources;
@@ -473,8 +569,9 @@ function getSharedResources(tileContent, nodeId) {
473
569
  }
474
570
  /**
475
571
  * Convert gltf material into I3S sharedResources data
476
- * @param {Object} gltfMaterial - gltf material data
477
- * @returns {Object} - Couple {materialDefinitionInfo, textureDefinitionInfo} extracted from gltf material data
572
+ * @param gltfMaterial - gltf material data
573
+ * @param nodeId - I3S node ID
574
+ * @returns - Couple {materialDefinitionInfo, textureDefinitionInfo} extracted from gltf material data
478
575
  */
479
576
  function convertGLTFMaterialToI3sSharedResources(gltfMaterial, nodeId) {
480
577
  const texture = gltfMaterial?.pbrMetallicRoughness?.baseColorTexture || gltfMaterial.emissiveTexture;
@@ -490,7 +587,7 @@ function convertGLTFMaterialToI3sSharedResources(gltfMaterial, nodeId) {
490
587
  colorFactor[3] = colorFactor[3] || 1;
491
588
  }
492
589
  return {
493
- materialDefinitionInfo: extractSharedResourcesMaterialInfo(colorFactor, metallicFactor),
590
+ materialDefinitionInfo: extractSharedResourcesMaterialInfo(colorFactor || [1, 1, 1, 1], metallicFactor),
494
591
  textureDefinitionInfo
495
592
  };
496
593
  }
@@ -505,9 +602,9 @@ function convertGLTFMaterialToI3sSharedResources(gltfMaterial, nodeId) {
505
602
  *
506
603
  * Assumption: F0 - specular in i3s ("specular reflection" <-> "reflectance value at normal incidence")
507
604
  * cdiff - diffuse in i3s ("Diffuse color" <-> "'c' diffuse" (c means color?))
508
- * @param {number[]} baseColorFactor - RGBA color in 0..1 format
509
- * @param {number} metallicFactor - "metallicFactor" attribute of gltf material object
510
- * @returns {Object}
605
+ * @param baseColorFactor - RGBA color in 0..1 format
606
+ * @param metallicFactor - "metallicFactor" attribute of gltf material object
607
+ * @returns material definition info for I3S shared resource
511
608
  */
512
609
  function extractSharedResourcesMaterialInfo(baseColorFactor, metallicFactor = 1) {
513
610
  const matDielectricColorComponent = 0.04 / 255; // Color from rgb (255) to 0..1 resolution
@@ -523,37 +620,42 @@ function extractSharedResourcesMaterialInfo(baseColorFactor, metallicFactor = 1)
523
620
  dielectricSpecular[3] = 1;
524
621
  const specular = dielectricSpecular.lerp(dielectricSpecular, baseColorVector, metallicFactor);
525
622
  return {
526
- diffuse: diffuse.toArray(),
527
- specular: specular.toArray()
623
+ params: {
624
+ diffuse: diffuse.toArray(),
625
+ specular: specular.toArray(),
626
+ renderMode: 'solid'
627
+ }
528
628
  };
529
629
  }
530
630
  /**
531
631
  * Form "textureDefinition" which is part of "sharedResouces"
532
- * @param {Object} texture - texture image info
533
- * @returns {Object}
632
+ * @param texture - texture image info
633
+ * @param nodeId - I3S node ID
634
+ * @returns texture definition infor for shared resource
534
635
  */
535
636
  function extractSharedResourcesTextureInfo(texture, nodeId) {
536
637
  return {
537
- encoding: [texture.source.mimeType],
638
+ encoding: texture?.source?.mimeType ? [texture.source.mimeType] : undefined,
538
639
  images: [
539
640
  {
540
641
  // 'i3s' has just size which is width of the image. Images are supposed to be square.
541
642
  // https://github.com/Esri/i3s-spec/blob/master/docs/1.7/image.cmn.md
542
643
  id: generateImageId(texture, nodeId),
543
- size: texture.source.image.width,
544
- length: [texture.source.image.data.length]
644
+ size: texture.source?.image.width,
645
+ length: [texture.source?.image.data.length]
545
646
  }
546
647
  ]
547
648
  };
548
649
  }
549
- /*
650
+ /**
550
651
  * Formula for counting imageId:
551
652
  * https://github.com/Esri/i3s-spec/blob/0a6366a9249b831db8436c322f8d27521e86cf07/format/Indexed%203d%20Scene%20Layer%20Format%20Specification.md#generating-image-ids
552
- * @param {Object} texture - texture image info
553
- * @returns {string}
653
+ * @param texture - texture image info
654
+ * @param nodeId - I3S node ID
655
+ * @returns calculate image ID according to the spec
554
656
  */
555
657
  function generateImageId(texture, nodeId) {
556
- const { width, height } = texture.source.image;
658
+ const { width, height } = texture.source?.image;
557
659
  const levelCountOfTexture = 1;
558
660
  const indexOfLevel = 0;
559
661
  const indexOfTextureInStore = nodeId + 1;
@@ -569,10 +671,10 @@ function generateImageId(texture, nodeId) {
569
671
  }
570
672
  /**
571
673
  * Make all feature ids unique through all nodes in layout.
572
- * @param {Array} featureIds
573
- * @param {Array} featureIndices
574
- * @param {Array} featuresHashArray
575
- * @param {Object} batchTable
674
+ * @param featureIds
675
+ * @param featureIndices
676
+ * @param featuresHashArray
677
+ * @param batchTable
576
678
  * @returns {void}
577
679
  */
578
680
  function makeFeatureIdsUnique(featureIds, featureIndices, featuresHashArray, batchTable) {
@@ -666,7 +768,9 @@ function convertBatchTableToAttributeBuffers(batchTable, featureIds, attributeSt
666
768
  default:
667
769
  attributeBuffer = generateStringAttributeBuffer(batchTableWithFeatureIds[key]);
668
770
  }
669
- attributeBuffers.push(attributeBuffer);
771
+ if (attributeBuffer) {
772
+ attributeBuffers.push(attributeBuffer);
773
+ }
670
774
  }
671
775
  }
672
776
  return attributeBuffers;
@@ -738,10 +842,12 @@ function generateBigUint64Array(featureIds) {
738
842
  /**
739
843
  * Generates draco compressed geometry
740
844
  * @param {Number} vertexCount
741
- * @param {Object} convertedAttributes
845
+ * @param {Object} convertedAttributes - get rid of this argument here
846
+ * @param {Object} attributes - geometry attributes to compress
847
+ * @param {string} dracoWorkerSoure - draco worker source code
742
848
  * @returns {Promise<object>} - COmpressed geometry.
743
849
  */
744
- async function generateCompressedGeometry(vertexCount, convertedAttributes, attributes) {
850
+ async function generateCompressedGeometry(vertexCount, convertedAttributes, attributes, dracoWorkerSoure) {
745
851
  const { positions, normals, texCoords, colors, featureIds, faceRange } = attributes;
746
852
  const indices = new Uint32Array(vertexCount);
747
853
  for (let index = 0; index < indices.length; index++) {
@@ -764,12 +870,16 @@ async function generateCompressedGeometry(vertexCount, convertedAttributes, attr
764
870
  'i3s-feature-ids': new Int32Array(featureIds)
765
871
  }
766
872
  };
767
- return new Uint8Array(await (0, core_2.encode)({ attributes: compressedAttributes, indices }, draco_1.DracoWriter, {
873
+ return (0, core_2.encode)({ attributes: compressedAttributes, indices }, draco_1.DracoWriterWorker, {
874
+ ...draco_1.DracoWriterWorker.options,
875
+ source: dracoWorkerSoure,
876
+ reuseWorkers: true,
877
+ _nodeWorkers: true,
768
878
  draco: {
769
879
  method: 'MESH_SEQUENTIAL_ENCODING',
770
880
  attributesMetadata
771
881
  }
772
- }));
882
+ });
773
883
  }
774
884
  /**
775
885
  * Generates ordered feature indices based on face range