@loaders.gl/tile-converter 3.1.7 → 3.2.0-alpha.2

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 (224) 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 +82 -0
  6. package/dist/3d-tiles-converter/3d-tiles-converter.d.ts.map +1 -0
  7. package/dist/3d-tiles-converter/3d-tiles-converter.js +268 -0
  8. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts +84 -0
  9. package/dist/3d-tiles-converter/helpers/b3dm-converter.d.ts.map +1 -0
  10. package/dist/3d-tiles-converter/helpers/b3dm-converter.js +278 -0
  11. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.d.ts +13 -0
  12. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.d.ts.map +1 -0
  13. package/dist/3d-tiles-converter/helpers/i3s-obb-to-3d-tiles-obb.js +23 -0
  14. package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts +9 -0
  15. package/dist/3d-tiles-converter/helpers/texture-atlas.d.ts.map +1 -0
  16. package/dist/3d-tiles-converter/helpers/texture-atlas.js +52 -0
  17. package/dist/3d-tiles-converter/json-templates/tileset.d.ts +15 -0
  18. package/dist/3d-tiles-converter/json-templates/tileset.d.ts.map +1 -0
  19. package/dist/3d-tiles-converter/json-templates/tileset.js +43 -0
  20. package/dist/bundle.d.ts +2 -0
  21. package/dist/bundle.d.ts.map +1 -0
  22. package/dist/bundle.js +5 -0
  23. package/dist/converter.min.js +20 -20
  24. package/dist/deps-installer/deps-installer.d.ts +4 -0
  25. package/dist/deps-installer/deps-installer.d.ts.map +1 -0
  26. package/dist/deps-installer/deps-installer.js +21 -0
  27. package/dist/dist.min.js +1082 -1131
  28. package/dist/es5/3d-tiles-attributes-worker.js +29 -0
  29. package/dist/es5/3d-tiles-attributes-worker.js.map +1 -0
  30. package/dist/es5/3d-tiles-converter/3d-tiles-converter.js +104 -44
  31. package/dist/es5/3d-tiles-converter/3d-tiles-converter.js.map +1 -1
  32. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js +34 -43
  33. package/dist/es5/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  34. package/dist/es5/i3s-attributes-worker.js +29 -0
  35. package/dist/es5/i3s-attributes-worker.js.map +1 -0
  36. package/dist/es5/i3s-converter/helpers/coordinate-converter.js +19 -11
  37. package/dist/es5/i3s-converter/helpers/coordinate-converter.js.map +1 -1
  38. package/dist/es5/i3s-converter/helpers/geometry-attributes.js +2 -2
  39. package/dist/es5/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  40. package/dist/es5/i3s-converter/helpers/geometry-converter.js +267 -178
  41. package/dist/es5/i3s-converter/helpers/geometry-converter.js.map +1 -1
  42. package/dist/es5/i3s-converter/helpers/gltf-attributes.js +71 -0
  43. package/dist/es5/i3s-converter/helpers/gltf-attributes.js.map +1 -0
  44. package/dist/es5/i3s-converter/helpers/node-pages.js +43 -52
  45. package/dist/es5/i3s-converter/helpers/node-pages.js.map +1 -1
  46. package/dist/es5/i3s-converter/i3s-converter.js +264 -219
  47. package/dist/es5/i3s-converter/i3s-converter.js.map +1 -1
  48. package/dist/es5/index.js +8 -0
  49. package/dist/es5/index.js.map +1 -1
  50. package/dist/es5/lib/utils/compress-util.js +14 -17
  51. package/dist/es5/lib/utils/compress-util.js.map +1 -1
  52. package/dist/es5/lib/utils/file-utils.js +39 -14
  53. package/dist/es5/lib/utils/file-utils.js.map +1 -1
  54. package/dist/es5/lib/utils/lod-conversion-utils.js.map +1 -1
  55. package/dist/es5/lib/utils/queue.js +61 -0
  56. package/dist/es5/lib/utils/queue.js.map +1 -0
  57. package/dist/es5/lib/utils/statistic-utills.js.map +1 -1
  58. package/dist/es5/lib/utils/write-queue.js +225 -0
  59. package/dist/es5/lib/utils/write-queue.js.map +1 -0
  60. package/dist/es5/pgm-loader.js +1 -1
  61. package/dist/es5/pgm-loader.js.map +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 +32 -5
  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 +23 -23
  71. package/dist/esm/3d-tiles-converter/helpers/b3dm-converter.js.map +1 -1
  72. package/dist/esm/i3s-attributes-worker.js +16 -0
  73. package/dist/esm/i3s-attributes-worker.js.map +1 -0
  74. package/dist/esm/i3s-converter/helpers/coordinate-converter.js +19 -11
  75. package/dist/esm/i3s-converter/helpers/coordinate-converter.js.map +1 -1
  76. package/dist/esm/i3s-converter/helpers/geometry-attributes.js +2 -2
  77. package/dist/esm/i3s-converter/helpers/geometry-attributes.js.map +1 -1
  78. package/dist/esm/i3s-converter/helpers/geometry-converter.js +117 -58
  79. package/dist/esm/i3s-converter/helpers/geometry-converter.js.map +1 -1
  80. package/dist/esm/i3s-converter/helpers/gltf-attributes.js +54 -0
  81. package/dist/esm/i3s-converter/helpers/gltf-attributes.js.map +1 -0
  82. package/dist/esm/i3s-converter/helpers/node-pages.js +12 -9
  83. package/dist/esm/i3s-converter/helpers/node-pages.js.map +1 -1
  84. package/dist/esm/i3s-converter/i3s-converter.js +115 -28
  85. package/dist/esm/i3s-converter/i3s-converter.js.map +1 -1
  86. package/dist/esm/index.js +1 -0
  87. package/dist/esm/index.js.map +1 -1
  88. package/dist/esm/lib/utils/compress-util.js +6 -8
  89. package/dist/esm/lib/utils/compress-util.js.map +1 -1
  90. package/dist/esm/lib/utils/file-utils.js +11 -1
  91. package/dist/esm/lib/utils/file-utils.js.map +1 -1
  92. package/dist/esm/lib/utils/lod-conversion-utils.js.map +1 -1
  93. package/dist/esm/lib/utils/queue.js +19 -0
  94. package/dist/esm/lib/utils/queue.js.map +1 -0
  95. package/dist/esm/lib/utils/statistic-utills.js.map +1 -1
  96. package/dist/esm/lib/utils/write-queue.js +88 -0
  97. package/dist/esm/lib/utils/write-queue.js.map +1 -0
  98. package/dist/esm/pgm-loader.js +1 -1
  99. package/dist/esm/pgm-loader.js.map +1 -1
  100. package/dist/esm/workers/3d-tiles-attributes-worker.js +5 -0
  101. package/dist/esm/workers/3d-tiles-attributes-worker.js.map +1 -0
  102. package/dist/esm/workers/i3s-attributes-worker.js +4 -0
  103. package/dist/esm/workers/i3s-attributes-worker.js.map +1 -0
  104. package/dist/i3s-attributes-worker.d.ts +33 -0
  105. package/dist/i3s-attributes-worker.d.ts.map +1 -0
  106. package/dist/i3s-attributes-worker.js +10 -0
  107. package/dist/i3s-attributes-worker.js.map +7 -0
  108. package/dist/i3s-converter/helpers/coordinate-converter.d.ts +41 -0
  109. package/dist/i3s-converter/helpers/coordinate-converter.d.ts.map +1 -0
  110. package/dist/i3s-converter/helpers/coordinate-converter.js +122 -0
  111. package/dist/i3s-converter/helpers/create-scene-server-path.d.ts +9 -0
  112. package/dist/i3s-converter/helpers/create-scene-server-path.d.ts.map +1 -0
  113. package/dist/i3s-converter/helpers/create-scene-server-path.js +28 -0
  114. package/dist/i3s-converter/helpers/geometry-attributes.d.ts +8 -0
  115. package/dist/i3s-converter/helpers/geometry-attributes.d.ts.map +1 -0
  116. package/dist/i3s-converter/helpers/geometry-attributes.js +177 -0
  117. package/dist/i3s-converter/helpers/geometry-converter.d.ts +29 -0
  118. package/dist/i3s-converter/helpers/geometry-converter.d.ts.map +1 -0
  119. package/dist/i3s-converter/helpers/geometry-converter.js +901 -0
  120. package/dist/i3s-converter/helpers/gltf-attributes.d.ts +9 -0
  121. package/dist/i3s-converter/helpers/gltf-attributes.d.ts.map +1 -0
  122. package/dist/i3s-converter/helpers/gltf-attributes.js +56 -0
  123. package/dist/i3s-converter/helpers/node-debug.d.ts +8 -0
  124. package/dist/i3s-converter/helpers/node-debug.d.ts.map +1 -0
  125. package/dist/i3s-converter/helpers/node-debug.js +114 -0
  126. package/dist/i3s-converter/helpers/node-pages.d.ts +117 -0
  127. package/dist/i3s-converter/helpers/node-pages.d.ts.map +1 -0
  128. package/dist/i3s-converter/helpers/node-pages.js +208 -0
  129. package/dist/i3s-converter/i3s-converter.d.ts +325 -0
  130. package/dist/i3s-converter/i3s-converter.d.ts.map +1 -0
  131. package/dist/i3s-converter/i3s-converter.js +1056 -0
  132. package/dist/i3s-converter/json-templates/layers.d.ts +95 -0
  133. package/dist/i3s-converter/json-templates/layers.d.ts.map +1 -0
  134. package/dist/i3s-converter/json-templates/layers.js +199 -0
  135. package/dist/i3s-converter/json-templates/metadata.d.ts +22 -0
  136. package/dist/i3s-converter/json-templates/metadata.d.ts.map +1 -0
  137. package/dist/i3s-converter/json-templates/metadata.js +25 -0
  138. package/dist/i3s-converter/json-templates/node.d.ts +61 -0
  139. package/dist/i3s-converter/json-templates/node.d.ts.map +1 -0
  140. package/dist/i3s-converter/json-templates/node.js +89 -0
  141. package/dist/i3s-converter/json-templates/scene-server.d.ts +28 -0
  142. package/dist/i3s-converter/json-templates/scene-server.d.ts.map +1 -0
  143. package/dist/i3s-converter/json-templates/scene-server.js +31 -0
  144. package/dist/i3s-converter/json-templates/shared-resources.d.ts +14 -0
  145. package/dist/i3s-converter/json-templates/shared-resources.d.ts.map +1 -0
  146. package/dist/i3s-converter/json-templates/shared-resources.js +129 -0
  147. package/dist/i3s-converter/json-templates/store.d.ts +95 -0
  148. package/dist/i3s-converter/json-templates/store.d.ts.map +1 -0
  149. package/dist/i3s-converter/json-templates/store.js +103 -0
  150. package/dist/i3s-converter/types.d.ts +114 -0
  151. package/dist/i3s-converter/types.d.ts.map +1 -0
  152. package/dist/i3s-converter/types.js +2 -0
  153. package/dist/i3s-server/app.d.ts +3 -0
  154. package/dist/i3s-server/app.d.ts.map +1 -0
  155. package/dist/i3s-server/app.js +14 -0
  156. package/dist/i3s-server/controllers/index-controller.d.ts +2 -0
  157. package/dist/i3s-server/controllers/index-controller.d.ts.map +1 -0
  158. package/dist/i3s-server/controllers/index-controller.js +23 -0
  159. package/dist/i3s-server/routes/index.d.ts +3 -0
  160. package/dist/i3s-server/routes/index.d.ts.map +1 -0
  161. package/dist/i3s-server/routes/index.js +16 -0
  162. package/dist/index.d.ts +6 -0
  163. package/dist/index.d.ts.map +1 -0
  164. package/dist/index.js +16 -0
  165. package/dist/lib/utils/compress-util.d.ts +45 -0
  166. package/dist/lib/utils/compress-util.d.ts.map +1 -0
  167. package/dist/lib/utils/compress-util.js +257 -0
  168. package/{src → dist}/lib/utils/file-utils.d.ts +6 -14
  169. package/dist/lib/utils/file-utils.d.ts.map +1 -0
  170. package/dist/lib/utils/file-utils.js +81 -0
  171. package/dist/lib/utils/lod-conversion-utils.d.ts +41 -0
  172. package/dist/lib/utils/lod-conversion-utils.d.ts.map +1 -0
  173. package/dist/lib/utils/lod-conversion-utils.js +76 -0
  174. package/dist/lib/utils/queue.d.ts +7 -0
  175. package/dist/lib/utils/queue.d.ts.map +1 -0
  176. package/dist/lib/utils/queue.js +18 -0
  177. package/dist/lib/utils/statistic-utills.d.ts +3 -0
  178. package/dist/lib/utils/statistic-utills.d.ts.map +1 -0
  179. package/dist/lib/utils/statistic-utills.js +64 -0
  180. package/dist/lib/utils/write-queue.d.ts +22 -0
  181. package/dist/lib/utils/write-queue.d.ts.map +1 -0
  182. package/dist/lib/utils/write-queue.js +62 -0
  183. package/dist/pgm-loader.d.ts +6 -0
  184. package/dist/pgm-loader.d.ts.map +1 -0
  185. package/dist/pgm-loader.js +23 -0
  186. package/dist/workers/3d-tiles-attributes-worker.d.ts +2 -0
  187. package/dist/workers/3d-tiles-attributes-worker.d.ts.map +1 -0
  188. package/dist/workers/3d-tiles-attributes-worker.js +9 -0
  189. package/dist/workers/i3s-attributes-worker.d.ts +2 -0
  190. package/dist/workers/i3s-attributes-worker.d.ts.map +1 -0
  191. package/dist/workers/i3s-attributes-worker.js +5 -0
  192. package/package.json +20 -18
  193. package/src/3d-tiles-attributes-worker.ts +43 -0
  194. package/src/3d-tiles-converter/3d-tiles-converter.ts +48 -5
  195. package/src/3d-tiles-converter/helpers/b3dm-converter.ts +21 -18
  196. package/src/i3s-attributes-worker.ts +46 -0
  197. package/src/i3s-converter/helpers/coordinate-converter.ts +29 -24
  198. package/src/i3s-converter/helpers/geometry-attributes.ts +4 -3
  199. package/src/i3s-converter/helpers/{geometry-converter.js → geometry-converter.ts} +421 -175
  200. package/src/i3s-converter/helpers/gltf-attributes.ts +68 -0
  201. package/src/i3s-converter/helpers/node-pages.ts +25 -17
  202. package/src/i3s-converter/i3s-converter.ts +124 -69
  203. package/src/i3s-converter/types.ts +90 -8
  204. package/src/index.ts +1 -0
  205. package/src/lib/utils/{compress-util.js → compress-util.ts} +105 -18
  206. package/src/lib/utils/file-utils.ts +84 -0
  207. package/src/lib/utils/{lod-conversion-utils.js → lod-conversion-utils.ts} +27 -5
  208. package/src/lib/utils/queue.ts +17 -0
  209. package/src/lib/utils/{statistic-utills.js → statistic-utills.ts} +0 -0
  210. package/src/lib/utils/write-queue.ts +75 -0
  211. package/src/workers/3d-tiles-attributes-worker.ts +6 -0
  212. package/src/workers/i3s-attributes-worker.ts +6 -0
  213. package/dist/es5/i3s-converter/helpers/geometry-converter.d.ts +0 -44
  214. package/dist/es5/lib/utils/compress-util.d.ts +0 -53
  215. package/dist/es5/lib/utils/file-utils.d.ts +0 -43
  216. package/dist/es5/lib/utils/lod-conversion-utils.d.ts +0 -32
  217. package/dist/esm/i3s-converter/helpers/geometry-converter.d.ts +0 -44
  218. package/dist/esm/lib/utils/compress-util.d.ts +0 -53
  219. package/dist/esm/lib/utils/file-utils.d.ts +0 -43
  220. package/dist/esm/lib/utils/lod-conversion-utils.d.ts +0 -32
  221. package/src/i3s-converter/helpers/geometry-converter.d.ts +0 -44
  222. package/src/lib/utils/compress-util.d.ts +0 -53
  223. package/src/lib/utils/file-utils.js +0 -38
  224. package/src/lib/utils/lod-conversion-utils.d.ts +0 -32
