@loaders.gl/i3s 4.0.0-alpha.4 → 4.0.0-alpha.6

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 (186) hide show
  1. package/dist/arcgis-webscene-loader.d.ts +7 -0
  2. package/dist/arcgis-webscene-loader.d.ts.map +1 -0
  3. package/dist/arcgis-webscene-loader.js +28 -0
  4. package/dist/bundle.d.ts +2 -0
  5. package/dist/bundle.d.ts.map +1 -0
  6. package/dist/bundle.js +2 -2
  7. package/dist/dist.min.js +10631 -0
  8. package/dist/es5/arcgis-webscene-loader.js +40 -0
  9. package/dist/es5/arcgis-webscene-loader.js.map +1 -0
  10. package/dist/es5/bundle.js +6 -0
  11. package/dist/es5/bundle.js.map +1 -0
  12. package/dist/es5/i3s-attribute-loader.js +195 -0
  13. package/dist/es5/i3s-attribute-loader.js.map +1 -0
  14. package/dist/es5/i3s-building-scene-layer-loader.js +46 -0
  15. package/dist/es5/i3s-building-scene-layer-loader.js.map +1 -0
  16. package/dist/es5/i3s-content-loader.js +57 -0
  17. package/dist/es5/i3s-content-loader.js.map +1 -0
  18. package/dist/es5/i3s-loader.js +193 -0
  19. package/dist/es5/i3s-loader.js.map +1 -0
  20. package/dist/es5/i3s-node-page-loader.js +39 -0
  21. package/dist/es5/i3s-node-page-loader.js.map +1 -0
  22. package/dist/es5/index.js +61 -0
  23. package/dist/es5/index.js.map +1 -0
  24. package/dist/es5/lib/helpers/i3s-nodepages-tiles.js +312 -0
  25. package/dist/es5/lib/helpers/i3s-nodepages-tiles.js.map +1 -0
  26. package/dist/es5/lib/parsers/constants.js +72 -0
  27. package/dist/es5/lib/parsers/constants.js.map +1 -0
  28. package/dist/es5/lib/parsers/parse-arcgis-webscene.js +158 -0
  29. package/dist/es5/lib/parsers/parse-arcgis-webscene.js.map +1 -0
  30. package/dist/es5/lib/parsers/parse-i3s-attribute.js +76 -0
  31. package/dist/es5/lib/parsers/parse-i3s-attribute.js.map +1 -0
  32. package/dist/es5/lib/parsers/parse-i3s-building-scene-layer.js +65 -0
  33. package/dist/es5/lib/parsers/parse-i3s-building-scene-layer.js.map +1 -0
  34. package/dist/es5/lib/parsers/parse-i3s-tile-content.js +510 -0
  35. package/dist/es5/lib/parsers/parse-i3s-tile-content.js.map +1 -0
  36. package/dist/es5/lib/parsers/parse-i3s.js +116 -0
  37. package/dist/es5/lib/parsers/parse-i3s.js.map +1 -0
  38. package/dist/es5/lib/utils/convert-i3s-obb-to-mbs.js +17 -0
  39. package/dist/es5/lib/utils/convert-i3s-obb-to-mbs.js.map +1 -0
  40. package/dist/es5/lib/utils/customizeColors.js +159 -0
  41. package/dist/es5/lib/utils/customizeColors.js.map +1 -0
  42. package/dist/es5/lib/utils/url-utils.js +33 -0
  43. package/dist/es5/lib/utils/url-utils.js.map +1 -0
  44. package/dist/es5/types.js +26 -0
  45. package/dist/es5/types.js.map +1 -0
  46. package/dist/es5/workers/i3s-content-nodejs-worker.js +7 -0
  47. package/dist/es5/workers/i3s-content-nodejs-worker.js.map +1 -0
  48. package/dist/es5/workers/i3s-content-worker.js +6 -0
  49. package/dist/es5/workers/i3s-content-worker.js.map +1 -0
  50. package/dist/esm/arcgis-webscene-loader.js +16 -0
  51. package/dist/esm/arcgis-webscene-loader.js.map +1 -0
  52. package/dist/esm/bundle.js +4 -0
  53. package/dist/esm/bundle.js.map +1 -0
  54. package/dist/esm/i3s-attribute-loader.js +119 -0
  55. package/dist/esm/i3s-attribute-loader.js.map +1 -0
  56. package/dist/esm/i3s-building-scene-layer-loader.js +19 -0
  57. package/dist/esm/i3s-building-scene-layer-loader.js.map +1 -0
  58. package/dist/esm/i3s-content-loader.js +31 -0
  59. package/dist/esm/i3s-content-loader.js.map +1 -0
  60. package/dist/esm/i3s-loader.js +87 -0
  61. package/dist/esm/i3s-loader.js.map +1 -0
  62. package/dist/esm/i3s-node-page-loader.js +15 -0
  63. package/dist/esm/i3s-node-page-loader.js.map +1 -0
  64. package/dist/esm/index.js +8 -0
  65. package/dist/esm/index.js.map +1 -0
  66. package/dist/esm/lib/helpers/i3s-nodepages-tiles.js +198 -0
  67. package/dist/esm/lib/helpers/i3s-nodepages-tiles.js.map +1 -0
  68. package/dist/esm/lib/parsers/constants.js +57 -0
  69. package/dist/esm/lib/parsers/constants.js.map +1 -0
  70. package/dist/esm/lib/parsers/parse-arcgis-webscene.js +70 -0
  71. package/dist/esm/lib/parsers/parse-arcgis-webscene.js.map +1 -0
  72. package/dist/esm/lib/parsers/parse-i3s-attribute.js +60 -0
  73. package/dist/esm/lib/parsers/parse-i3s-attribute.js.map +1 -0
  74. package/dist/esm/lib/parsers/parse-i3s-building-scene-layer.js +39 -0
  75. package/dist/esm/lib/parsers/parse-i3s-building-scene-layer.js.map +1 -0
  76. package/dist/esm/lib/parsers/parse-i3s-tile-content.js +435 -0
  77. package/dist/esm/lib/parsers/parse-i3s-tile-content.js.map +1 -0
  78. package/dist/esm/lib/parsers/parse-i3s.js +83 -0
  79. package/dist/esm/lib/parsers/parse-i3s.js.map +1 -0
  80. package/dist/esm/lib/utils/convert-i3s-obb-to-mbs.js +9 -0
  81. package/dist/esm/lib/utils/convert-i3s-obb-to-mbs.js.map +1 -0
  82. package/dist/esm/lib/utils/customizeColors.js +92 -0
  83. package/dist/esm/lib/utils/customizeColors.js.map +1 -0
  84. package/dist/esm/lib/utils/url-utils.js +28 -0
  85. package/dist/esm/lib/utils/url-utils.js.map +1 -0
  86. package/dist/esm/types.js +18 -0
  87. package/dist/esm/types.js.map +1 -0
  88. package/dist/esm/workers/i3s-content-nodejs-worker.js +5 -0
  89. package/dist/esm/workers/i3s-content-nodejs-worker.js.map +1 -0
  90. package/dist/esm/workers/i3s-content-worker.js +4 -0
  91. package/dist/esm/workers/i3s-content-worker.js.map +1 -0
  92. package/dist/i3s-attribute-loader.d.ts +21 -0
  93. package/dist/i3s-attribute-loader.d.ts.map +1 -0
  94. package/dist/i3s-attribute-loader.js +155 -132
  95. package/dist/i3s-building-scene-layer-loader.d.ts +6 -0
  96. package/dist/i3s-building-scene-layer-loader.d.ts.map +1 -0
  97. package/dist/i3s-building-scene-layer-loader.js +23 -18
  98. package/dist/i3s-content-loader.d.ts +6 -0
  99. package/dist/i3s-content-loader.d.ts.map +1 -0
  100. package/dist/i3s-content-loader.js +30 -22
  101. package/dist/i3s-content-nodejs-worker.js +198 -0
  102. package/dist/i3s-content-nodejs-worker.js.map +7 -0
  103. package/dist/i3s-content-worker.js +1523 -1383
  104. package/dist/i3s-loader.d.ts +11 -0
  105. package/dist/i3s-loader.d.ts.map +1 -0
  106. package/dist/i3s-loader.js +88 -83
  107. package/dist/i3s-node-page-loader.d.ts +7 -0
  108. package/dist/i3s-node-page-loader.d.ts.map +1 -0
  109. package/dist/i3s-node-page-loader.js +20 -20
  110. package/dist/index.d.ts +9 -0
  111. package/dist/index.d.ts.map +1 -0
  112. package/dist/index.js +19 -6
  113. package/dist/lib/helpers/i3s-nodepages-tiles.d.ts +74 -0
  114. package/dist/lib/helpers/i3s-nodepages-tiles.d.ts.map +1 -0
  115. package/dist/lib/helpers/i3s-nodepages-tiles.js +232 -219
  116. package/dist/lib/parsers/constants.d.ts +40 -0
  117. package/dist/lib/parsers/constants.d.ts.map +1 -0
  118. package/dist/lib/parsers/constants.js +87 -49
  119. package/dist/lib/parsers/parse-arcgis-webscene.d.ts +7 -0
  120. package/dist/lib/parsers/parse-arcgis-webscene.d.ts.map +1 -0
  121. package/dist/lib/parsers/parse-arcgis-webscene.js +88 -0
  122. package/dist/lib/parsers/parse-i3s-attribute.d.ts +12 -0
  123. package/dist/lib/parsers/parse-i3s-attribute.d.ts.map +1 -0
  124. package/dist/lib/parsers/parse-i3s-attribute.js +87 -62
  125. package/dist/lib/parsers/parse-i3s-building-scene-layer.d.ts +9 -0
  126. package/dist/lib/parsers/parse-i3s-building-scene-layer.d.ts.map +1 -0
  127. package/dist/lib/parsers/parse-i3s-building-scene-layer.js +41 -38
  128. package/dist/lib/parsers/parse-i3s-tile-content.d.ts +4 -0
  129. package/dist/lib/parsers/parse-i3s-tile-content.d.ts.map +1 -0
  130. package/dist/lib/parsers/parse-i3s-tile-content.js +458 -461
  131. package/dist/lib/parsers/parse-i3s.d.ts +6 -0
  132. package/dist/lib/parsers/parse-i3s.d.ts.map +1 -0
  133. package/dist/lib/parsers/parse-i3s.js +92 -73
  134. package/dist/lib/utils/convert-i3s-obb-to-mbs.d.ts +2 -0
  135. package/dist/lib/utils/convert-i3s-obb-to-mbs.d.ts.map +1 -0
  136. package/dist/lib/utils/convert-i3s-obb-to-mbs.js +19 -8
  137. package/dist/lib/utils/customizeColors.d.ts +14 -0
  138. package/dist/lib/utils/customizeColors.d.ts.map +1 -0
  139. package/dist/lib/utils/customizeColors.js +94 -0
  140. package/dist/lib/utils/url-utils.d.ts +22 -0
  141. package/dist/lib/utils/url-utils.d.ts.map +1 -0
  142. package/dist/lib/utils/url-utils.js +41 -29
  143. package/dist/types.d.ts +1064 -0
  144. package/dist/types.d.ts.map +1 -0
  145. package/dist/types.js +20 -2
  146. package/dist/workers/i3s-content-nodejs-worker.d.ts +2 -0
  147. package/dist/workers/i3s-content-nodejs-worker.d.ts.map +1 -0
  148. package/dist/workers/i3s-content-nodejs-worker.js +6 -0
  149. package/dist/workers/i3s-content-worker.d.ts +2 -0
  150. package/dist/workers/i3s-content-worker.d.ts.map +1 -0
  151. package/dist/workers/i3s-content-worker.js +5 -4
  152. package/package.json +17 -17
  153. package/src/arcgis-webscene-loader.ts +31 -0
  154. package/src/i3s-attribute-loader.ts +9 -9
  155. package/src/i3s-content-loader.ts +19 -6
  156. package/src/i3s-loader.ts +22 -13
  157. package/src/i3s-node-page-loader.ts +6 -10
  158. package/src/index.ts +24 -7
  159. package/src/lib/helpers/i3s-nodepages-tiles.ts +84 -57
  160. package/src/lib/parsers/constants.ts +68 -55
  161. package/src/lib/parsers/parse-arcgis-webscene.ts +102 -0
  162. package/src/lib/parsers/parse-i3s-attribute.ts +21 -14
  163. package/src/lib/parsers/parse-i3s-building-scene-layer.ts +2 -1
  164. package/src/lib/parsers/parse-i3s-tile-content.ts +227 -200
  165. package/src/lib/parsers/parse-i3s.ts +55 -39
  166. package/src/lib/utils/customizeColors.ts +134 -0
  167. package/src/lib/utils/url-utils.ts +7 -7
  168. package/src/types.ts +874 -86
  169. package/src/workers/i3s-content-nodejs-worker.ts +5 -0
  170. package/dist/bundle.js.map +0 -1
  171. package/dist/i3s-attribute-loader.js.map +0 -1
  172. package/dist/i3s-building-scene-layer-loader.js.map +0 -1
  173. package/dist/i3s-content-loader.js.map +0 -1
  174. package/dist/i3s-loader.js.map +0 -1
  175. package/dist/i3s-node-page-loader.js.map +0 -1
  176. package/dist/index.js.map +0 -1
  177. package/dist/lib/helpers/i3s-nodepages-tiles.js.map +0 -1
  178. package/dist/lib/parsers/constants.js.map +0 -1
  179. package/dist/lib/parsers/parse-i3s-attribute.js.map +0 -1
  180. package/dist/lib/parsers/parse-i3s-building-scene-layer.js.map +0 -1
  181. package/dist/lib/parsers/parse-i3s-tile-content.js.map +0 -1
  182. package/dist/lib/parsers/parse-i3s.js.map +0 -1
  183. package/dist/lib/utils/convert-i3s-obb-to-mbs.js.map +0 -1
  184. package/dist/lib/utils/url-utils.js.map +0 -1
  185. package/dist/types.js.map +0 -1
  186. package/dist/workers/i3s-content-worker.js.map +0 -1
