@loaders.gl/i3s 3.1.0-beta.7 → 3.1.3
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.
- package/dist/bundle.js +5 -10364
- package/dist/dist.min.js +10371 -0
- package/dist/es5/bundle.js +1 -1
- package/dist/es5/bundle.js.map +1 -1
- package/dist/es5/i3s-attribute-loader.js +147 -62
- package/dist/es5/i3s-attribute-loader.js.map +1 -1
- package/dist/es5/i3s-building-scene-layer-loader.js +36 -8
- package/dist/es5/i3s-building-scene-layer-loader.js.map +1 -1
- package/dist/es5/i3s-content-loader.js +36 -10
- package/dist/es5/i3s-content-loader.js.map +1 -1
- package/dist/es5/i3s-loader.js +175 -51
- package/dist/es5/i3s-loader.js.map +1 -1
- package/dist/es5/i3s-node-page-loader.js +51 -8
- package/dist/es5/i3s-node-page-loader.js.map +1 -1
- package/dist/es5/index.js +6 -6
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/lib/helpers/i3s-nodepages-tiles.js +328 -173
- package/dist/es5/lib/helpers/i3s-nodepages-tiles.js.map +1 -1
- package/dist/es5/lib/parsers/constants.js +9 -28
- package/dist/es5/lib/parsers/constants.js.map +1 -1
- package/dist/es5/lib/parsers/parse-i3s-attribute.js +69 -27
- package/dist/es5/lib/parsers/parse-i3s-attribute.js.map +1 -1
- package/dist/es5/lib/parsers/parse-i3s-building-scene-layer.js +62 -28
- package/dist/es5/lib/parsers/parse-i3s-building-scene-layer.js.map +1 -1
- package/dist/es5/lib/parsers/parse-i3s-tile-content.js +416 -314
- package/dist/es5/lib/parsers/parse-i3s-tile-content.js.map +1 -1
- package/dist/es5/lib/parsers/parse-i3s.js +109 -49
- package/dist/es5/lib/parsers/parse-i3s.js.map +1 -1
- package/dist/es5/lib/utils/convert-i3s-obb-to-mbs.js +8 -4
- package/dist/es5/lib/utils/convert-i3s-obb-to-mbs.js.map +1 -1
- package/dist/es5/lib/utils/url-utils.js +14 -17
- package/dist/es5/lib/utils/url-utils.js.map +1 -1
- package/dist/es5/types.js +10 -2
- package/dist/es5/types.js.map +1 -1
- package/dist/esm/i3s-attribute-loader.js +1 -1
- package/dist/esm/i3s-attribute-loader.js.map +1 -1
- package/dist/esm/i3s-building-scene-layer-loader.js +1 -1
- package/dist/esm/i3s-building-scene-layer-loader.js.map +1 -1
- package/dist/esm/i3s-content-loader.js +1 -1
- package/dist/esm/i3s-content-loader.js.map +1 -1
- package/dist/esm/i3s-loader.js +1 -1
- package/dist/esm/i3s-loader.js.map +1 -1
- package/dist/esm/i3s-node-page-loader.js +1 -1
- package/dist/esm/i3s-node-page-loader.js.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/helpers/i3s-nodepages-tiles.js +33 -23
- package/dist/esm/lib/helpers/i3s-nodepages-tiles.js.map +1 -1
- package/dist/esm/lib/parsers/constants.js +2 -18
- package/dist/esm/lib/parsers/constants.js.map +1 -1
- package/dist/esm/lib/parsers/parse-i3s-tile-content.js +44 -61
- package/dist/esm/lib/parsers/parse-i3s-tile-content.js.map +1 -1
- package/dist/esm/lib/parsers/parse-i3s.js +40 -25
- package/dist/esm/lib/parsers/parse-i3s.js.map +1 -1
- package/dist/esm/lib/utils/url-utils.js +2 -3
- package/dist/esm/lib/utils/url-utils.js.map +1 -1
- package/dist/esm/types.js +7 -0
- package/dist/esm/types.js.map +1 -1
- package/dist/i3s-building-scene-layer-loader.js +1 -1
- package/dist/i3s-content-loader.js +1 -1
- package/dist/i3s-content-worker.js +106 -95
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/helpers/i3s-nodepages-tiles.d.ts +20 -20
- package/dist/lib/helpers/i3s-nodepages-tiles.d.ts.map +1 -1
- package/dist/lib/helpers/i3s-nodepages-tiles.js +33 -32
- package/dist/lib/parsers/constants.d.ts +1 -17
- package/dist/lib/parsers/constants.d.ts.map +1 -1
- package/dist/lib/parsers/constants.js +3 -21
- package/dist/lib/parsers/parse-i3s-attribute.d.ts +1 -1
- package/dist/lib/parsers/parse-i3s-tile-content.d.ts +2 -2
- package/dist/lib/parsers/parse-i3s-tile-content.d.ts.map +1 -1
- package/dist/lib/parsers/parse-i3s-tile-content.js +35 -61
- package/dist/lib/parsers/parse-i3s.d.ts +5 -3
- package/dist/lib/parsers/parse-i3s.d.ts.map +1 -1
- package/dist/lib/parsers/parse-i3s.js +37 -32
- package/dist/lib/utils/url-utils.d.ts +6 -6
- package/dist/lib/utils/url-utils.d.ts.map +1 -1
- package/dist/lib/utils/url-utils.js +5 -5
- package/dist/types.d.ts +289 -74
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -1
- package/package.json +10 -10
- package/src/i3s-building-scene-layer-loader.ts +1 -1
- package/src/i3s-content-loader.ts +1 -1
- package/src/index.ts +3 -3
- package/src/lib/helpers/i3s-nodepages-tiles.ts +71 -55
- package/src/lib/parsers/constants.ts +2 -22
- package/src/lib/parsers/parse-i3s-tile-content.ts +74 -103
- package/src/lib/parsers/parse-i3s.ts +48 -37
- package/src/lib/utils/url-utils.ts +7 -7
- package/src/types.ts +302 -93
package/src/index.ts
CHANGED
|
@@ -15,13 +15,13 @@ export type {
|
|
|
15
15
|
LodSelection,
|
|
16
16
|
NodeReference,
|
|
17
17
|
Resource,
|
|
18
|
-
I3SGeometry,
|
|
19
18
|
MaxScreenThresholdSQ,
|
|
20
19
|
NodeInPage,
|
|
21
20
|
SharedResources,
|
|
22
|
-
TextureImage,
|
|
23
21
|
Attribute,
|
|
24
22
|
Extent,
|
|
25
|
-
FeatureAttribute
|
|
23
|
+
FeatureAttribute,
|
|
24
|
+
FieldInfo,
|
|
25
|
+
I3SMaterialDefinition
|
|
26
26
|
} from './types';
|
|
27
27
|
export {COORDINATE_SYSTEM} from './lib/parsers/constants';
|
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
import {load} from '@loaders.gl/core';
|
|
2
2
|
import {getSupportedGPUTextureFormats, selectSupportedBasisFormat} from '@loaders.gl/textures';
|
|
3
|
-
import {Tileset, NodePage} from '../../types';
|
|
4
3
|
import {I3SNodePageLoader} from '../../i3s-node-page-loader';
|
|
5
4
|
import {normalizeTileNonUrlData} from '../parsers/parse-i3s';
|
|
6
5
|
import {getUrlWithToken, generateTilesetAttributeUrls} from '../utils/url-utils';
|
|
6
|
+
import type {LoaderOptions} from '@loaders.gl/loader-utils';
|
|
7
|
+
import {
|
|
8
|
+
I3STilesetHeader,
|
|
9
|
+
LodSelection,
|
|
10
|
+
NodePage,
|
|
11
|
+
NodeInPage,
|
|
12
|
+
Obb,
|
|
13
|
+
MeshMaterial,
|
|
14
|
+
I3SMaterialDefinition,
|
|
15
|
+
I3STextureFormat,
|
|
16
|
+
MeshGeometry,
|
|
17
|
+
I3STileHeader
|
|
18
|
+
} from '../../types';
|
|
7
19
|
|
|
8
20
|
/**
|
|
9
21
|
* class I3SNodePagesTiles - loads nodePages and form i3s tiles from them
|
|
10
22
|
*/
|
|
11
23
|
export default class I3SNodePagesTiles {
|
|
12
|
-
tileset:
|
|
24
|
+
tileset: I3STilesetHeader;
|
|
13
25
|
nodePages: NodePage[] = [];
|
|
14
26
|
pendingNodePages: {promise: Promise<NodePage>; status: 'Pending' | 'Done'}[] = [];
|
|
15
27
|
nodesPerPage: number;
|
|
16
|
-
options:
|
|
17
|
-
lodSelectionMetricType
|
|
18
|
-
textureDefinitionsSelectedFormats:
|
|
28
|
+
options: LoaderOptions;
|
|
29
|
+
lodSelectionMetricType?: string;
|
|
30
|
+
textureDefinitionsSelectedFormats: ({format: I3STextureFormat; name: string} | null)[] = [];
|
|
19
31
|
private textureLoaderOptions: {[key: string]: any} = {};
|
|
20
32
|
|
|
21
33
|
/**
|
|
@@ -24,10 +36,10 @@ export default class I3SNodePagesTiles {
|
|
|
24
36
|
* @param tileset - i3s tileset header ('layers/0')
|
|
25
37
|
* @param options - i3s loader options
|
|
26
38
|
*/
|
|
27
|
-
constructor(tileset:
|
|
39
|
+
constructor(tileset: I3STilesetHeader, options: LoaderOptions) {
|
|
28
40
|
this.tileset = {...tileset}; // spread the tileset to avoid circular reference
|
|
29
|
-
this.nodesPerPage = tileset.nodePages
|
|
30
|
-
this.lodSelectionMetricType = tileset.nodePages
|
|
41
|
+
this.nodesPerPage = tileset.nodePages?.nodesPerPage || 64;
|
|
42
|
+
this.lodSelectionMetricType = tileset.nodePages?.lodSelectionMetricType;
|
|
31
43
|
this.options = options;
|
|
32
44
|
|
|
33
45
|
this.initSelectedFormatsForTextureDefinitions(tileset);
|
|
@@ -37,7 +49,7 @@ export default class I3SNodePagesTiles {
|
|
|
37
49
|
* Loads some nodePage and return a particular node from it
|
|
38
50
|
* @param id - id of node through all node pages
|
|
39
51
|
*/
|
|
40
|
-
async getNodeById(id: number) {
|
|
52
|
+
async getNodeById(id: number): Promise<NodeInPage> {
|
|
41
53
|
const pageIndex = Math.floor(id / this.nodesPerPage);
|
|
42
54
|
if (!this.nodePages[pageIndex] && !this.pendingNodePages[pageIndex]) {
|
|
43
55
|
const nodePageUrl = getUrlWithToken(
|
|
@@ -63,34 +75,33 @@ export default class I3SNodePagesTiles {
|
|
|
63
75
|
* @param id - id of node through all node pages
|
|
64
76
|
*/
|
|
65
77
|
// eslint-disable-next-line complexity
|
|
66
|
-
async formTileFromNodePages(id: number) {
|
|
67
|
-
const node = await this.getNodeById(id);
|
|
68
|
-
const children:
|
|
78
|
+
async formTileFromNodePages(id: number): Promise<I3STileHeader> {
|
|
79
|
+
const node: NodeInPage = await this.getNodeById(id);
|
|
80
|
+
const children: {id: string; obb: Obb}[] = [];
|
|
69
81
|
for (const child of node.children || []) {
|
|
70
82
|
const childNode = await this.getNodeById(child);
|
|
71
83
|
children.push({
|
|
72
|
-
id: child,
|
|
84
|
+
id: child.toString(),
|
|
73
85
|
obb: childNode.obb
|
|
74
86
|
});
|
|
75
87
|
}
|
|
76
88
|
|
|
77
|
-
let contentUrl
|
|
78
|
-
let textureUrl: string |
|
|
79
|
-
let materialDefinition
|
|
80
|
-
let textureFormat = '
|
|
89
|
+
let contentUrl: string | undefined;
|
|
90
|
+
let textureUrl: string | undefined;
|
|
91
|
+
let materialDefinition: I3SMaterialDefinition | undefined;
|
|
92
|
+
let textureFormat: I3STextureFormat = 'jpg';
|
|
81
93
|
let attributeUrls: string[] = [];
|
|
82
|
-
let isDracoGeometry = false;
|
|
94
|
+
let isDracoGeometry: boolean = false;
|
|
83
95
|
|
|
84
96
|
if (node && node.mesh) {
|
|
85
97
|
// Get geometry resource URL and type (compressed / non-compressed)
|
|
86
98
|
const {url, isDracoGeometry: isDracoGeometryResult} = (node.mesh.geometry &&
|
|
87
|
-
this.getContentUrl(node.mesh.geometry)) || {
|
|
99
|
+
this.getContentUrl(node.mesh.geometry)) || {isDracoGeometry: false};
|
|
88
100
|
contentUrl = url;
|
|
89
101
|
isDracoGeometry = isDracoGeometryResult;
|
|
90
102
|
|
|
91
|
-
const
|
|
92
|
-
node.mesh.material
|
|
93
|
-
);
|
|
103
|
+
const {textureData, materialDefinition: nodeMaterialDefinition} =
|
|
104
|
+
this.getInformationFromMaterial(node.mesh.material);
|
|
94
105
|
materialDefinition = nodeMaterialDefinition;
|
|
95
106
|
textureFormat = textureData.format || textureFormat;
|
|
96
107
|
if (textureData.name) {
|
|
@@ -105,7 +116,7 @@ export default class I3SNodePagesTiles {
|
|
|
105
116
|
const lodSelection = this.getLodSelection(node);
|
|
106
117
|
|
|
107
118
|
return normalizeTileNonUrlData({
|
|
108
|
-
id,
|
|
119
|
+
id: id.toString(),
|
|
109
120
|
lodSelection,
|
|
110
121
|
obb: node.obb,
|
|
111
122
|
contentUrl,
|
|
@@ -121,13 +132,14 @@ export default class I3SNodePagesTiles {
|
|
|
121
132
|
|
|
122
133
|
/**
|
|
123
134
|
* Forms url and type of geometry resource by nodepage's data and `geometryDefinitions` in the tileset
|
|
124
|
-
* @param
|
|
125
|
-
* @returns
|
|
135
|
+
* @param - data about the node's mesh from the nodepage
|
|
136
|
+
* @returns -
|
|
126
137
|
* {string} url - url to the geometry resource
|
|
127
138
|
* {boolean} isDracoGeometry - whether the geometry resource contain DRACO compressed geometry
|
|
128
139
|
*/
|
|
129
|
-
private getContentUrl(meshGeometryData) {
|
|
130
|
-
let result =
|
|
140
|
+
private getContentUrl(meshGeometryData: MeshGeometry) {
|
|
141
|
+
let result: {url: string; isDracoGeometry: boolean} | null = null;
|
|
142
|
+
// @ts-ignore
|
|
131
143
|
const geometryDefinition = this.tileset.geometryDefinitions[meshGeometryData.definition];
|
|
132
144
|
let geometryIndex = -1;
|
|
133
145
|
// Try to find DRACO geometryDefinition of `useDracoGeometry` option is set
|
|
@@ -156,21 +168,21 @@ export default class I3SNodePagesTiles {
|
|
|
156
168
|
|
|
157
169
|
/**
|
|
158
170
|
* Forms 1.6 compatible LOD selection object from a nodepage's node data
|
|
159
|
-
* @param
|
|
160
|
-
* @returns
|
|
161
|
-
* {string} metricType - the label of the LOD metric
|
|
162
|
-
* {number} maxError - the value of the metric
|
|
171
|
+
* @param node - a node from nodepage
|
|
172
|
+
* @returns- Array of LodSelection
|
|
163
173
|
*/
|
|
164
|
-
private getLodSelection(node):
|
|
165
|
-
const lodSelection:
|
|
174
|
+
private getLodSelection(node: NodeInPage): LodSelection[] {
|
|
175
|
+
const lodSelection: LodSelection[] = [];
|
|
166
176
|
if (this.lodSelectionMetricType === 'maxScreenThresholdSQ') {
|
|
167
177
|
lodSelection.push({
|
|
168
178
|
metricType: 'maxScreenThreshold',
|
|
179
|
+
// @ts-ignore
|
|
169
180
|
maxError: Math.sqrt(node.lodThreshold / (Math.PI * 0.25))
|
|
170
181
|
});
|
|
171
182
|
}
|
|
172
183
|
lodSelection.push({
|
|
173
184
|
metricType: this.lodSelectionMetricType,
|
|
185
|
+
// @ts-ignore
|
|
174
186
|
maxError: node.lodThreshold
|
|
175
187
|
});
|
|
176
188
|
return lodSelection;
|
|
@@ -178,43 +190,47 @@ export default class I3SNodePagesTiles {
|
|
|
178
190
|
|
|
179
191
|
/**
|
|
180
192
|
* Returns information about texture and material from `materialDefinitions`
|
|
181
|
-
* @param
|
|
182
|
-
* @returns
|
|
193
|
+
* @param material - material data from nodepage
|
|
194
|
+
* @returns - Couple {textureData, materialDefinition}
|
|
183
195
|
* {string} textureData.name - path name of the texture
|
|
184
196
|
* {string} textureData.format - format of the texture
|
|
185
197
|
* materialDefinition - PBR-like material definition from `materialDefinitions`
|
|
186
198
|
*/
|
|
187
|
-
private getInformationFromMaterial(material) {
|
|
188
|
-
const
|
|
199
|
+
private getInformationFromMaterial(material: MeshMaterial) {
|
|
200
|
+
const informationFromMaterial: {
|
|
201
|
+
textureData: {name: string | null; format?: I3STextureFormat};
|
|
202
|
+
materialDefinition?: I3SMaterialDefinition;
|
|
203
|
+
} = {textureData: {name: null}};
|
|
204
|
+
|
|
189
205
|
if (material) {
|
|
190
|
-
const materialDefinition = this.tileset.materialDefinitions[material.definition];
|
|
191
|
-
|
|
192
|
-
materialDefinition
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
206
|
+
const materialDefinition = this.tileset.materialDefinitions?.[material.definition];
|
|
207
|
+
if (materialDefinition) {
|
|
208
|
+
informationFromMaterial.materialDefinition = materialDefinition;
|
|
209
|
+
const textureSetDefinitionIndex =
|
|
210
|
+
materialDefinition?.pbrMetallicRoughness?.baseColorTexture?.textureSetDefinitionId;
|
|
211
|
+
|
|
212
|
+
if (typeof textureSetDefinitionIndex === 'number') {
|
|
213
|
+
informationFromMaterial.textureData =
|
|
214
|
+
this.textureDefinitionsSelectedFormats[textureSetDefinitionIndex] ||
|
|
215
|
+
informationFromMaterial.textureData;
|
|
216
|
+
}
|
|
200
217
|
}
|
|
201
|
-
return [textureDataDefault, materialDefinition];
|
|
202
218
|
}
|
|
203
|
-
return
|
|
219
|
+
return informationFromMaterial;
|
|
204
220
|
}
|
|
205
221
|
|
|
206
222
|
/**
|
|
207
223
|
* Sets preferable and supported format for each textureDefinition of the tileset
|
|
208
|
-
* @param
|
|
209
|
-
* @returns
|
|
224
|
+
* @param tileset - I3S layer data
|
|
225
|
+
* @returns
|
|
210
226
|
*/
|
|
211
|
-
private initSelectedFormatsForTextureDefinitions(tileset) {
|
|
227
|
+
private initSelectedFormatsForTextureDefinitions(tileset: I3STilesetHeader): void {
|
|
212
228
|
this.textureDefinitionsSelectedFormats = [];
|
|
213
229
|
const possibleI3sFormats = this.getSupportedTextureFormats();
|
|
214
230
|
const textureSetDefinitions = tileset.textureSetDefinitions || [];
|
|
215
231
|
for (const textureSetDefinition of textureSetDefinitions) {
|
|
216
232
|
const formats = (textureSetDefinition && textureSetDefinition.formats) || [];
|
|
217
|
-
let selectedFormat: {
|
|
233
|
+
let selectedFormat: {name: string; format: I3STextureFormat} | null = null;
|
|
218
234
|
for (const i3sFormat of possibleI3sFormats) {
|
|
219
235
|
const format = formats.find((value) => value.format === i3sFormat);
|
|
220
236
|
if (format) {
|
|
@@ -239,8 +255,8 @@ export default class I3SNodePagesTiles {
|
|
|
239
255
|
* Returns the array of supported texture format
|
|
240
256
|
* @returns list of format strings
|
|
241
257
|
*/
|
|
242
|
-
private getSupportedTextureFormats():
|
|
243
|
-
const formats:
|
|
258
|
+
private getSupportedTextureFormats(): I3STextureFormat[] {
|
|
259
|
+
const formats: I3STextureFormat[] = [];
|
|
244
260
|
if (!this.options.i3s || this.options.i3s.useCompressedTextures) {
|
|
245
261
|
// I3S 1.7 selection
|
|
246
262
|
const supportedCompressedFormats = getSupportedGPUTextureFormats();
|
|
@@ -14,7 +14,7 @@ export function getConstructorForDataFormat(dataType: string) {
|
|
|
14
14
|
case DATA_TYPE.UInt64:
|
|
15
15
|
return Float64Array;
|
|
16
16
|
default:
|
|
17
|
-
|
|
17
|
+
throw new Error(`parse i3s tile content: unknown type of data: ${dataType}`);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -25,26 +25,6 @@ export const GL_TYPE_MAP: {[key: string]: number} = {
|
|
|
25
25
|
UInt32: GL.UNSIGNED_INT,
|
|
26
26
|
UInt64: GL.DOUBLE
|
|
27
27
|
};
|
|
28
|
-
|
|
29
|
-
export const I3S_NAMED_VERTEX_ATTRIBUTES = {
|
|
30
|
-
position: 'position',
|
|
31
|
-
normal: 'normal',
|
|
32
|
-
uv0: 'uv0',
|
|
33
|
-
color: 'color',
|
|
34
|
-
region: 'region'
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export const I3S_NAMED_GEOMETRY_ATTRIBUTES = {
|
|
38
|
-
vertexAttributes: 'vertexAttributes',
|
|
39
|
-
featureAttributeOrder: 'featureAttributeOrder',
|
|
40
|
-
featureAttributes: 'featureAttributes'
|
|
41
|
-
};
|
|
42
|
-
// TODO Remove Named Attributes and replase with Typescipt types
|
|
43
|
-
export const I3S_NAMED_HEADER_ATTRIBUTES = {
|
|
44
|
-
// header: 'header',
|
|
45
|
-
vertexCount: 'vertexCount',
|
|
46
|
-
featureCount: 'featureCount'
|
|
47
|
-
};
|
|
48
28
|
/**
|
|
49
29
|
* Returns how many bytes a type occupies
|
|
50
30
|
* @param dataType
|
|
@@ -66,7 +46,7 @@ export function sizeOf(dataType: string): number {
|
|
|
66
46
|
case DATA_TYPE.Float64:
|
|
67
47
|
return 8;
|
|
68
48
|
default:
|
|
69
|
-
|
|
49
|
+
throw new Error(`parse i3s tile content: unknown size of data: ${dataType}`);
|
|
70
50
|
}
|
|
71
51
|
}
|
|
72
52
|
|
|
@@ -2,49 +2,39 @@ 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
|
-
import type {GLTFMaterial} from '@loaders.gl/gltf';
|
|
7
5
|
import type {LoaderOptions, LoaderContext} from '@loaders.gl/loader-utils';
|
|
8
6
|
import {ImageLoader} from '@loaders.gl/images';
|
|
9
|
-
import {DracoLoader} from '@loaders.gl/draco';
|
|
7
|
+
import {DracoLoader, DracoMesh} from '@loaders.gl/draco';
|
|
10
8
|
import {BasisLoader, CompressedTextureLoader} from '@loaders.gl/textures';
|
|
11
9
|
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
import {
|
|
11
|
+
I3STilesetHeader,
|
|
12
|
+
I3STileHeader,
|
|
15
13
|
FeatureAttribute,
|
|
16
|
-
TileContent,
|
|
17
14
|
VertexAttribute,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
TileContentTexture
|
|
15
|
+
I3SMeshAttributes,
|
|
16
|
+
I3SMeshAttribute,
|
|
17
|
+
TileContentTexture,
|
|
18
|
+
HeaderAttributeProperty,
|
|
19
|
+
I3SMaterialDefinition
|
|
21
20
|
} from '../../types';
|
|
22
21
|
import {getUrlWithToken} from '../utils/url-utils';
|
|
23
22
|
|
|
24
|
-
import {
|
|
25
|
-
GL_TYPE_MAP,
|
|
26
|
-
getConstructorForDataFormat,
|
|
27
|
-
sizeOf,
|
|
28
|
-
I3S_NAMED_HEADER_ATTRIBUTES,
|
|
29
|
-
I3S_NAMED_VERTEX_ATTRIBUTES,
|
|
30
|
-
I3S_NAMED_GEOMETRY_ATTRIBUTES,
|
|
31
|
-
COORDINATE_SYSTEM
|
|
32
|
-
} from './constants';
|
|
23
|
+
import {GL_TYPE_MAP, getConstructorForDataFormat, sizeOf, COORDINATE_SYSTEM} from './constants';
|
|
33
24
|
|
|
34
25
|
const scratchVector = new Vector3([0, 0, 0]);
|
|
35
26
|
|
|
36
|
-
function getLoaderForTextureFormat(textureFormat
|
|
27
|
+
function getLoaderForTextureFormat(textureFormat?: 'jpg' | 'png' | 'ktx-etc2' | 'dds' | 'ktx2') {
|
|
37
28
|
switch (textureFormat) {
|
|
38
|
-
case 'jpeg':
|
|
39
|
-
case 'png':
|
|
40
|
-
return ImageLoader;
|
|
41
29
|
case 'ktx-etc2':
|
|
42
30
|
case 'dds':
|
|
43
31
|
return CompressedTextureLoader;
|
|
44
32
|
case 'ktx2':
|
|
45
33
|
return BasisLoader;
|
|
34
|
+
case 'jpg':
|
|
35
|
+
case 'png':
|
|
46
36
|
default:
|
|
47
|
-
return
|
|
37
|
+
return ImageLoader;
|
|
48
38
|
}
|
|
49
39
|
}
|
|
50
40
|
|
|
@@ -52,22 +42,19 @@ const I3S_ATTRIBUTE_TYPE = 'i3s-attribute-type';
|
|
|
52
42
|
|
|
53
43
|
export async function parseI3STileContent(
|
|
54
44
|
arrayBuffer: ArrayBuffer,
|
|
55
|
-
tile:
|
|
56
|
-
tileset:
|
|
45
|
+
tile: I3STileHeader,
|
|
46
|
+
tileset: I3STilesetHeader,
|
|
57
47
|
options?: LoaderOptions,
|
|
58
48
|
context?: LoaderContext
|
|
59
49
|
) {
|
|
60
50
|
tile.content = tile.content || {};
|
|
61
51
|
tile.content.featureIds = tile.content.featureIds || null;
|
|
62
52
|
|
|
63
|
-
// construct featureData from defaultGeometrySchema;
|
|
64
|
-
tile.content.featureData = constructFeatureDataStruct(tileset);
|
|
65
53
|
tile.content.attributes = {};
|
|
66
54
|
|
|
67
55
|
if (tile.textureUrl) {
|
|
68
56
|
const url = getUrlWithToken(tile.textureUrl, options?.i3s?.token);
|
|
69
|
-
const loader = getLoaderForTextureFormat(tile.textureFormat)
|
|
70
|
-
// @ts-ignore context must be defined
|
|
57
|
+
const loader = getLoaderForTextureFormat(tile.textureFormat);
|
|
71
58
|
const response = await fetch(url);
|
|
72
59
|
const arrayBuffer = await response.arrayBuffer();
|
|
73
60
|
|
|
@@ -104,30 +91,36 @@ export async function parseI3STileContent(
|
|
|
104
91
|
tile.content.texture = null;
|
|
105
92
|
}
|
|
106
93
|
|
|
107
|
-
return await parseI3SNodeGeometry(arrayBuffer, tile, options);
|
|
94
|
+
return await parseI3SNodeGeometry(arrayBuffer, tile, tileset, options);
|
|
108
95
|
}
|
|
109
96
|
|
|
110
97
|
/* eslint-disable max-statements */
|
|
111
|
-
async function parseI3SNodeGeometry(
|
|
98
|
+
async function parseI3SNodeGeometry(
|
|
99
|
+
arrayBuffer: ArrayBuffer,
|
|
100
|
+
tile: I3STileHeader,
|
|
101
|
+
tileset: I3STilesetHeader,
|
|
102
|
+
options?: LoaderOptions
|
|
103
|
+
) {
|
|
112
104
|
if (!tile.content) {
|
|
113
105
|
return tile;
|
|
114
106
|
}
|
|
115
107
|
|
|
116
108
|
const content = tile.content;
|
|
117
|
-
let attributes:
|
|
109
|
+
let attributes: I3SMeshAttributes;
|
|
118
110
|
let vertexCount: number;
|
|
119
111
|
let byteOffset: number = 0;
|
|
120
112
|
let featureCount: number = 0;
|
|
113
|
+
let indices: TypedArray | undefined;
|
|
121
114
|
|
|
122
115
|
if (tile.isDracoGeometry) {
|
|
123
|
-
const decompressedGeometry = await parse(arrayBuffer, DracoLoader, {
|
|
116
|
+
const decompressedGeometry: DracoMesh = await parse(arrayBuffer, DracoLoader, {
|
|
124
117
|
draco: {
|
|
125
118
|
attributeNameEntry: I3S_ATTRIBUTE_TYPE
|
|
126
119
|
}
|
|
127
120
|
});
|
|
128
|
-
|
|
121
|
+
// @ts-expect-error
|
|
129
122
|
vertexCount = decompressedGeometry.header.vertexCount;
|
|
130
|
-
|
|
123
|
+
indices = decompressedGeometry.indices?.value;
|
|
131
124
|
const {
|
|
132
125
|
POSITION,
|
|
133
126
|
NORMAL,
|
|
@@ -143,8 +136,7 @@ async function parseI3SNodeGeometry(arrayBuffer: ArrayBuffer, tile: Tile, option
|
|
|
143
136
|
color: COLOR_0,
|
|
144
137
|
uv0: TEXCOORD_0,
|
|
145
138
|
uvRegion,
|
|
146
|
-
id: featureIndex
|
|
147
|
-
indices
|
|
139
|
+
id: featureIndex
|
|
148
140
|
};
|
|
149
141
|
|
|
150
142
|
updateAttributesMetadata(attributes, decompressedGeometry);
|
|
@@ -155,10 +147,14 @@ async function parseI3SNodeGeometry(arrayBuffer: ArrayBuffer, tile: Tile, option
|
|
|
155
147
|
flattenFeatureIdsByFeatureIndices(attributes, featureIds);
|
|
156
148
|
}
|
|
157
149
|
} else {
|
|
158
|
-
const {
|
|
159
|
-
|
|
150
|
+
const {
|
|
151
|
+
vertexAttributes,
|
|
152
|
+
ordering: attributesOrder,
|
|
153
|
+
featureAttributes,
|
|
154
|
+
featureAttributeOrder
|
|
155
|
+
} = tileset.store.defaultGeometrySchema;
|
|
160
156
|
// First 8 bytes reserved for header (vertexCount and featureCount)
|
|
161
|
-
const headers = parseHeaders(
|
|
157
|
+
const headers = parseHeaders(tileset, arrayBuffer);
|
|
162
158
|
byteOffset = headers.byteOffset;
|
|
163
159
|
vertexCount = headers.vertexCount;
|
|
164
160
|
featureCount = headers.featureCount;
|
|
@@ -168,7 +164,6 @@ async function parseI3SNodeGeometry(arrayBuffer: ArrayBuffer, tile: Tile, option
|
|
|
168
164
|
byteOffset,
|
|
169
165
|
vertexAttributes,
|
|
170
166
|
vertexCount,
|
|
171
|
-
// @ts-expect-error
|
|
172
167
|
attributesOrder
|
|
173
168
|
);
|
|
174
169
|
|
|
@@ -204,7 +199,7 @@ async function parseI3SNodeGeometry(arrayBuffer: ArrayBuffer, tile: Tile, option
|
|
|
204
199
|
texCoords: attributes.uv0,
|
|
205
200
|
uvRegions: normalizeAttribute(attributes.uvRegion) // Normalize from UInt16
|
|
206
201
|
};
|
|
207
|
-
content.indices =
|
|
202
|
+
content.indices = indices || null;
|
|
208
203
|
|
|
209
204
|
if (attributes.id && attributes.id.value) {
|
|
210
205
|
tile.content.featureIds = attributes.id.value;
|
|
@@ -228,7 +223,10 @@ async function parseI3SNodeGeometry(arrayBuffer: ArrayBuffer, tile: Tile, option
|
|
|
228
223
|
* @param decompressedGeometry
|
|
229
224
|
* @param attributes
|
|
230
225
|
*/
|
|
231
|
-
function updateAttributesMetadata(
|
|
226
|
+
function updateAttributesMetadata(
|
|
227
|
+
attributes: I3SMeshAttributes,
|
|
228
|
+
decompressedGeometry: DracoMesh
|
|
229
|
+
): void {
|
|
232
230
|
for (const key in decompressedGeometry.loaderData.attributes) {
|
|
233
231
|
const dracoAttribute = decompressedGeometry.loaderData.attributes[key];
|
|
234
232
|
|
|
@@ -253,9 +251,9 @@ function updateAttributesMetadata(attributes: NormalizedAttributes, decompressed
|
|
|
253
251
|
* @returns - result of attributes concatenation.
|
|
254
252
|
*/
|
|
255
253
|
function concatAttributes(
|
|
256
|
-
normalizedVertexAttributes:
|
|
257
|
-
normalizedFeatureAttributes:
|
|
258
|
-
):
|
|
254
|
+
normalizedVertexAttributes: I3SMeshAttributes,
|
|
255
|
+
normalizedFeatureAttributes: I3SMeshAttributes
|
|
256
|
+
): I3SMeshAttributes {
|
|
259
257
|
return {...normalizedVertexAttributes, ...normalizedFeatureAttributes};
|
|
260
258
|
}
|
|
261
259
|
|
|
@@ -264,7 +262,7 @@ function concatAttributes(
|
|
|
264
262
|
* @param attribute - geometry attribute
|
|
265
263
|
* @returns - geometry attribute in right format
|
|
266
264
|
*/
|
|
267
|
-
function normalizeAttribute(attribute:
|
|
265
|
+
function normalizeAttribute(attribute: I3SMeshAttribute): I3SMeshAttribute {
|
|
268
266
|
if (!attribute) {
|
|
269
267
|
return attribute;
|
|
270
268
|
}
|
|
@@ -272,49 +270,26 @@ function normalizeAttribute(attribute: NormalizedAttribute): NormalizedAttribute
|
|
|
272
270
|
return attribute;
|
|
273
271
|
}
|
|
274
272
|
|
|
275
|
-
function
|
|
276
|
-
// seed featureData from defaultGeometrySchema
|
|
277
|
-
const defaultGeometrySchema = tileset.store.defaultGeometrySchema;
|
|
278
|
-
const featureData = defaultGeometrySchema;
|
|
279
|
-
// populate the vertex attributes value types and values per element
|
|
280
|
-
for (const geometryAttribute in I3S_NAMED_GEOMETRY_ATTRIBUTES) {
|
|
281
|
-
for (const namedAttribute in I3S_NAMED_VERTEX_ATTRIBUTES) {
|
|
282
|
-
const attribute = defaultGeometrySchema[geometryAttribute][namedAttribute];
|
|
283
|
-
if (attribute) {
|
|
284
|
-
const {byteOffset = 0, count = 0, valueType, valuesPerElement} = attribute;
|
|
285
|
-
|
|
286
|
-
featureData[geometryAttribute][namedAttribute] = {
|
|
287
|
-
valueType,
|
|
288
|
-
valuesPerElement,
|
|
289
|
-
byteOffset,
|
|
290
|
-
count
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
featureData.attributesOrder = defaultGeometrySchema.ordering;
|
|
297
|
-
return featureData;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
function parseHeaders(content: TileContent, arrayBuffer: ArrayBuffer) {
|
|
273
|
+
function parseHeaders(tileset: I3STilesetHeader, arrayBuffer: ArrayBuffer) {
|
|
301
274
|
let byteOffset = 0;
|
|
302
275
|
// First 8 bytes reserved for header (vertexCount and featurecount)
|
|
303
276
|
let vertexCount = 0;
|
|
304
277
|
let featureCount = 0;
|
|
305
|
-
|
|
278
|
+
for (const {property, type} of tileset.store.defaultGeometrySchema.header) {
|
|
306
279
|
const TypedArrayTypeHeader = getConstructorForDataFormat(type);
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
280
|
+
switch (property) {
|
|
281
|
+
case HeaderAttributeProperty.vertexCount:
|
|
282
|
+
vertexCount = new TypedArrayTypeHeader(arrayBuffer, 0, 4)[0];
|
|
283
|
+
byteOffset += sizeOf(type);
|
|
284
|
+
break;
|
|
285
|
+
case HeaderAttributeProperty.featureCount:
|
|
286
|
+
featureCount = new TypedArrayTypeHeader(arrayBuffer, 4, 4)[0];
|
|
287
|
+
byteOffset += sizeOf(type);
|
|
288
|
+
break;
|
|
289
|
+
default:
|
|
290
|
+
break;
|
|
316
291
|
}
|
|
317
|
-
}
|
|
292
|
+
}
|
|
318
293
|
|
|
319
294
|
return {
|
|
320
295
|
vertexCount,
|
|
@@ -332,7 +307,7 @@ function normalizeAttributes(
|
|
|
332
307
|
vertexCount: number,
|
|
333
308
|
attributesOrder: string[]
|
|
334
309
|
) {
|
|
335
|
-
const attributes:
|
|
310
|
+
const attributes: I3SMeshAttributes = {};
|
|
336
311
|
|
|
337
312
|
// the order of attributes depend on the order being added to the vertexAttributes object
|
|
338
313
|
for (const attribute of attributesOrder) {
|
|
@@ -351,13 +326,12 @@ function normalizeAttributes(
|
|
|
351
326
|
break;
|
|
352
327
|
}
|
|
353
328
|
const buffer = arrayBuffer.slice(byteOffset);
|
|
354
|
-
let value:
|
|
329
|
+
let value: TypedArray;
|
|
355
330
|
|
|
356
331
|
if (valueType === 'UInt64') {
|
|
357
332
|
value = parseUint64Values(buffer, count * valuesPerElement, sizeOf(valueType));
|
|
358
333
|
} else {
|
|
359
334
|
const TypedArrayType = getConstructorForDataFormat(valueType);
|
|
360
|
-
// @ts-expect-error
|
|
361
335
|
value = new TypedArrayType(buffer, 0, count * valuesPerElement);
|
|
362
336
|
}
|
|
363
337
|
|
|
@@ -395,7 +369,7 @@ function parseUint64Values(
|
|
|
395
369
|
buffer: ArrayBuffer,
|
|
396
370
|
elementsCount: number,
|
|
397
371
|
attributeSize: number
|
|
398
|
-
):
|
|
372
|
+
): Uint32Array {
|
|
399
373
|
const values: number[] = [];
|
|
400
374
|
const dataView = new DataView(buffer);
|
|
401
375
|
let offset = 0;
|
|
@@ -411,10 +385,10 @@ function parseUint64Values(
|
|
|
411
385
|
offset += attributeSize;
|
|
412
386
|
}
|
|
413
387
|
|
|
414
|
-
return values;
|
|
388
|
+
return new Uint32Array(values);
|
|
415
389
|
}
|
|
416
390
|
|
|
417
|
-
function parsePositions(attribute:
|
|
391
|
+
function parsePositions(attribute: I3SMeshAttribute, tile: I3STileHeader): Matrix4 {
|
|
418
392
|
const mbs = tile.mbs;
|
|
419
393
|
const value = attribute.value;
|
|
420
394
|
const metadata = attribute.metadata;
|
|
@@ -466,7 +440,7 @@ function offsetsToCartesians(
|
|
|
466
440
|
* @param positions positions attribute
|
|
467
441
|
* @returns Matrix4 - model matrix for geometry transformation
|
|
468
442
|
*/
|
|
469
|
-
function getModelMatrix(positions:
|
|
443
|
+
function getModelMatrix(positions: I3SMeshAttribute): Matrix4 {
|
|
470
444
|
const metadata = positions.metadata;
|
|
471
445
|
const scaleX: number = metadata?.['i3s-scale_x']?.double || 1;
|
|
472
446
|
const scaleY: number = metadata?.['i3s-scale_y']?.double || 1;
|
|
@@ -483,7 +457,7 @@ function getModelMatrix(positions: NormalizedAttribute): Matrix4 {
|
|
|
483
457
|
* @param texture - texture image
|
|
484
458
|
* @returns {object}
|
|
485
459
|
*/
|
|
486
|
-
function makePbrMaterial(materialDefinition
|
|
460
|
+
function makePbrMaterial(materialDefinition?: I3SMaterialDefinition, texture?: TileContentTexture) {
|
|
487
461
|
let pbrMaterial;
|
|
488
462
|
if (materialDefinition) {
|
|
489
463
|
pbrMaterial = {
|
|
@@ -521,7 +495,9 @@ function makePbrMaterial(materialDefinition: GLTFMaterial, texture: TileContentT
|
|
|
521
495
|
);
|
|
522
496
|
}
|
|
523
497
|
|
|
524
|
-
|
|
498
|
+
if (texture) {
|
|
499
|
+
setMaterialTexture(pbrMaterial, texture);
|
|
500
|
+
}
|
|
525
501
|
|
|
526
502
|
return pbrMaterial;
|
|
527
503
|
}
|
|
@@ -576,7 +552,7 @@ function setMaterialTexture(material, image: TileContentTexture): void {
|
|
|
576
552
|
* @param normalizedFeatureAttributes
|
|
577
553
|
* @returns
|
|
578
554
|
*/
|
|
579
|
-
function flattenFeatureIdsByFaceRanges(normalizedFeatureAttributes:
|
|
555
|
+
function flattenFeatureIdsByFaceRanges(normalizedFeatureAttributes: I3SMeshAttributes): void {
|
|
580
556
|
const {id, faceRange} = normalizedFeatureAttributes;
|
|
581
557
|
|
|
582
558
|
if (!id || !faceRange) {
|
|
@@ -614,7 +590,7 @@ function flattenFeatureIdsByFaceRanges(normalizedFeatureAttributes: NormalizedAt
|
|
|
614
590
|
* @returns
|
|
615
591
|
*/
|
|
616
592
|
function flattenFeatureIdsByFeatureIndices(
|
|
617
|
-
attributes:
|
|
593
|
+
attributes: I3SMeshAttributes,
|
|
618
594
|
featureIds: Int32Array
|
|
619
595
|
): void {
|
|
620
596
|
const featureIndices = attributes.id.value;
|
|
@@ -633,12 +609,7 @@ function flattenFeatureIdsByFeatureIndices(
|
|
|
633
609
|
* @returns
|
|
634
610
|
*/
|
|
635
611
|
function getFeatureIdsFromFeatureIndexMetadata(
|
|
636
|
-
featureIndex:
|
|
612
|
+
featureIndex: I3SMeshAttribute
|
|
637
613
|
): Int32Array | undefined {
|
|
638
|
-
return
|
|
639
|
-
featureIndex &&
|
|
640
|
-
featureIndex.metadata &&
|
|
641
|
-
featureIndex.metadata['i3s-feature-ids'] &&
|
|
642
|
-
featureIndex.metadata['i3s-feature-ids'].intArray
|
|
643
|
-
);
|
|
614
|
+
return featureIndex?.metadata?.['i3s-feature-ids']?.intArray;
|
|
644
615
|
}
|