@@ -0,0 +1,68 @@
1
+ import type {B3DMContent} from '@loaders.gl/3d-tiles';
2
+ import type {Accessor} from 'modules/gltf/src/lib/types/gltf-postprocessed-schema';
3
+ import type {B3DMAttributesData} from '../../i3s-attributes-worker';
4
+
5
+ type AttributesObject = {
6
+ [k: string]: Accessor;
7
+ };
8
+
9
+ /**
10
+ * Keep only values for B3DM attributes to pass data to worker thread.
11
+ * @param attributes
12
+ */
13
+ function getB3DMAttributesWithoutBufferView(attributes: AttributesObject): AttributesObject {
14
+ const attributesWithoutBufferView = {};
15
+
16
+ for (const attributeName in attributes) {
17
+ attributesWithoutBufferView[attributeName] = {
18
+ value: attributes[attributeName].value
19
+ };
20
+ }
21
+
22
+ return attributesWithoutBufferView;
23
+ }
24
+
25
+ /**
26
+ * Prepare attributes for conversion to avoid binary data breaking in worker thread.
27
+ * @param tileContent
28
+ * @returns
29
+ */
30
+ export function prepareDataForAttributesConversion(tileContent: B3DMContent): B3DMAttributesData {
31
+ const gltfMaterials = tileContent.gltf?.materials?.map((material) => ({id: material.id}));
32
+ let nodes =
33
+ tileContent.gltf?.scene?.nodes ||
34
+ tileContent.gltf?.scenes?.[0]?.nodes ||
35
+ tileContent.gltf?.nodes ||
36
+ [];
37
+
38
+ const prepearedNodes = nodes.map((node) => {
39
+ if (!node.mesh) {
40
+ return node;
41
+ }
42
+
43
+ return {
44
+ ...node,
45
+ mesh: {
46
+ ...node.mesh,
47
+ primitives: node.mesh?.primitives.map((primitive) => ({
48
+ ...primitive,
49
+ indices: {value: primitive?.indices?.value},
50
+ attributes: getB3DMAttributesWithoutBufferView(primitive.attributes),
51
+ material: {
52
+ id: primitive?.material?.id
53
+ }
54
+ }))
55
+ }
56
+ };
57
+ });
58
+
59
+ const cartographicOrigin = tileContent.cartographicOrigin;
60
+ const cartesianModelMatrix = tileContent.cartesianModelMatrix;
61
+
62
+ return {
63
+ gltfMaterials,
64
+ nodes: prepearedNodes,
65
+ cartographicOrigin,
66
+ cartesianModelMatrix
67
+ };
68
+ }
@@ -1,7 +1,10 @@
1
+ import type {WriteQueueItem} from '../../lib/utils/write-queue';
2
+
1
3
  import {join} from 'path';