@@ -2,115 +2,141 @@ import type {TypedArray} from '@loaders.gl/schema';
2
2
  import {load, parse} from '@loaders.gl/core';
3
3
  import {Vector3, Matrix4} from '@math.gl/core';
4
4
  import {Ellipsoid} from '@math.gl/geospatial';
5
-
6
5
  import type {LoaderOptions, LoaderContext} from '@loaders.gl/loader-utils';
7
6
  import {ImageLoader} from '@loaders.gl/images';
8
- import {DracoLoader} from '@loaders.gl/draco';
7
+ import {DracoLoader, DracoMesh} from '@loaders.gl/draco';
9
8
  import {BasisLoader, CompressedTextureLoader} from '@loaders.gl/textures';
10
9
 
11
- import {Tileset, Tile} from '../../types';
10
+ import {
11
+ FeatureAttribute,
12
+ VertexAttribute,
13
+ I3SMeshAttributes,
14
+ I3SMeshAttribute,
15
+ TileContentTexture,
16
+ HeaderAttributeProperty,
17
+ I3SMaterialDefinition,
18
+ I3STileContent,
19
+ I3STileOptions,
20
+ I3STilesetOptions
21
+ } from '../../types';
12
22
  import {getUrlWithToken} from '../utils/url-utils';
13
23
 