2
4
  import transform from 'json-map-transform';
3
5
  import {METADATA as metadataTemplate} from '../json-templates/metadata';
4
6
  import {NodeInPage} from '@loaders.gl/i3s';
7
+ import WriteQueue from '../../lib/utils/write-queue';
5
8
 
6
9
  // @ts-nocheck
7
10
  /**
@@ -188,36 +191,41 @@ export default class NodePages {
188
191
  /**
189
192
  * Save all the node pages
190
193
  * Run this method when all nodes is pushed in nodePages
191
- * @param {string} layers0Path - path of layer
192
- * @param {Object} fileMap - fileMap which keep info for slpk archive
193
- * @param {boolean} slpk
194
- * @return {promise}
194
+ * @param layers0Path - path of layer
195
+ * @param writeQueue - write queue that controlls files write concurrency
196
+ * @param slpk
195
197
  */
196
- async save(layers0Path: string, fileMap: Object, slpk: boolean = false): Promise<void> {
197
- const promises: Promise<any>[] = [];
198
+ async save(
199
+ layers0Path: string,
200
+ writeQueue: WriteQueue<WriteQueueItem>,
201
+ slpk: boolean = false
202
+ ): Promise<void> {
198
203
  if (slpk) {
199
204
  for (const [index, nodePage] of this.nodePages.entries()) {
200
205
  const nodePageStr = JSON.stringify(nodePage);
201
206
  const slpkPath = join(layers0Path, 'nodepages');
202
- promises.push(this.writeFile(slpkPath, nodePageStr, `${index.toString()}.json`));
203
- fileMap[`nodePages/${index.toString()}.json.gz`] = `${slpkPath}.json.gz`;
207
+ writeQueue.enqueue({
208
+ archiveKey: `nodePages/${index.toString()}.json.gz`,
209
+ writePromise: this.writeFile(slpkPath, nodePageStr, `${index.toString()}.json`)
210
+ });
204
211
  }
205
212
  const metadata = transform({nodeCount: this.nodesCounter}, metadataTemplate());
206
213
  const compress = false;
207
- fileMap['metadata.json'] = await this.writeFile(
208
- layers0Path,
209
- JSON.stringify(metadata),
210
- 'metadata.json',
211
- compress
212
- );
214
+ writeQueue.enqueue({
215
+ archiveKey: 'metadata.json',
216
+ writePromise: this.writeFile(
217
+ layers0Path,
218
+ JSON.stringify(metadata),
219
+ 'metadata.json',
220
+ compress
221
+ )
222
+ });
213
223
  } else {
214
224
  for (const [index, nodePage] of this.nodePages.entries()) {
215
225
  const nodePageStr = JSON.stringify(nodePage);
216
226
  const nodePagePath = join(layers0Path, 'nodepages', index.toString());
217
- promises.push(this.writeFile(nodePagePath, nodePageStr));
227
+ writeQueue.enqueue({writePromise: this.writeFile(nodePagePath, nodePageStr)});
218
228
  }
219
229
  }
220
-
221
- await Promise.all(promises);
222
230
  }
223
231
  }