14
- import {
15
- GL_TYPE_MAP,
16
- TYPE_ARRAY_MAP,
17
- SIZEOF,
18
- I3S_NAMED_HEADER_ATTRIBUTES,
19
- I3S_NAMED_VERTEX_ATTRIBUTES,
20
- I3S_NAMED_GEOMETRY_ATTRIBUTES,
21
- COORDINATE_SYSTEM
22
- } from './constants';
24
+ import {GL_TYPE_MAP, getConstructorForDataFormat, sizeOf, COORDINATE_SYSTEM} from './constants';
25
+ import {I3SLoaderOptions} from '../../i3s-loader';
26
+ import {customizeColors} from '../utils/customizeColors';
23
27
 
24
28
  const scratchVector = new Vector3([0, 0, 0]);
25
29
 
26
- const FORMAT_LOADER_MAP = {
27
- jpeg: ImageLoader,
28
- png: ImageLoader,
29
- 'ktx-etc2': CompressedTextureLoader,
30
- dds: CompressedTextureLoader,
31
- ktx2: BasisLoader
32
- };
30
+ function getLoaderForTextureFormat(textureFormat?: 'jpg' | 'png' | 'ktx-etc2' | 'dds' | 'ktx2') {
31
+ switch (textureFormat) {
32
+ case 'ktx-etc2':
33
+ case 'dds':
34
+ return CompressedTextureLoader;
35
+ case 'ktx2':
36
+ return BasisLoader;
37
+ case 'jpg':
38
+ case 'png':
39
+ default:
40
+ return ImageLoader;
41
+ }
42
+ }
33
43
 
34
44
  const I3S_ATTRIBUTE_TYPE = 'i3s-attribute-type';
35
45
 
36
46
  export async function parseI3STileContent(
37
47
  arrayBuffer: ArrayBuffer,
38
- tile: Tile,
39
- tileset: Tileset,
48
+ tileOptions: I3STileOptions,
49
+ tilesetOptions: I3STilesetOptions,
40
50
  options?: LoaderOptions,
41
51
  context?: LoaderContext
42
- ) {
43
- tile.content = tile.content || {};
44
- tile.content.featureIds = tile.content.featureIds || null;
45
-
46
- // construct featureData from defaultGeometrySchema;
47
- tile.content.featureData = constructFeatureDataStruct(tile, tileset);
48
- tile.content.attributes = {};
49
-
50
- if (tile.textureUrl) {
51
- const url = getUrlWithToken(tile.textureUrl, options?.i3s?.token);
52
- const loader = FORMAT_LOADER_MAP[tile.textureFormat] || ImageLoader;
53
- // @ts-ignore context must be defined
54
- const response = await fetch(url);
52
+ ): Promise<I3STileContent> {
53
+ const content: I3STileContent = {
54
+ attributes: {},
55
+ indices: null,
56
+ featureIds: [],
57
+ vertexCount: 0,
58
+ modelMatrix: new Matrix4(),
59
+ coordinateSystem: 0,
60
+ byteLength: 0,
61
+ texture: null
62
+ };
63
+
64
+ if (tileOptions.textureUrl) {
65
+ // @ts-expect-error options is not properly typed
66
+ const url = getUrlWithToken(tileOptions.textureUrl, options?.i3s?.token);
67
+ const loader = getLoaderForTextureFormat(tileOptions.textureFormat);
68
+ const response = await fetch(url, options?.fetch as RequestInit);
55
69
  const arrayBuffer = await response.arrayBuffer();
56
70
 
71
+ // @ts-expect-error options is not properly typed
57
72
  if (options?.i3s.decodeTextures) {
58
73
  if (loader === ImageLoader) {
59
- const options = {...tile.textureLoaderOptions, image: {type: 'data'}};
60
- // @ts-ignore context must be defined
61
- // Image constructor is not supported in worker thread.
62
- // Do parsing image data on the main thread by using context to avoid worker issues.
63
- tile.content.texture = await context.parse(arrayBuffer, options);
74
+ const options = {...tileOptions.textureLoaderOptions, image: {type: 'data'}};
75
+ try {
76
+ // @ts-ignore context must be defined
77
+ // Image constructor is not supported in worker thread.
78
+ // Do parsing image data on the main thread by using context to avoid worker issues.
79
+ content.texture = await context.parse(arrayBuffer, options);
80
+ } catch (e) {
81
+ // context object is different between worker and node.js conversion script.
82
+ // To prevent error we parse data in ordinary way if it is not parsed by using context.
83
+ // @ts-expect-error
84
+ content.texture = await parse(arrayBuffer, loader, options);
85
+ }
64
86
  } else if (loader === CompressedTextureLoader || loader === BasisLoader) {
65
- // @ts-ignore context must be defined
66
- const texture = await load(arrayBuffer, loader, tile.textureLoaderOptions);
67
- tile.content.texture = {
87
+ let texture = await load(arrayBuffer, loader, tileOptions.textureLoaderOptions);
88
+ if (loader === BasisLoader) {
89
+ // @ts-expect-error
90
+ texture = texture[0];
91
+ }
92
+ content.texture = {
68
93
  compressed: true,
69
94
  mipmaps: false,
95
+ // @ts-expect-error
70
96
  width: texture[0].width,
97
+ // @ts-expect-error
71
98
  height: texture[0].height,
99
+ // @ts-expect-error
72
100
  data: texture
73
101
  };
74
102
  }
75
103
  } else {
76
- tile.content.texture = arrayBuffer;
104
+ content.texture = arrayBuffer;
77
105
  }
78
106
  }
79
107
 
80
- tile.content.material = makePbrMaterial(tile.materialDefinition, tile.content.texture);
81
- if (tile.content.material) {
82
- tile.content.texture = null;
108
+ content.material = makePbrMaterial(tileOptions.materialDefinition, content.texture);
109
+ if (content.material) {
110
+ content.texture = null;
83
111
  }
84
112
 
85
- return await parseI3SNodeGeometry(arrayBuffer, tile, options, context);
113
+ return await parseI3SNodeGeometry(arrayBuffer, content, tileOptions, tilesetOptions, options);
86
114
  }
87
115
 
88
116
  /* eslint-disable max-statements */
89
117
  async function parseI3SNodeGeometry(
90
118
  arrayBuffer: ArrayBuffer,
91
- tile: Tile = {},
92
- options?: LoaderOptions,
93
- context?: LoaderContext
94
- ) {
95
- if (!tile.content) {
96
- return tile;
97
- }
98
-
99
- const content = tile.content;
100
- let attributes;
101
- let vertexCount;
102
- let byteOffset = 0;
103
- let featureCount = 0;
104
-
105
- if (tile.isDracoGeometry) {
106
- const decompressedGeometry = await parse(arrayBuffer, DracoLoader, {
119
+ content: I3STileContent,
120
+ tileOptions: I3STileOptions,
121
+ tilesetOptions: I3STilesetOptions,
122
+ options?: I3SLoaderOptions
123
+ ): Promise<I3STileContent> {
124
+ const contentByteLength = arrayBuffer.byteLength;
125
+ let attributes: I3SMeshAttributes;
126
+ let vertexCount: number;
127
+ let byteOffset: number = 0;
128
+ let featureCount: number = 0;
129
+ let indices: TypedArray | undefined;
130
+
131
+ if (tileOptions.isDracoGeometry) {
132
+ const decompressedGeometry: DracoMesh = await parse(arrayBuffer, DracoLoader, {
107
133
  draco: {
108
134
  attributeNameEntry: I3S_ATTRIBUTE_TYPE
109
135
  }
110
136
  });
111
-
137
+ // @ts-expect-error
112
138
  vertexCount = decompressedGeometry.header.vertexCount;
113
- const indices = decompressedGeometry.indices.value;
139
+ indices = decompressedGeometry.indices?.value;
114
140
  const {
115
141
  POSITION,
116
142
  NORMAL,
@@ -126,8 +152,7 @@ async function parseI3SNodeGeometry(
126
152
  color: COLOR_0,
127
153
  uv0: TEXCOORD_0,
128
154
  uvRegion,
129
- id: featureIndex,
130
- indices
155
+ id: featureIndex
131
156
  };
132
157
 
133
158
  updateAttributesMetadata(attributes, decompressedGeometry);
@@ -138,10 +163,14 @@ async function parseI3SNodeGeometry(
138
163
  flattenFeatureIdsByFeatureIndices(attributes, featureIds);
139
164
  }
140
165
  } else {
141
- const {vertexAttributes, attributesOrder, featureAttributes, featureAttributeOrder} =
142
- content.featureData;
166
+ const {
167
+ vertexAttributes,
168
+ ordering: attributesOrder,
169
+ featureAttributes,
170
+ featureAttributeOrder
171
+ } = tilesetOptions.store.defaultGeometrySchema;
143
172
  // First 8 bytes reserved for header (vertexCount and featureCount)
144
- const headers = parseHeaders(content, arrayBuffer);
173
+ const headers = parseHeaders(arrayBuffer, tilesetOptions);
145
174
  byteOffset = headers.byteOffset;
146
175
  vertexCount = headers.vertexCount;
147
176
  featureCount = headers.featureCount;
@@ -171,7 +200,7 @@ async function parseI3SNodeGeometry(
171
200
  !options?.i3s?.coordinateSystem ||
172
201
  options.i3s.coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS
173
202
  ) {
174
- const {enuMatrix} = parsePositions(attributes.position, tile);
203
+ const enuMatrix = parsePositions(attributes.position, tileOptions);
175
204
  content.modelMatrix = enuMatrix.invert();
176
205
  content.coordinateSystem = COORDINATE_SYSTEM.METER_OFFSETS;
177
206
  } else {
@@ -179,17 +208,25 @@ async function parseI3SNodeGeometry(
179
208
  content.coordinateSystem = COORDINATE_SYSTEM.LNGLAT_OFFSETS;
180
209
  }
181
210
 
211
+ attributes.color = await customizeColors(
212
+ attributes.color,
213
+ attributes.id,
214
+ tileOptions,
215
+ tilesetOptions,
216
+ options
217
+ );
218
+
182
219
  content.attributes = {
183
220
  positions: attributes.position,
184
221
  normals: attributes.normal,
185
222
  colors: normalizeAttribute(attributes.color), // Normalize from UInt8
186
223
  texCoords: attributes.uv0,
187
- uvRegions: normalizeAttribute(attributes.uvRegion) // Normalize from UInt16
224
+ uvRegions: normalizeAttribute(attributes.uvRegion || attributes.region) // Normalize from UInt16
188
225
  };
189
- content.indices = attributes.indices || null;
226
+ content.indices = indices || null;
190
227
 
191
228
  if (attributes.id && attributes.id.value) {
192
- tile.content.featureIds = attributes.id.value;
229
+ content.featureIds = attributes.id.value;
193
230
  }
194
231
 
195
232
  // Remove undefined attributes
@@ -200,9 +237,9 @@ async function parseI3SNodeGeometry(
200
237
  }
201
238
 
202
239
  content.vertexCount = vertexCount;
203
- content.byteLength = arrayBuffer.byteLength;
240
+ content.byteLength = contentByteLength;
204
241
 
205
- return tile;
242
+ return content;
206
243
  }
207
244
 
208
245
  /**
@@ -210,7 +247,10 @@ async function parseI3SNodeGeometry(
210
247
  * @param decompressedGeometry
211
248
  * @param attributes
212
249
  */
213
- function updateAttributesMetadata(attributes, decompressedGeometry) {
250
+ function updateAttributesMetadata(
251
+ attributes: I3SMeshAttributes,
252
+ decompressedGeometry: DracoMesh
253
+ ): void {
214
254
  for (const key in decompressedGeometry.loaderData.attributes) {
215
255
  const dracoAttribute = decompressedGeometry.loaderData.attributes[key];
216
256
 
@@ -230,20 +270,23 @@ function updateAttributesMetadata(attributes, decompressedGeometry) {
230
270
  /**
231
271
  * Do concatenation of attribute objects.
232
272
  * Done as separate fucntion to avoid ts errors.
233
- * @param {Object} normalizedVertexAttributes
234
- * @param {Object} normalizedFeatureAttributes
235
- * @returns {object} - result of attributes concatenation.
273
+ * @param normalizedVertexAttributes
274
+ * @param normalizedFeatureAttributes
275
+ * @returns - result of attributes concatenation.
236
276
  */
237
- function concatAttributes(normalizedVertexAttributes, normalizedFeatureAttributes) {
277
+ function concatAttributes(
278
+ normalizedVertexAttributes: I3SMeshAttributes,
279
+ normalizedFeatureAttributes: I3SMeshAttributes
280
+ ): I3SMeshAttributes {
238
281
  return {...normalizedVertexAttributes, ...normalizedFeatureAttributes};
239
282
  }
240
283
 
241
284
  /**
242
285
  * Normalize attribute to range [0..1] . Eg. convert colors buffer from [255,255,255,255] to [1,1,1,1]
243
- * @param {Object} attribute - geometry attribute
244
- * @returns {Object} - geometry attribute in right format
286
+ * @param attribute - geometry attribute
287
+ * @returns - geometry attribute in right format
245
288
  */
246
- function normalizeAttribute(attribute) {
289
+ function normalizeAttribute(attribute: I3SMeshAttribute): I3SMeshAttribute {
247
290
  if (!attribute) {
248
291
  return attribute;
249
292
  }
@@ -251,49 +294,27 @@ function normalizeAttribute(attribute) {
251
294
  return attribute;
252
295
  }
253
296
 
254
- function constructFeatureDataStruct(tile, tileset) {
255
- // seed featureData from defaultGeometrySchema
256
- const defaultGeometrySchema = tileset.store.defaultGeometrySchema;
257
- const featureData = defaultGeometrySchema;
258
- // populate the vertex attributes value types and values per element
259
- for (const geometryAttribute in I3S_NAMED_GEOMETRY_ATTRIBUTES) {
260
- for (const namedAttribute in I3S_NAMED_VERTEX_ATTRIBUTES) {
261
- const attribute = defaultGeometrySchema[geometryAttribute][namedAttribute];
262
- if (attribute) {
263
- const {byteOffset = 0, count = 0, valueType, valuesPerElement} = attribute;
264
-
265
- featureData[geometryAttribute][namedAttribute] = {
266
- valueType,
267
- valuesPerElement,
268
- byteOffset,
269
- count
270
- };
271
- }
272
- }
273
- }
274
-
275
- featureData.attributesOrder = defaultGeometrySchema.ordering;
276
- return featureData;
277
- }
278
-
279
- function parseHeaders(content, buffer) {
297
+ function parseHeaders(arrayBuffer: ArrayBuffer, options: I3STilesetOptions) {
280
298
  let byteOffset = 0;
281
299
  // First 8 bytes reserved for header (vertexCount and featurecount)
282
300
  let vertexCount = 0;
283
301
  let featureCount = 0;
284
- const headers = content.featureData[I3S_NAMED_HEADER_ATTRIBUTES.header];
285
- for (const header in headers) {
286
- const {property, type} = headers[header];
287
- const TypedArrayTypeHeader = TYPE_ARRAY_MAP[type];
288
- if (property === I3S_NAMED_HEADER_ATTRIBUTES.vertexCount) {
289
- vertexCount = new TypedArrayTypeHeader(buffer, 0, 4)[0];
290
- byteOffset += SIZEOF[type];
291
- }
292
- if (property === I3S_NAMED_HEADER_ATTRIBUTES.featureCount) {
293
- featureCount = new TypedArrayTypeHeader(buffer, 4, 4)[0];
294
- byteOffset += SIZEOF[type];
302
+ for (const {property, type} of options.store.defaultGeometrySchema.header) {
303
+ const TypedArrayTypeHeader = getConstructorForDataFormat(type);
304
+ switch (property) {
305
+ case HeaderAttributeProperty.vertexCount:
306
+ vertexCount = new TypedArrayTypeHeader(arrayBuffer, 0, 4)[0];
307
+ byteOffset += sizeOf(type);
308
+ break;
309
+ case HeaderAttributeProperty.featureCount:
310
+ featureCount = new TypedArrayTypeHeader(arrayBuffer, 4, 4)[0];
311
+ byteOffset += sizeOf(type);
312
+ break;
313
+ default:
314
+ break;
295
315
  }
296
316
  }
317
+
297
318
  return {
298
319
  vertexCount,
299
320
  featureCount,
@@ -304,57 +325,59 @@ function parseHeaders(content, buffer) {
304
325
  /* eslint-enable max-statements */
305
326
 
306
327
  function normalizeAttributes(
307
- arrayBuffer,
308
- byteOffset,
309
- vertexAttributes,
310
- vertexCount,
311
- attributesOrder
328
+ arrayBuffer: ArrayBuffer,
329
+ byteOffset: number,
330
+ vertexAttributes: VertexAttribute | FeatureAttribute,
331
+ attributeCount: number,
332
+ attributesOrder: string[]
312
333
  ) {
313
- const attributes = {};
334
+ const attributes: I3SMeshAttributes = {};
314
335
 
315
336
  // the order of attributes depend on the order being added to the vertexAttributes object
316
337
  for (const attribute of attributesOrder) {
317
338
  if (vertexAttributes[attribute]) {
318
- const {valueType, valuesPerElement} = vertexAttributes[attribute];
319
- // update count and byteOffset count by calculating from defaultGeometrySchema + binnary content
320
- const count = vertexCount;
339
+ const {valueType, valuesPerElement}: {valueType: string; valuesPerElement: number} =
340
+ vertexAttributes[attribute];
321
341
  // protect from arrayBuffer read overunns by NOT assuming node has regions always even though its declared in defaultGeometrySchema.
322
342
  // In i3s 1.6: client is required to decide that based on ./shared resource of the node (materialDefinitions.[Mat_id].params.vertexRegions == true)
323
343
  // In i3s 1.7 the property has been rolled into the 3d scene layer json/node pages.
324
344
  // Code below does not account when the bytelength is actually bigger than
325
345
  // the calculated value (b\c the tile potentially could have mesh segmentation information).
326
346
  // In those cases tiles without regions could fail or have garbage values.
327
- if (byteOffset + count * valuesPerElement > arrayBuffer.byteLength) {
328
- break;
329
- }
330
- const buffer = arrayBuffer.slice(byteOffset);
331
- let value: number[] | TypedArray = [];
332
-
333
- if (valueType === 'UInt64') {
334
- value = parseUint64Values(buffer, count * valuesPerElement, SIZEOF[valueType]);
335
- } else {
336
- const TypedArrayType = TYPE_ARRAY_MAP[valueType];
337
- value = new TypedArrayType(buffer, 0, count * valuesPerElement);
338
- }
347
+ if (
348
+ byteOffset + attributeCount * valuesPerElement * sizeOf(valueType) <=
349
+ arrayBuffer.byteLength
350
+ ) {
351
+ const buffer = arrayBuffer.slice(byteOffset);
352
+ let value: TypedArray;
353
+
354
+ if (valueType === 'UInt64') {
355
+ value = parseUint64Values(buffer, attributeCount * valuesPerElement, sizeOf(valueType));
356
+ } else {
357
+ const TypedArrayType = getConstructorForDataFormat(valueType);
358
+ value = new TypedArrayType(buffer, 0, attributeCount * valuesPerElement);
359
+ }
360
+
361
+ attributes[attribute] = {
362
+ value,
363
+ type: GL_TYPE_MAP[valueType],
364
+ size: valuesPerElement
365
+ };
339
366
 
340
- attributes[attribute] = {
341
- value,
342
- type: GL_TYPE_MAP[valueType],
343
- size: valuesPerElement
344
- };
345
-
346
- switch (attribute) {
347
- case 'color':
348
- // @ts-ignore
349
- attributes.color.normalized = true;
350
- break;
351
- case 'position':
352
- case 'region':
353
- case 'normal':
354
- default:
367
+ switch (attribute) {
368
+ case 'color':
369
+ attributes.color.normalized = true;
370
+ break;
371
+ case 'position':
372
+ case 'region':
373
+ case 'normal':
374
+ default:
375
+ }
376
+
377
+ byteOffset = byteOffset + attributeCount * valuesPerElement * sizeOf(valueType);
378
+ } else if (attribute !== 'uv0') {
379
+ break;
355
380
  }
356
-
357
- byteOffset = byteOffset + count * valuesPerElement * SIZEOF[valueType];
358
381
  }
359
382
  }
360
383
 
@@ -372,7 +395,7 @@ function parseUint64Values(
372
395
  buffer: ArrayBuffer,
373
396
  elementsCount: number,
374
397
  attributeSize: number
375
- ): number[] {
398
+ ): Uint32Array {
376
399
  const values: number[] = [];
377
400
  const dataView = new DataView(buffer);
378
401
  let offset = 0;
@@ -388,11 +411,11 @@ function parseUint64Values(
388
411
  offset += attributeSize;
389
412
  }
390
413
 
391
- return values;
414
+ return new Uint32Array(values);
392
415
  }
393
416
 
394
- function parsePositions(attribute, tile) {
395
- const mbs = tile.mbs;
417
+ function parsePositions(attribute: I3SMeshAttribute, options: I3STileOptions): Matrix4 {
418
+ const mbs = options.mbs;
396
419
  const value = attribute.value;
397
420
  const metadata = attribute.metadata;
398
421
  const enuMatrix = new Matrix4();
@@ -402,20 +425,22 @@ function parsePositions(attribute, tile) {
402
425
  Ellipsoid.WGS84.eastNorthUpToFixedFrame(cartesianOrigin, enuMatrix);
403
426
  attribute.value = offsetsToCartesians(value, metadata, cartographicOrigin);
404
427
 
405
- return {
406
- enuMatrix
407
- };
428
+ return enuMatrix;
408
429
  }
409
430
 
410
431
  /**
411
432
  * Converts position coordinates to absolute cartesian coordinates
412
- * @param {Float32Array} vertices - "position" attribute data
413
- * @param {Object} metadata - When the geometry is DRACO compressed, contain position attribute's metadata
433
+ * @param vertices - "position" attribute data
434
+ * @param metadata - When the geometry is DRACO compressed, contain position attribute's metadata
414
435
  * https://github.com/Esri/i3s-spec/blob/master/docs/1.7/compressedAttributes.cmn.md
415
- * @param {Vector3} cartographicOrigin - Cartographic origin coordinates
416
- * @returns {Float64Array} - converted "position" data
436
+ * @param cartographicOrigin - Cartographic origin coordinates
437
+ * @returns - converted "position" data
417
438
  */
418
- function offsetsToCartesians(vertices, metadata = {}, cartographicOrigin) {
439
+ function offsetsToCartesians(
440
+ vertices: number[] | TypedArray,
441
+ metadata: any = {},
442
+ cartographicOrigin: Vector3
443
+ ): Float64Array {
419
444
  const positions = new Float64Array(vertices.length);
420
445
  const scaleX = (metadata['i3s-scale_x'] && metadata['i3s-scale_x'].double) || 1;
421
446
  const scaleY = (metadata['i3s-scale_y'] && metadata['i3s-scale_y'].double) || 1;
@@ -441,10 +466,10 @@ function offsetsToCartesians(vertices, metadata = {}, cartographicOrigin) {
441
466
  * @param positions positions attribute
442
467
  * @returns Matrix4 - model matrix for geometry transformation
443
468
  */
444
- function getModelMatrix(positions) {
469
+ function getModelMatrix(positions: I3SMeshAttribute): Matrix4 {
445
470
  const metadata = positions.metadata;
446
- const scaleX = metadata?.['i3s-scale_x']?.double || 1;
447
- const scaleY = metadata?.['i3s-scale_y']?.double || 1;
471
+ const scaleX: number = metadata?.['i3s-scale_x']?.double || 1;
472
+ const scaleY: number = metadata?.['i3s-scale_y']?.double || 1;
448
473
  const modelMatrix = new Matrix4();
449
474
  modelMatrix[0] = scaleX;
450
475
  modelMatrix[5] = scaleY;
@@ -453,12 +478,12 @@ function getModelMatrix(positions) {
453
478
 
454
479
  /**
455
480
  * Makes a glTF-compatible PBR material from an I3S material definition
456
- * @param {object} materialDefinition - i3s material definition
481
+ * @param materialDefinition - i3s material definition
457
482
  * https://github.com/Esri/i3s-spec/blob/master/docs/1.7/materialDefinitions.cmn.md
458
- * @param {object} texture - texture image
483
+ * @param texture - texture image
459
484
  * @returns {object}
460
485
  */
461
- function makePbrMaterial(materialDefinition, texture) {
486
+ function makePbrMaterial(materialDefinition?: I3SMaterialDefinition, texture?: TileContentTexture) {
462
487
  let pbrMaterial;
463
488
  if (materialDefinition) {
464
489
  pbrMaterial = {
@@ -496,17 +521,19 @@ function makePbrMaterial(materialDefinition, texture) {
496
521
  );
497
522
  }
498
523
 
499
- setMaterialTexture(pbrMaterial, texture);
524
+ if (texture) {
525
+ setMaterialTexture(pbrMaterial, texture);
526
+ }
500
527
 
501
528
  return pbrMaterial;
502
529
  }
503
530
 
504
531
  /**
505
532
  * Convert color from [255,255,255,255] to [1,1,1,1]
506
- * @param {Array} colorFactor - color array
507
- * @returns {Array} - new color array
533
+ * @param colorFactor - color array
534
+ * @returns - new color array
508
535
  */
509
- function convertColorFormat(colorFactor) {
536
+ function convertColorFormat(colorFactor: number[]): number[] {
510
537
  const normalizedColor = [...colorFactor];
511
538
  for (let index = 0; index < colorFactor.length; index++) {
512
539
  normalizedColor[index] = colorFactor[index] / 255;
@@ -517,10 +544,10 @@ function convertColorFormat(colorFactor) {
517
544
  /**
518
545
  * Set texture in PBR material
519
546
  * @param {object} material - i3s material definition
520
- * @param {object} image - texture image
521
- * @returns {void}
547
+ * @param image - texture image
548
+ * @returns
522
549
  */
523
- function setMaterialTexture(material, image) {
550
+ function setMaterialTexture(material, image: TileContentTexture): void {
524
551
  const texture = {source: {image}};
525
552
  // I3SLoader now support loading only one texture. This elseif sequence will assign this texture to one of
526
553
  // properties defined in materialDefinition
@@ -548,10 +575,10 @@ function setMaterialTexture(material, image) {
548
575
 
549
576
  /**
550
577
  * Flatten feature ids using face ranges
551
- * @param {object} normalizedFeatureAttributes
552
- * @returns {void}
578
+ * @param normalizedFeatureAttributes
579
+ * @returns
553
580
  */
554
- function flattenFeatureIdsByFaceRanges(normalizedFeatureAttributes) {
581
+ function flattenFeatureIdsByFaceRanges(normalizedFeatureAttributes: I3SMeshAttributes): void {
555
582
  const {id, faceRange} = normalizedFeatureAttributes;
556
583
 
557
584
  if (!id || !faceRange) {
@@ -584,11 +611,14 @@ function flattenFeatureIdsByFaceRanges(normalizedFeatureAttributes) {
584
611
 
585
612
  /**
586
613
  * Flatten feature ids using featureIndices
587
- * @param {object} attributes
588
- * @param {any} featureIds
589
- * @returns {void}
614
+ * @param attributes
615
+ * @param featureIds
616
+ * @returns
590
617
  */
591
- function flattenFeatureIdsByFeatureIndices(attributes, featureIds) {
618
+ function flattenFeatureIdsByFeatureIndices(
619
+ attributes: I3SMeshAttributes,
620
+ featureIds: Int32Array
621
+ ): void {
592
622
  const featureIndices = attributes.id.value;
593
623
  const result = new Float32Array(featureIndices.length);
594
624
 
@@ -601,14 +631,11 @@ function flattenFeatureIdsByFeatureIndices(attributes, featureIds) {
601
631
 
602
632
  /**
603
633
  * Flatten feature ids using featureIndices
604
- * @param {object} featureIndex
605
- * @returns {Int32Array}
634
+ * @param featureIndex
635
+ * @returns
606
636
  */
607
- function getFeatureIdsFromFeatureIndexMetadata(featureIndex) {
608
- return (
609
- featureIndex &&
610
- featureIndex.metadata &&
611
- featureIndex.metadata['i3s-feature-ids'] &&
612
- featureIndex.metadata['i3s-feature-ids'].intArray
613
- );
637
+ function getFeatureIdsFromFeatureIndexMetadata(
638
+ featureIndex: I3SMeshAttribute
639
+ ): Int32Array | undefined {
640
+ return featureIndex?.metadata?.['i3s-feature-ids']?.intArray;
614
641
  }