@@ -1,6 +1,6 @@
1
1
  import type {Tile3D, Tileset3DProps} from '@loaders.gl/tiles';
2
2
  import type {BatchTableJson, B3DMContent} from '@loaders.gl/3d-tiles';
3
-
3
+ import type {WriteQueueItem} from '../lib/utils/write-queue';
4
4
  import type {
5
5
  AttributeStorageInfo,
6
6
  SceneLayer3D,
@@ -10,14 +10,13 @@ import type {
10
10
  MaxScreenThresholdSQ,
11
11
  NodeInPage,
12
12
  LodSelection,
13
- SharedResources,
14
13
  Attribute,
15
14
  ESRIField,
16
15
  Field,
17
16
  PopupInfo,
18
17
  FieldInfo
19
18
  } from '@loaders.gl/i3s';
20
- import {load, encode} from '@loaders.gl/core';
19
+ import {load, encode, fetchFile, getLoaderOptions} from '@loaders.gl/core';
21
20
  import {Tileset3D} from '@loaders.gl/tiles';
22
21
  import {CesiumIonLoader, Tiles3DLoader} from '@loaders.gl/3d-tiles';
23
22
  import {Geoid} from '@math.gl/geoid';
@@ -38,7 +37,7 @@ import {calculateFilesSize, timeConverter} from '../lib/utils/statistic-utills';
38
37
  import convertB3dmToI3sGeometry from './helpers/geometry-converter';
39
38
  import {
40
39
  createBoundingVolumes,
41
- convertCommonToI3SExtentCoordinate
40
+ convertBoundingVolumeToI3SFullExtent
42
41
  } from './helpers/coordinate-converter';
43
42
  import {createSceneServerPath} from './helpers/create-scene-server-path';
44
43
  import {convertGeometricErrorToScreenThreshold} from '../lib/utils/lod-conversion-utils';
@@ -49,12 +48,16 @@ import {NODE as nodeTemplate} from './json-templates/node';
49
48
  import {SHARED_RESOURCES as sharedResourcesTemplate} from './json-templates/shared-resources';
50
49
  import {validateNodeBoundingVolumes} from './helpers/node-debug';
51
50
  import TileHeader from '@loaders.gl/tiles/src/tileset/tile-3d';
52
- import {KTX2BasisUniversalTextureWriter} from '@loaders.gl/textures';
51
+ import {KTX2BasisWriter} from '@loaders.gl/textures';
53
52
  import {LoaderWithParser} from '@loaders.gl/loader-utils';
54
53
  import {I3SMaterialDefinition, TextureSetDefinitionFormats} from '@loaders.gl/i3s/src/types';
55
54
  import {ImageWriter} from '@loaders.gl/images';
56
55
  import {GLTFImagePostprocessed} from '@loaders.gl/gltf';
57
- import {I3SConvertedResources} from './types';
56
+ import {I3SConvertedResources, SharedResourcesArrays} from './types';
57
+ import {getWorkerURL, WorkerFarm} from '@loaders.gl/worker-utils';
58
+ import {DracoWriterWorker} from '@loaders.gl/draco';
59
+ import WriteQueue from '../lib/utils/write-queue';
60
+ import {I3SAttributesWorker} from '../i3s-attributes-worker';
58
61
 
59
62
  const ION_DEFAULT_TOKEN =
60
63
  process.env.IonToken || // eslint-disable-line
@@ -75,7 +78,6 @@ const CESIUM_DATASET_PREFIX = 'https://';
75
78
  */
76
79
  export default class I3SConverter {
77
80
  nodePages: NodePages;
78
- fileMap: {[key: string]: string};
79
81
  options: any;
80
82
  layers0Path: string;
81
83
  materialMap: Map<any, any>;
@@ -96,10 +98,12 @@ export default class I3SConverter {
96
98
  Loader: LoaderWithParser = Tiles3DLoader;
97
99
  generateTextures: boolean;
98
100
  generateBoundingVolumes: boolean;
101
+ layersHasTexture: boolean;
102
+ workerSource: {[key: string]: string} = {};
103
+ writeQueue: WriteQueue<WriteQueueItem> = new WriteQueue();
99
104
 
100
105
  constructor() {
101
106
  this.nodePages = new NodePages(writeFile, HARDCODED_NODES_PER_PAGE);
102
- this.fileMap = {};
103
107
  this.options = {};
104
108
  this.layers0Path = '';
105
109
  this.materialMap = new Map();
@@ -114,6 +118,7 @@ export default class I3SConverter {
114
118
  this.validate = false;
115
119
  this.generateTextures = false;
116
120
  this.generateBoundingVolumes = false;
121
+ this.layersHasTexture = false;
117
122
  }
118
123
 
119
124
  /**
@@ -167,6 +172,9 @@ export default class I3SConverter {
167
172
  this.generateTextures = Boolean(generateTextures);
168
173
  this.generateBoundingVolumes = Boolean(generateBoundingVolumes);
169
174
 
175
+ this.writeQueue = new WriteQueue();
176
+ this.writeQueue.startListening();
177
+
170
178
  console.log('Loading egm file...'); // eslint-disable-line
171
179
  this.geoidHeightModel = await load(egmFilePath, PGMLoader);
172
180
  console.log('Loading egm file completed!'); // eslint-disable-line
@@ -175,6 +183,8 @@ export default class I3SConverter {
175
183
  this.nodePages.useWriteFunction(writeFileForSlpk);
176
184
  }
177
185
 
186
+ await this.loadWorkers();
187
+
178
188
  const preloadOptions = await this._fetchPreloadOptions();
179
189
  const tilesetOptions: Tileset3DProps = {loadOptions: {basis: {format: 'rgba32'}}};
180
190
  if (preloadOptions.headers) {
@@ -187,6 +197,11 @@ export default class I3SConverter {
187
197
 
188
198
  await this._createAndSaveTileset(outputPath, tilesetName);
189
199
  await this._finishConversion({slpk: Boolean(slpk), outputPath, tilesetName});
200
+
201
+ // Clean up worker pools
202
+ const workerFarm = WorkerFarm.getWorkerFarm({});
203
+ workerFarm.destroy();
204
+
190
205
  return sourceTilesetJson;
191
206
  }
192
207
 
@@ -226,10 +241,19 @@ export default class I3SConverter {
226
241
  await this._convertNodesTree(root0, sourceRootTile, parentId, boundingVolumes);
227
242
 
228
243
  this.layers0!.materialDefinitions = this.materialDefinitions;
244
+
245
+ if (this.layersHasTexture === false) {
246
+ this.layers0!.store.defaultGeometrySchema.ordering =
247
+ this.layers0!.store.defaultGeometrySchema.ordering.filter(
248
+ (attribute) => attribute !== 'uv0'
249
+ );
250
+ }
251
+
229
252
  await this._writeLayers0();
230
253
  createSceneServerPath(tilesetName, this.layers0!, tilesetPath);
231
254
  await this._writeNodeIndexDocument(root0, 'root', join(this.layers0Path, 'nodes', 'root'));
232
- await this.nodePages.save(this.layers0Path, this.fileMap, isCreateSlpk);
255
+ await this.nodePages.save(this.layers0Path, this.writeQueue, isCreateSlpk);
256
+ await this.writeQueue.finalize();
233
257
  await this._createSlpk(tilesetPath);
234
258
  }
235
259
 
@@ -238,7 +262,10 @@ export default class I3SConverter {
238
262
  * @param tilesetName - Name of layer
239
263
  */
240
264
  private _formLayers0(tilesetName: string): void {
241
- const extent = convertCommonToI3SExtentCoordinate(this.sourceTileset);
265
+ const fullExtent = convertBoundingVolumeToI3SFullExtent(
266
+ this.sourceTileset?.boundingVolume || this.sourceTileset?.root?.boundingVolume
267
+ );
268
+ const extent = [fullExtent.xmin, fullExtent.ymin, fullExtent.xmax, fullExtent.ymax];
242
269
  const layers0data = {
243
270
  version: `{${uuidv4().toUpperCase()}}`,
244
271
  id: 0,
@@ -308,13 +335,16 @@ export default class I3SConverter {
308
335
  const childPath = join(this.layers0Path, 'nodes', child.path!);
309
336
 
310
337
  if (this.options.slpk) {
311
- this.fileMap['nodes/1/3dNodeIndexDocument.json.gz'] = await writeFileForSlpk(
312
- childPath,
313
- JSON.stringify(child),
314
- '3dNodeIndexDocument.json'
315
- );
338
+ this.writeQueue.enqueue({
339
+ archiveKey: 'nodes/1/3dNodeIndexDocument.json.gz',
340
+ writePromise: writeFileForSlpk(
341
+ childPath,
342
+ JSON.stringify(child),
343
+ '3dNodeIndexDocument.json'
344
+ )
345
+ });
316
346
  } else {
317
- await writeFile(childPath, JSON.stringify(child));
347
+ this.writeQueue.enqueue({writePromise: writeFile(childPath, JSON.stringify(child))});
318
348
  }
319
349
  } else {
320
350
  await this._addChildrenWithNeighborsAndWriteFile({
@@ -332,13 +362,18 @@ export default class I3SConverter {
332
362
  */
333
363
  private async _writeLayers0(): Promise<void> {
334
364
  if (this.options.slpk) {
335
- this.fileMap['3dSceneLayer.json.gz'] = await writeFileForSlpk(
336
- this.layers0Path,
337
- JSON.stringify(this.layers0),
338
- '3dSceneLayer.json'
339
- );
365
+ this.writeQueue.enqueue({
366
+ archiveKey: '3dSceneLayer.json.gz',
367
+ writePromise: writeFileForSlpk(
368
+ this.layers0Path,
369
+ JSON.stringify(this.layers0),
370
+ '3dSceneLayer.json'
371
+ )
372
+ });
340
373
  } else {
341
- await writeFile(this.layers0Path, JSON.stringify(this.layers0));
374
+ this.writeQueue.enqueue({
375
+ writePromise: writeFile(this.layers0Path, JSON.stringify(this.layers0))
376
+ });
342
377
  }
343
378
  }
344
379
 
@@ -351,13 +386,12 @@ export default class I3SConverter {
351
386
  rootPath: string
352
387
  ): Promise<void> {
353
388
  if (this.options.slpk) {
354
- this.fileMap[`nodes/${nodePath}/3dNodeIndexDocument.json.gz`] = await writeFileForSlpk(
355
- rootPath,
356
- JSON.stringify(root0),
357
- '3dNodeIndexDocument.json'
358
- );
389
+ this.writeQueue.enqueue({
390
+ archiveKey: `nodes/${nodePath}/3dNodeIndexDocument.json.gz`,
391
+ writePromise: writeFileForSlpk(rootPath, JSON.stringify(root0), '3dNodeIndexDocument.json')
392
+ });
359
393
  } else {
360
- await writeFile(rootPath, JSON.stringify(root0));
394
+ this.writeQueue.enqueue({writePromise: writeFile(rootPath, JSON.stringify(root0))});
361
395
  }
362
396
  }
363
397
 
@@ -374,7 +408,6 @@ export default class I3SConverter {
374
408
  slpkFileName,
375
409
  0,
376
410
  '.',
377
- // @ts-expect-error
378
411
  this.options.sevenZipExe
379
412
  );
380
413
 
@@ -556,6 +589,8 @@ export default class I3SConverter {
556
589
  };
557
590
 
558
591
  for (const resources of resourcesData || [emptyResources]) {
592
+ this.layersHasTexture = this.layersHasTexture || Boolean(resources.texture);
593
+
559
594
  if (this.generateBoundingVolumes && resources.boundingVolumes) {
560
595
  boundingVolumes = resources.boundingVolumes;
561
596
  }
@@ -644,7 +679,8 @@ export default class I3SConverter {
644
679
  this.layers0?.attributeStorageInfo,
645
680
  this.options.draco,
646
681
  this.generateBoundingVolumes,
647
- this.geoidHeightModel!
682
+ this.geoidHeightModel!,
683
+ this.workerSource
648
684
  );
649
685
  return resourcesData;
650
686
  }
@@ -794,7 +830,7 @@ export default class I3SConverter {
794
830
  const slpkChildPath = join('nodes', nodePath);
795
831
 
796
832
  await this._writeGeometries(geometryBuffer!, compressedGeometry!, childPath, slpkChildPath);
797
- await this._writeShared(sharedResources!, childPath, slpkChildPath, nodePath);
833
+ await this._writeShared(sharedResources, childPath, slpkChildPath, nodePath);
798
834
  await this._writeTexture(texture, childPath, slpkChildPath);
799
835
  await this._writeAttributes(attributes, childPath, slpkChildPath);
800
836
  }
@@ -808,33 +844,35 @@ export default class I3SConverter {
808
844
  */
809
845
  private async _writeGeometries(
810
846
  geometryBuffer: ArrayBuffer,
811
- compressedGeometry: ArrayBuffer,
847
+ compressedGeometry: Promise<ArrayBuffer>,
812
848
  childPath: string,
813
849
  slpkChildPath: string
814
850
  ): Promise<void> {
815
851
  if (this.options.slpk) {
816
852
  const slpkGeometryPath = join(childPath, 'geometries');
817
- this.fileMap[`${slpkChildPath}/geometries/0.bin.gz`] = await writeFileForSlpk(
818
- slpkGeometryPath,
819
- geometryBuffer,
820
- '0.bin'
821
- );
853
+ this.writeQueue.enqueue({
854
+ archiveKey: `${slpkChildPath}/geometries/0.bin.gz`,
855
+ writePromise: writeFileForSlpk(slpkGeometryPath, geometryBuffer, '0.bin')
856
+ });
822
857
  } else {
823
858
  const geometryPath = join(childPath, 'geometries/0/');
824
- await writeFile(geometryPath, geometryBuffer, 'index.bin');
859
+ this.writeQueue.enqueue({
860
+ writePromise: writeFile(geometryPath, geometryBuffer, 'index.bin')
861
+ });
825
862
  }
826
863
 
827
864
  if (this.options.draco) {
828
865
  if (this.options.slpk) {
829
866
  const slpkCompressedGeometryPath = join(childPath, 'geometries');
830
- this.fileMap[`${slpkChildPath}/geometries/1.bin.gz`] = await writeFileForSlpk(
831
- slpkCompressedGeometryPath,
832
- compressedGeometry,
833
- '1.bin'
834
- );
867
+ this.writeQueue.enqueue({
868
+ archiveKey: `${slpkChildPath}/geometries/1.bin.gz`,
869
+ writePromise: writeFileForSlpk(slpkCompressedGeometryPath, compressedGeometry, '1.bin')
870
+ });
835
871
  } else {
836
872
  const compressedGeometryPath = join(childPath, 'geometries/1/');
837
- await writeFile(compressedGeometryPath, compressedGeometry, 'index.bin');
873
+ this.writeQueue.enqueue({
874
+ writePromise: writeFile(compressedGeometryPath, compressedGeometry, 'index.bin')
875
+ });
838
876
  }
839
877
  }
840
878
  }
@@ -847,24 +885,26 @@ export default class I3SConverter {
847
885
  * @param nodePath - a node path
848
886
  */
849
887
  private async _writeShared(
850
- sharedResources: SharedResources,
888
+ sharedResources: SharedResourcesArrays | null,
851
889
  childPath: string,
852
890
  slpkChildPath: string,
853
891
  nodePath: string
854
892
  ): Promise<void> {
893
+ if (!sharedResources) {
894
+ return;
895
+ }
855
896
  sharedResources.nodePath = nodePath;
856
897
  const sharedData = transform(sharedResources, sharedResourcesTemplate());
857
898
  const sharedDataStr = JSON.stringify(sharedData);
858
899
  if (this.options.slpk) {
859
900
  const slpkSharedPath = join(childPath, 'shared');
860
- this.fileMap[`${slpkChildPath}/shared/sharedResource.json.gz`] = await writeFileForSlpk(
861
- slpkSharedPath,
862
- sharedDataStr,
863
- 'sharedResource.json'
864
- );
901
+ this.writeQueue.enqueue({
902
+ archiveKey: `${slpkChildPath}/shared/sharedResource.json.gz`,
903
+ writePromise: writeFileForSlpk(slpkSharedPath, sharedDataStr, 'sharedResource.json')
904
+ });
865
905
  } else {
866
906
  const sharedPath = join(childPath, 'shared/');
867
- await writeFile(sharedPath, sharedDataStr);
907
+ this.writeQueue.enqueue({writePromise: writeFile(sharedPath, sharedDataStr)});
868
908
  }
869
909
  }
870
910
 
@@ -892,9 +932,7 @@ export default class I3SConverter {
892
932
 
893
933
  if (this.generateTextures) {
894
934
  formats.push({name: '1', format: 'ktx2'});
895
- const ktx2TextureData = new Uint8Array(
896
- await encode(texture.image, KTX2BasisUniversalTextureWriter)
897
- );
935
+ const ktx2TextureData = new Uint8Array(await encode(texture.image, KTX2BasisWriter));
898
936
  await this.writeTextureFile(ktx2TextureData, '1', 'ktx2', childPath, slpkChildPath);
899
937
  }
900
938
 
@@ -946,15 +984,15 @@ export default class I3SConverter {
946
984
  const slpkTexturePath = join(childPath, 'textures');
947
985
  const compress = false;
948
986
 
949
- this.fileMap[`${slpkChildPath}/textures/${name}.${format}`] = await writeFileForSlpk(
950
- slpkTexturePath,
951
- textureData,
952
- `${name}.${format}`,
953
- compress
954
- );
987
+ this.writeQueue.enqueue({
988
+ archiveKey: `${slpkChildPath}/textures/${name}.${format}`,
989
+ writePromise: writeFileForSlpk(slpkTexturePath, textureData, `${name}.${format}`, compress)
990
+ });
955
991
  } else {
956
992
  const texturePath = join(childPath, `textures/${name}/`);
957
- await writeFile(texturePath, textureData, `index.${format}`);
993
+ this.writeQueue.enqueue({
994
+ writePromise: writeFile(texturePath, textureData, `index.${format}`)
995
+ });
958
996
  }
959
997
  }
960
998
 
@@ -965,25 +1003,26 @@ export default class I3SConverter {
965
1003
  * @param slpkChildPath - the resource path inside *slpk file
966
1004
  */
967
1005
  private async _writeAttributes(
968
- attributes: ArrayBuffer[],
1006
+ attributes: ArrayBuffer[] | null = [],
969
1007
  childPath: string,
970
1008
  slpkChildPath: string
971
1009
  ): Promise<void> {
972
- if (attributes.length && this.layers0?.attributeStorageInfo?.length) {
1010
+ if (attributes?.length && this.layers0?.attributeStorageInfo?.length) {
973
1011
  for (let index = 0; index < attributes.length; index++) {
974
1012
  const folderName = this.layers0.attributeStorageInfo[index].key;
975
1013
  const fileBuffer = new Uint8Array(attributes[index]);
976
1014
 
977
1015
  if (this.options.slpk) {
978
1016
  const slpkAttributesPath = join(childPath, 'attributes', folderName);
979
- this.fileMap[`${slpkChildPath}/attributes/${folderName}.bin.gz`] = await writeFileForSlpk(
980
- slpkAttributesPath,
981
- fileBuffer,
982
- '0.bin'
983
- );
1017
+ this.writeQueue.enqueue({
1018
+ archiveKey: `${slpkChildPath}/attributes/${folderName}.bin.gz`,
1019
+ writePromise: writeFileForSlpk(slpkAttributesPath, fileBuffer, '0.bin')
1020
+ });
984
1021
  } else {
985
1022
  const attributesPath = join(childPath, `attributes/${folderName}/0`);
986
- await writeFile(attributesPath, fileBuffer, 'index.bin');
1023
+ this.writeQueue.enqueue({
1024
+ writePromise: writeFile(attributesPath, fileBuffer, 'index.bin')
1025
+ });
987
1026
  }
988
1027
  }
989
1028
  }
@@ -1297,4 +1336,20 @@ export default class I3SConverter {
1297
1336
  private isContentSupported(sourceRootTile: Tile3D): boolean {
1298
1337
  return ['b3dm', 'glTF'].includes(sourceRootTile?.content?.type);
1299
1338
  }
1339
+
1340
+ private async loadWorkers(): Promise<void> {
1341
+ console.log(`Loading workers source...`); // eslint-disable-line no-undef, no-console
1342
+ if (this.options.draco) {
1343
+ const url = getWorkerURL(DracoWriterWorker, {...getLoaderOptions()});
1344
+ const sourceResponse = await fetchFile(url);
1345
+ const source = await sourceResponse.text();
1346
+ this.workerSource.draco = source;
1347
+ }
1348
+
1349
+ const i3sAttributesWorkerUrl = getWorkerURL(I3SAttributesWorker, {...getLoaderOptions()});
1350
+ const sourceResponse = await fetchFile(i3sAttributesWorkerUrl);
1351
+ const source = await sourceResponse.text();
1352
+ this.workerSource.I3SAttributes = source;
1353
+ console.log(`Loading workers source completed!`); // eslint-disable-line no-undef, no-console
1354
+ }
1300
1355
  }
@@ -1,42 +1,124 @@
1
- import {BoundingVolumes, I3SMaterialDefinition, SharedResources} from '@loaders.gl/i3s';
1
+ import {
2
+ BoundingVolumes,
3
+ I3SMaterialDefinition,
4
+ MaterialDefinitionInfo,
5
+ TextureDefinitionInfo
6
+ } from '@loaders.gl/i3s';
7
+ import {ImageDataType} from '@loaders.gl/images';
2
8
 
9
+ /** Converted resources for specific node */
3
10
  export type I3SConvertedResources = {
11
+ /** Non-compressed geometry buffer that have structure met
12
+ * https://github.com/Esri/i3s-spec/blob/master/docs/1.8/defaultGeometrySchema.cmn.md
13
+ * (Geometry buffer)
14
+ */
4
15
  geometry: ArrayBuffer | null;
5
- compressedGeometry?: ArrayBuffer | null;
16
+ /**
17
+ * Draco compressed geometry
18
+ */
19
+ compressedGeometry?: Promise<ArrayBuffer> | null;
20
+ /**
21
+ * Texture image content
22
+ */
6
23
  texture: any | null;
7
- sharedResources: SharedResources | null;
24
+ /**
25
+ * Shared resources built from GLTF material
26
+ */
27
+ sharedResources: SharedResourcesArrays | null;
28
+ /**
29
+ * Material definition of the node
30
+ */
8
31
  meshMaterial?: I3SMaterialDefinition | null;
32
+ /**
33
+ * Number of vertices in the node
34
+ */
9
35
  vertexCount: number | null;
10
- attributes: any | null;
36
+ /**
37
+ * Feature attributes contents
38
+ */
39
+ attributes: ArrayBuffer[] | null;
40
+ /**
41
+ * Number of features in the node
42
+ */
11
43
  featureCount: number | null;
12
- geometryBuffer?: ArrayBuffer;
44
+ /**
45
+ * MBS and/or OBB bounding volumes of the node
46
+ */
13
47
  boundingVolumes: BoundingVolumes | null;
14
48
  };
15
49
 
16
- export type AttributesData = {
50
+ /**
51
+ * Geometry and feature attributes converted from GLTF primitives
52
+ */
53
+ export type ConvertedAttributes = {
54
+ /** POSITION attribute value */
17
55
  positions: Float32Array;
56
+ /** NORMAL attribute value */
18
57
  normals: Float32Array;
58
+ /** TEXCOORD_0 attribute value */
19
59
  texCoords: Float32Array;
60
+ /** COLOR_0 attribute value */
20
61
  colors: Uint8Array;
62
+ /** Feature indices grouped by ...
63
+ * converted from "batch ids" of GLTF
64
+ */
65
+ featureIndicesGroups?: number[][];
66
+ /** Feature indices converted from "batch ids" */
21
67
  featureIndices: number[];
22
- triangleCount: number;
23
- boundingVolumes?: BoundingVolumes | null;
68
+ /**
69
+ * MBS and/or OBB bounding volumes of the node
70
+ */
71
+ boundingVolumes: null | BoundingVolumes;
24
72
  };
25
73
 
74
+ /** Postprocessed geometry and feature attributes
75
+ * https://github.com/Esri/i3s-spec/blob/master/docs/1.8/defaultGeometrySchema.cmn.md
76
+ */
26
77
  export type GeometryAttributes = {
78
+ /** POSITION attribute value */
27
79
  positions: Float32Array;
80
+ /** NORMAL attribute value */
28
81
  normals: Float32Array;
82
+ /** TEXCOORD_0 attribute value */
29
83
  texCoords: Float32Array;
84
+ /** COLOR_0 attribute value */
30
85
  colors: Uint8Array;
86
+ /** faceRanges attribute value */
31
87
  faceRange: Uint32Array;
88
+ /** feature Ids attribute value */
32
89
  featureIds: number[];
90
+ /** number of features in the node */
33
91
  featureCount: number;
34
92
  };
35
93
 
94
+ /** Geometry attributes specific for the particular feature */
36
95
  export type GroupedByFeatureIdAttributes = {
96
+ /** Feature Id */
37
97
  featureId: number;
98
+ /** POSITION attribute value */
38
99
  positions: Float32Array;
100
+ /** NORMAL attribute value */
39
101
  normals: Float32Array;
102
+ /** COLOR_0 attribute value */
40
103
  colors: Uint8Array;
104
+ /** TEXCOORD_0 attribute value */
41
105
  texCoords: Float32Array;
42
106
  };
107
+
108
+ /** Shared resources made from GLTF material */
109
+ export type SharedResourcesArrays = {
110
+ /** material definitions list https://github.com/Esri/i3s-spec/blob/master/docs/1.8/materialDefinitionInfo.cmn.md */
111
+ materialDefinitionInfos?: MaterialDefinitionInfo[];
112
+ /** texture definitions list https://github.com/Esri/i3s-spec/blob/master/docs/1.8/textureDefinitionInfo.cmn.md*/
113
+ textureDefinitionInfos?: TextureDefinitionInfo[];
114
+ /** node id to make unique SharedResource ids */
115
+ nodePath?: string;
116
+ };
117
+
118
+ /** I3S material definition and texture content taken from GLTF material */
119
+ export type I3SMaterialWithTexture = {
120
+ /** Material definition https://github.com/Esri/i3s-spec/blob/master/docs/1.8/materialDefinitions.cmn.md */
121
+ material: I3SMaterialDefinition;
122
+ /** Texture content (image) */
123
+ texture?: ImageDataType;
124
+ };