@loaders.gl/tile-converter 5.0.0-alpha.1 → 5.0.0-alpha.11
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/LICENSE +14 -3
- package/README.md +497 -0
- package/dist/converter.min.cjs +210 -282
- package/dist/i3s-server/bin/i3s-server.min.cjs +106 -341
- package/dist/index.cjs +38586 -0
- package/dist/index.js +38557 -0
- package/dist/v5/adapters.cjs +3548 -0
- package/dist/v5/adapters.d.ts +33 -0
- package/dist/v5/adapters.js +3537 -0
- package/dist/v5/browser-sink.d.ts +37 -0
- package/dist/v5/browser-source.d.ts +38 -0
- package/dist/v5/browser-tileset-source.d.ts +70 -0
- package/dist/v5/browser.cjs +76 -0
- package/dist/v5/browser.d.ts +44 -0
- package/dist/v5/browser.js +75 -0
- package/dist/v5/conversion-api.d.ts +122 -0
- package/dist/v5/conversion-archive.d.ts +32 -0
- package/dist/v5/core.cjs +917 -0
- package/dist/v5/core.d.ts +16 -0
- package/dist/v5/core.js +899 -0
- package/dist/v5/feature-arrow.d.ts +36 -0
- package/dist/v5/i3s-mesh-conversion.d.ts +32 -0
- package/dist/v5/i3s-mesh-sink.d.ts +25 -0
- package/dist/v5/i3s-mesh-source-features.d.ts +13 -0
- package/dist/v5/i3s-mesh-source-material.d.ts +5 -0
- package/dist/v5/i3s-mesh-source.d.ts +30 -0
- package/dist/v5/index.cjs +73 -0
- package/dist/v5/index.d.ts +40 -0
- package/dist/v5/index.js +75 -0
- package/dist/v5/mesh-conversion.d.ts +71 -0
- package/dist/v5/mesh-draco.d.ts +8 -0
- package/dist/v5/mesh-features.d.ts +9 -0
- package/dist/v5/mesh-source-features.d.ts +21 -0
- package/dist/v5/mesh-source-texture.d.ts +6 -0
- package/dist/v5/mesh-source.d.ts +41 -0
- package/dist/v5/mesh-tileset-archive.d.ts +18 -0
- package/dist/v5/mesh-tileset-sink.d.ts +51 -0
- package/dist/v5/mesh.d.ts +86 -0
- package/dist/v5/point-cloud-conversion.d.ts +31 -0
- package/dist/v5/point-cloud-source-encoder.d.ts +46 -0
- package/dist/v5/point-cloud-source.d.ts +25 -0
- package/dist/v5/point-cloud-spatial.d.ts +22 -0
- package/dist/v5/point-cloud-tileset-sink.d.ts +28 -0
- package/dist/v5/point-cloud.d.ts +49 -0
- package/dist/v5/resource-fetcher.d.ts +18 -0
- package/dist/v5/resource-manifest.d.ts +58 -0
- package/dist/v5/spatial-conversion.d.ts +61 -0
- package/dist/v5/tileset-source.d.ts +21 -0
- package/package.json +52 -26
- package/src/common/README.md +5 -0
- package/src/index.ts +1 -2
- package/src/{3d-tiles-converter → v4/3d-tiles-converter}/3d-tiles-converter.ts +13 -2
- package/src/v4/3d-tiles-converter/helpers/validate-i3s-spatial-reference.ts +124 -0
- package/src/{deps-installer → v4/deps-installer}/deps-installer.ts +10 -7
- package/src/{i3s-converter → v4/i3s-converter}/helpers/batch-ids-extensions.ts +1 -1
- package/src/v4/i3s-converter/helpers/encode-string-attribute.ts +23 -0
- package/src/{i3s-converter → v4/i3s-converter}/helpers/geometry-converter.ts +30 -55
- package/src/{i3s-converter → v4/i3s-converter}/helpers/gltf-attributes.ts +5 -4
- package/src/{i3s-converter → v4/i3s-converter}/helpers/load-3d-tiles.ts +5 -9
- package/src/{i3s-converter → v4/i3s-converter}/i3s-converter.ts +6 -7
- package/src/{i3s-server → v4/i3s-server}/README.md +2 -2
- package/src/{i3s-server → v4/i3s-server}/routes/slpk-router.ts +1 -0
- package/src/v4/index.ts +2 -0
- package/src/{lib → v4/lib}/utils/compress-util.ts +8 -7
- package/src/v5/adapters.ts +75 -0
- package/src/v5/browser-sink.ts +130 -0
- package/src/v5/browser-source.ts +155 -0
- package/src/v5/browser-tileset-source.ts +328 -0
- package/src/v5/browser.ts +139 -0
- package/src/v5/conversion-api.ts +287 -0
- package/src/v5/conversion-archive.ts +85 -0
- package/src/v5/core.ts +61 -0
- package/src/v5/feature-arrow.ts +429 -0
- package/src/v5/i3s-mesh-conversion.ts +192 -0
- package/src/v5/i3s-mesh-sink.ts +351 -0
- package/src/v5/i3s-mesh-source-features.ts +279 -0
- package/src/v5/i3s-mesh-source-material.ts +157 -0
- package/src/v5/i3s-mesh-source.ts +227 -0
- package/src/v5/index.ts +131 -0
- package/src/v5/mesh-conversion.ts +230 -0
- package/src/v5/mesh-draco.ts +182 -0
- package/src/v5/mesh-features.ts +319 -0
- package/src/v5/mesh-source-features.ts +263 -0
- package/src/v5/mesh-source-texture.ts +169 -0
- package/src/v5/mesh-source.ts +422 -0
- package/src/v5/mesh-tileset-archive.ts +50 -0
- package/src/v5/mesh-tileset-sink.ts +324 -0
- package/src/v5/mesh.ts +526 -0
- package/src/v5/point-cloud-conversion.ts +88 -0
- package/src/v5/point-cloud-source-encoder.ts +116 -0
- package/src/v5/point-cloud-source.ts +84 -0
- package/src/v5/point-cloud-spatial.ts +280 -0
- package/src/v5/point-cloud-tileset-sink.ts +234 -0
- package/src/v5/point-cloud.ts +398 -0
- package/src/v5/resource-fetcher.ts +110 -0
- package/src/v5/resource-manifest.ts +213 -0
- package/src/v5/spatial-conversion.ts +389 -0
- package/src/v5/tileset-source.ts +54 -0
- /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/3d-tiles-content-converter.ts +0 -0
- /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/i3s-obb-to-3d-tiles-obb.ts +0 -0
- /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/load-i3s.ts +0 -0
- /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/helpers/texture-atlas.ts +0 -0
- /package/src/{3d-tiles-converter → v4/3d-tiles-converter}/json-templates/tileset.ts +0 -0
- /package/src/{constants.ts → v4/constants.ts} +0 -0
- /package/src/{converter-cli.ts → v4/converter-cli.ts} +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/attribute-metadata-info.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/coordinate-converter.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/create-scene-server-path.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/feature-attributes.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/geometry-attributes.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/node-debug.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/node-index-document.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/node-pages.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/preprocess-3d-tiles.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/progress.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/helpers/tileset-traversal.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/geometry-definitions.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/layers.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/metadata.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/node.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/scene-server.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/shared-resources.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/json-templates/store.ts +0 -0
- /package/src/{i3s-converter → v4/i3s-converter}/types.ts +0 -0
- /package/src/{i3s-server → v4/i3s-server}/app.ts +0 -0
- /package/src/{i3s-server → v4/i3s-server}/bin/www.ts +0 -0
- /package/src/{i3s-server → v4/i3s-server}/certs/cert.pem +0 -0
- /package/src/{i3s-server → v4/i3s-server}/certs/key.pem +0 -0
- /package/src/{i3s-server → v4/i3s-server}/controllers/slpk-controller.ts +0 -0
- /package/src/{i3s-server → v4/i3s-server}/utils/create-scene-server.ts +0 -0
- /package/src/{i3s-server → v4/i3s-server}/utils/server-utils.ts +0 -0
- /package/src/{lib → v4/lib}/json-schemas/conversion-dump-json-schema.ts +0 -0
- /package/src/{lib → v4/lib}/utils/cli-utils.ts +0 -0
- /package/src/{lib → v4/lib}/utils/conversion-dump.ts +0 -0
- /package/src/{lib → v4/lib}/utils/file-utils.ts +0 -0
- /package/src/{lib → v4/lib}/utils/geometry-utils.ts +0 -0
- /package/src/{lib → v4/lib}/utils/lod-conversion-utils.ts +0 -0
- /package/src/{lib → v4/lib}/utils/queue.ts +0 -0
- /package/src/{lib → v4/lib}/utils/statistic-utils.ts +0 -0
- /package/src/{lib → v4/lib}/utils/write-queue.ts +0 -0
- /package/src/{pgm-loader.ts → v4/pgm-loader.ts} +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {I3STileContent, I3STileHeader} from '@loaders.gl/i3s';
|
|
6
|
+
import type {GLTFMaterialPostprocessed} from '@loaders.gl/gltf';
|
|
7
|
+
import {getBinaryImageMetadata} from '@loaders.gl/images';
|
|
8
|
+
import {TileConversionError} from '@loaders.gl/tile-converter/v5/core';
|
|
9
|
+
import type {MeshTilesetSourceOptions} from './mesh-source.js';
|
|
10
|
+
import {mapMeshSourceMaterial} from './mesh-source.js';
|
|
11
|
+
import type {MeshTileMaterial} from './mesh.js';
|
|
12
|
+
|
|
13
|
+
/** Maps normalized I3S factors and one encoded base-color PNG/JPEG with explicit wrapping. */
|
|
14
|
+
export async function mapI3SMeshSourceMaterial(
|
|
15
|
+
content: I3STileContent,
|
|
16
|
+
header: Partial<I3STileHeader>,
|
|
17
|
+
readExternalResource: MeshTilesetSourceOptions['readExternalResource'],
|
|
18
|
+
contentUri: string | undefined,
|
|
19
|
+
signal?: AbortSignal
|
|
20
|
+
): Promise<MeshTileMaterial | undefined> {
|
|
21
|
+
const material = Object.fromEntries(
|
|
22
|
+
Object.entries(content.material || {}).filter(([, value]) => value !== undefined)
|
|
23
|
+
);
|
|
24
|
+
const metallicRoughness = material.pbrMetallicRoughness
|
|
25
|
+
? Object.fromEntries(
|
|
26
|
+
Object.entries(material.pbrMetallicRoughness).filter(([, value]) => value !== undefined)
|
|
27
|
+
)
|
|
28
|
+
: {};
|
|
29
|
+
material.pbrMetallicRoughness = metallicRoughness;
|
|
30
|
+
if (material.cullFace !== undefined && material.cullFace !== 'back') {
|
|
31
|
+
throw new TileConversionError(
|
|
32
|
+
'I3S_MESH_SOURCE_MATERIAL_UNSUPPORTED',
|
|
33
|
+
'Only back-face culling is supported'
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
delete material.cullFace;
|
|
37
|
+
let textureInfo = metallicRoughness.baseColorTexture
|
|
38
|
+
? {...(metallicRoughness.baseColorTexture as Record<string, unknown>)}
|
|
39
|
+
: undefined;
|
|
40
|
+
const resources = header.textureUrls?.length
|
|
41
|
+
? header.textureUrls
|
|
42
|
+
: header.textureUrl
|
|
43
|
+
? [
|
|
44
|
+
{
|
|
45
|
+
textureSetDefinitionId: textureInfo?.textureSetDefinitionId ?? 0,
|
|
46
|
+
textureUrl: header.textureUrl,
|
|
47
|
+
textureFormat: header.textureFormat || 'jpg'
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
: [];
|
|
51
|
+
// Legacy singleton textures without a material definition are implicit base-color maps.
|
|
52
|
+
if (!textureInfo && !header.materialDefinition && resources.length === 1) {
|
|
53
|
+
textureInfo = {textureSetDefinitionId: resources[0].textureSetDefinitionId};
|
|
54
|
+
}
|
|
55
|
+
const encodedTextures = content.textures || {};
|
|
56
|
+
if (
|
|
57
|
+
!textureInfo &&
|
|
58
|
+
(resources.length || content.texture || Object.keys(encodedTextures).length)
|
|
59
|
+
) {
|
|
60
|
+
throw new TileConversionError(
|
|
61
|
+
'I3S_MESH_SOURCE_TEXTURE_UNSUPPORTED',
|
|
62
|
+
'Texture resources require a base-color mapping'
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (textureInfo) {
|
|
66
|
+
const definitionId = textureInfo.textureSetDefinitionId;
|
|
67
|
+
const wrappingModes: Record<string, number> = {none: 33071, repeat: 10497, mirror: 33648};
|
|
68
|
+
if (
|
|
69
|
+
typeof definitionId !== 'number' ||
|
|
70
|
+
!Number.isSafeInteger(definitionId) ||
|
|
71
|
+
definitionId < 0 ||
|
|
72
|
+
(textureInfo.texCoord !== undefined && textureInfo.texCoord !== 0) ||
|
|
73
|
+
Object.keys(textureInfo).some(
|
|
74
|
+
name => !['textureSetDefinitionId', 'texCoord', 'wrapS', 'wrapT', 'texture'].includes(name)
|
|
75
|
+
) ||
|
|
76
|
+
(['wrapS', 'wrapT'] as const).some(
|
|
77
|
+
name =>
|
|
78
|
+
textureInfo![name] !== undefined &&
|
|
79
|
+
(typeof textureInfo![name] !== 'string' ||
|
|
80
|
+
!Object.hasOwn(wrappingModes, textureInfo![name] as string))
|
|
81
|
+
) ||
|
|
82
|
+
resources.length > 1 ||
|
|
83
|
+
resources.some(resource => resource.textureSetDefinitionId !== definitionId) ||
|
|
84
|
+
Object.keys(encodedTextures).some(key => key !== String(definitionId))
|
|
85
|
+
) {
|
|
86
|
+
throw new TileConversionError(
|
|
87
|
+
'I3S_MESH_SOURCE_TEXTURE_UNSUPPORTED',
|
|
88
|
+
'Only one base-color texture set on TEXCOORD_0 with qualified wrapping is supported'
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
let encoded =
|
|
92
|
+
encodedTextures[String(definitionId)] ||
|
|
93
|
+
content.texture ||
|
|
94
|
+
(textureInfo.texture as {source?: {image?: unknown}} | undefined)?.source?.image;
|
|
95
|
+
if (!encoded) {
|
|
96
|
+
if (!resources.length || !readExternalResource) {
|
|
97
|
+
throw new TileConversionError(
|
|
98
|
+
'I3S_MESH_SOURCE_TEXTURE_UNSUPPORTED',
|
|
99
|
+
'Encoded texture bytes or an explicit bounded resource reader are required'
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
signal?.throwIfAborted();
|
|
103
|
+
encoded = await readExternalResource(resources[0].textureUrl, contentUri, signal);
|
|
104
|
+
signal?.throwIfAborted();
|
|
105
|
+
}
|
|
106
|
+
const data = encoded instanceof ArrayBuffer ? new Uint8Array(encoded) : encoded;
|
|
107
|
+
let image;
|
|
108
|
+
if (data instanceof Uint8Array) {
|
|
109
|
+
try {
|
|
110
|
+
image = getBinaryImageMetadata(new DataView(data.buffer, data.byteOffset, data.byteLength));
|
|
111
|
+
} catch {
|
|
112
|
+
/* Reject malformed or compressed image resources below. */
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const declaredFormat = resources[0]?.textureFormat;
|
|
116
|
+
if (
|
|
117
|
+
!image ||
|
|
118
|
+
!['image/png', 'image/jpeg'].includes(image.mimeType) ||
|
|
119
|
+
(declaredFormat &&
|
|
120
|
+
(declaredFormat === 'png'
|
|
121
|
+
? image.mimeType !== 'image/png'
|
|
122
|
+
: declaredFormat === 'jpg'
|
|
123
|
+
? image.mimeType !== 'image/jpeg'
|
|
124
|
+
: true))
|
|
125
|
+
) {
|
|
126
|
+
throw new TileConversionError(
|
|
127
|
+
'I3S_MESH_SOURCE_TEXTURE_UNSUPPORTED',
|
|
128
|
+
'I3S base-color bytes must have matching PNG/JPEG headers'
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
const sampler = Object.fromEntries(
|
|
132
|
+
['wrapS', 'wrapT']
|
|
133
|
+
.filter(name => textureInfo![name] !== undefined)
|
|
134
|
+
.map(name => [name, wrappingModes[textureInfo![name] as string]])
|
|
135
|
+
);
|
|
136
|
+
metallicRoughness.baseColorTexture = {
|
|
137
|
+
texCoord: 0,
|
|
138
|
+
texture: {
|
|
139
|
+
source: {mimeType: image.mimeType, bufferView: {data}},
|
|
140
|
+
...(Object.keys(sampler).length ? {sampler} : {})
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const mapped = await mapMeshSourceMaterial(
|
|
145
|
+
material as GLTFMaterialPostprocessed,
|
|
146
|
+
undefined,
|
|
147
|
+
contentUri,
|
|
148
|
+
signal
|
|
149
|
+
);
|
|
150
|
+
if (mapped?.baseColorTexture && !content.sourceAttributes?.uv0) {
|
|
151
|
+
throw new TileConversionError(
|
|
152
|
+
'MESH_TEXCOORD_REQUIRED',
|
|
153
|
+
'Base-color textures require TEXCOORD_0'
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
return mapped;
|
|
157
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import type {I3STileContent, I3SMeshFeatures} from '@loaders.gl/i3s';
|
|
6
|
+
import type {
|
|
7
|
+
Tileset3D,
|
|
8
|
+
TilesetSourceMetadata,
|
|
9
|
+
TilesetContentTraversalItem
|
|
10
|
+
} from '@loaders.gl/tiles';
|
|
11
|
+
import {
|
|
12
|
+
TileConversionError,
|
|
13
|
+
createTilesetConversionSource
|
|
14
|
+
} from '@loaders.gl/tile-converter/v5/core';
|
|
15
|
+
import type {
|
|
16
|
+
TileConversionSource,
|
|
17
|
+
TilesetConversionSourceOptions
|
|
18
|
+
} from '@loaders.gl/tile-converter/v5/core';
|
|
19
|
+
import type {MeshSourceResource} from './mesh-source.js';
|
|
20
|
+
import type {MeshTilesetSourceOptions} from './mesh-source.js';
|
|
21
|
+
import {mapI3SMeshSourceMaterial} from './i3s-mesh-source-material.js';
|
|
22
|
+
import {extractI3SMeshFeatures} from './i3s-mesh-source-features.js';
|
|
23
|
+
import type {I3SMeshSourceFeatureOptions} from './i3s-mesh-source-features.js';
|
|
24
|
+
import {validateMeshGeometry} from './mesh.js';
|
|
25
|
+
export type {I3SMeshSourceFeatureOptions} from './i3s-mesh-source-features.js';
|
|
26
|
+
|
|
27
|
+
/** Selected I3S triangle, encoded base-color appearance and explicit-schema feature profile. */
|
|
28
|
+
export interface I3SMeshTilesetSourceOptions extends TilesetConversionSourceOptions {
|
|
29
|
+
/** Read scalar/string attribute resources with an explicit schema and geometry OID mapping. */
|
|
30
|
+
readonly features?: I3SMeshSourceFeatureOptions;
|
|
31
|
+
/** Application-owned bounded reader, including archive resolution, authentication and decompression. */
|
|
32
|
+
readonly readExternalResource?: MeshTilesetSourceOptions['readExternalResource'];
|
|
33
|
+
/** Custom alternative to features, for source semantics outside the scalar resource profile. */
|
|
34
|
+
readonly getFeatures?: (
|
|
35
|
+
content: I3STileContent,
|
|
36
|
+
item: TilesetContentTraversalItem,
|
|
37
|
+
metadata: TilesetSourceMetadata,
|
|
38
|
+
signal?: AbortSignal
|
|
39
|
+
) => I3SMeshFeatures | Promise<I3SMeshFeatures>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Reads original absolute I3S positions through camera-independent traversal.
|
|
44
|
+
* Use a dedicated runtime with i3s.geometryMode='source'. The shared I3S spatial codec owns
|
|
45
|
+
* units, elevation and reprojection; this source never consumes renderer placement matrices.
|
|
46
|
+
* Pair the GLB codec with autoOrigin=true, or select an explicit target origin on the resources.
|
|
47
|
+
* Positions/normals/TEXCOORD_0, basic PBR factors and one encoded PNG/JPEG base-color texture
|
|
48
|
+
* are supported. Vertex colors, UV regions, additional attributes and segmentation fail explicitly.
|
|
49
|
+
* Features require an explicit schema/resource reader or a custom Arrow mapper.
|
|
50
|
+
* Unsafe decoded numeric geometry identifiers are rejected; exact property IDs use bigint.
|
|
51
|
+
* @param tileset - Dedicated I3S runtime using source-coordinate content decoding.
|
|
52
|
+
* @param options - Feature mapping and lifetime policy for content loaded during traversal.
|
|
53
|
+
* @returns A portable source of one absolute mesh per I3S node content.
|
|
54
|
+
*/
|
|
55
|
+
export function createI3SMeshTilesetConversionSource(
|
|
56
|
+
tileset: Tileset3D,
|
|
57
|
+
options: I3SMeshTilesetSourceOptions = {}
|
|
58
|
+
): TileConversionSource<TilesetSourceMetadata, MeshSourceResource> {
|
|
59
|
+
const source = createTilesetConversionSource(tileset, options);
|
|
60
|
+
return {
|
|
61
|
+
/** Validates the layer profile and explicit source decode policy before reading. */
|
|
62
|
+
async inspect(signal) {
|
|
63
|
+
if (options.features && options.getFeatures) {
|
|
64
|
+
throw new TileConversionError(
|
|
65
|
+
'I3S_MESH_SOURCE_FEATURE_MAPPING_REQUIRED',
|
|
66
|
+
'Choose explicit resource features or a custom getFeatures mapper, not both'
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
const metadata = await source.inspect(signal);
|
|
70
|
+
if (
|
|
71
|
+
metadata.type !== 'I3S' ||
|
|
72
|
+
!['3DObject', 'IntegratedMesh'].includes(metadata.tileset.layerType) ||
|
|
73
|
+
tileset.options.i3s?.geometryMode !== 'source'
|
|
74
|
+
) {
|
|
75
|
+
throw new TileConversionError(
|
|
76
|
+
'I3S_MESH_SOURCE_PROFILE_UNSUPPORTED',
|
|
77
|
+
'I3S mesh extraction requires a 3DObject/IntegratedMesh runtime with geometryMode=source'
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
if (!metadata.spatialReference?.sourceCrs) {
|
|
81
|
+
throw new TileConversionError(
|
|
82
|
+
'I3S_MESH_SOURCE_REFERENCE_REQUIRED',
|
|
83
|
+
'I3S conversion requires an explicit source CRS'
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
return metadata;
|
|
87
|
+
},
|
|
88
|
+
/** Converts each supported content entry before shared traversal releases its buffers. */
|
|
89
|
+
async *read(metadata, signal) {
|
|
90
|
+
for await (const item of source.read(metadata, signal)) {
|
|
91
|
+
for (const entry of item.contents) {
|
|
92
|
+
signal?.throwIfAborted();
|
|
93
|
+
const content = entry.payload as I3STileContent;
|
|
94
|
+
const attributes = content?.sourceAttributes;
|
|
95
|
+
if (
|
|
96
|
+
content?.geometryMode !== 'source' ||
|
|
97
|
+
content.topology !== 'triangle-list' ||
|
|
98
|
+
!attributes ||
|
|
99
|
+
!(attributes.position?.value instanceof Float64Array) ||
|
|
100
|
+
content.spatialReference?.status !== 'native' ||
|
|
101
|
+
(
|
|
102
|
+
[
|
|
103
|
+
'sourceCrs',
|
|
104
|
+
'verticalCrs',
|
|
105
|
+
'axisOrder',
|
|
106
|
+
'units',
|
|
107
|
+
'verticalUnitScale',
|
|
108
|
+
'heightReference',
|
|
109
|
+
'elevationMode',
|
|
110
|
+
'elevationOffset',
|
|
111
|
+
'elevationUnitScale',
|
|
112
|
+
'coordinateEpoch'
|
|
113
|
+
] as const
|
|
114
|
+
).some(
|
|
115
|
+
field =>
|
|
116
|
+
JSON.stringify(content.spatialReference?.[field]) !==
|
|
117
|
+
JSON.stringify(metadata.spatialReference?.[field])
|
|
118
|
+
)
|
|
119
|
+
) {
|
|
120
|
+
throw new TileConversionError(
|
|
121
|
+
'I3S_MESH_SOURCE_GEOMETRY_UNSUPPORTED',
|
|
122
|
+
'I3S extraction requires original source-frame Float64 triangle geometry'
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
if (
|
|
126
|
+
!['earth-centered', 'vertex-reference-frame'].includes(
|
|
127
|
+
content.normalReferenceFrame || ''
|
|
128
|
+
) ||
|
|
129
|
+
content.normalReferenceFrame !==
|
|
130
|
+
(metadata.tileset.store?.normalReferenceFrame || 'earth-centered')
|
|
131
|
+
) {
|
|
132
|
+
throw new TileConversionError(
|
|
133
|
+
'I3S_MESH_SOURCE_NORMAL_FRAME_UNSUPPORTED',
|
|
134
|
+
'Unknown I3S vector basis'
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
if (
|
|
138
|
+
content.meshSegmentation ||
|
|
139
|
+
Object.entries(attributes).some(
|
|
140
|
+
([name, value]) =>
|
|
141
|
+
value && !['position', 'normal', 'uv0', 'id', 'faceRange'].includes(name)
|
|
142
|
+
)
|
|
143
|
+
) {
|
|
144
|
+
throw new TileConversionError(
|
|
145
|
+
'I3S_MESH_SOURCE_ATTRIBUTE_UNSUPPORTED',
|
|
146
|
+
'Only positions, normals, TEXCOORD_0 and explicitly mapped feature associations are supported'
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
const hasFeatures =
|
|
150
|
+
content.featureIds.length > 0 ||
|
|
151
|
+
metadata.tileset.fields?.length ||
|
|
152
|
+
metadata.tileset.attributeStorageInfo?.length;
|
|
153
|
+
if (Array.from(content.featureIds).some(value => !Number.isSafeInteger(value))) {
|
|
154
|
+
throw new TileConversionError(
|
|
155
|
+
'I3S_MESH_SOURCE_FEATURE_ID_UNSUPPORTED',
|
|
156
|
+
'Decoded numeric feature IDs must be exact safe integers'
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
if (hasFeatures && !options.getFeatures && !options.features) {
|
|
160
|
+
throw new TileConversionError(
|
|
161
|
+
'I3S_MESH_SOURCE_FEATURE_MAPPING_REQUIRED',
|
|
162
|
+
'I3S feature data requires explicit resource features or a custom Arrow mapper'
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
const mesh = validateMeshGeometry(
|
|
166
|
+
{
|
|
167
|
+
mode: 4,
|
|
168
|
+
topology: 'triangle-list',
|
|
169
|
+
attributes: {
|
|
170
|
+
POSITION: attributes.position,
|
|
171
|
+
...(attributes.normal ? {NORMAL: attributes.normal} : {}),
|
|
172
|
+
...(attributes.uv0 ? {TEXCOORD_0: attributes.uv0} : {})
|
|
173
|
+
},
|
|
174
|
+
...(content.indices ? {indices: {value: content.indices, size: 1}} : {})
|
|
175
|
+
},
|
|
176
|
+
true
|
|
177
|
+
);
|
|
178
|
+
if (mesh.attributes.POSITION.value.length / 3 !== content.vertexCount) {
|
|
179
|
+
throw new TileConversionError(
|
|
180
|
+
'I3S_MESH_SOURCE_COUNT_INVALID',
|
|
181
|
+
'I3S vertexCount must match the decoded geometry'
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
const features = options.getFeatures
|
|
185
|
+
? await options.getFeatures(content, item, metadata, signal)
|
|
186
|
+
: options.features
|
|
187
|
+
? await extractI3SMeshFeatures(
|
|
188
|
+
content,
|
|
189
|
+
item,
|
|
190
|
+
metadata,
|
|
191
|
+
options.features,
|
|
192
|
+
options.readExternalResource,
|
|
193
|
+
entry.uri,
|
|
194
|
+
signal
|
|
195
|
+
)
|
|
196
|
+
: undefined;
|
|
197
|
+
signal?.throwIfAborted();
|
|
198
|
+
if (hasFeatures && !features) {
|
|
199
|
+
throw new TileConversionError(
|
|
200
|
+
'I3S_MESH_SOURCE_FEATURE_MAPPING_REQUIRED',
|
|
201
|
+
'The feature mapper must return all declared feature data'
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
const mappedMaterial = await mapI3SMeshSourceMaterial(
|
|
205
|
+
content,
|
|
206
|
+
item.tile.header,
|
|
207
|
+
options.readExternalResource,
|
|
208
|
+
entry.uri,
|
|
209
|
+
signal
|
|
210
|
+
);
|
|
211
|
+
signal?.throwIfAborted();
|
|
212
|
+
yield {
|
|
213
|
+
id: `${item.tile.id}/${entry.index}`,
|
|
214
|
+
origin: [0, 0, 0],
|
|
215
|
+
mesh,
|
|
216
|
+
normalReferenceFrame:
|
|
217
|
+
content.normalReferenceFrame === 'vertex-reference-frame'
|
|
218
|
+
? 'vertex-reference-frame'
|
|
219
|
+
: 'earth-centered',
|
|
220
|
+
features,
|
|
221
|
+
material: mappedMaterial
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
}
|
package/src/v5/index.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
export {
|
|
2
|
+
convertTileset,
|
|
3
|
+
inspectTileset,
|
|
4
|
+
TileConversionError,
|
|
5
|
+
validateTileset
|
|
6
|
+
} from '@loaders.gl/tile-converter/v5/core';
|
|
7
|
+
export type {
|
|
8
|
+
ConvertTilesetOptions,
|
|
9
|
+
TileConversionCodec,
|
|
10
|
+
TileConversionDiagnostic,
|
|
11
|
+
TileConversionProgress,
|
|
12
|
+
TileConversionReport,
|
|
13
|
+
TileConversionSink,
|
|
14
|
+
TileConversionSource,
|
|
15
|
+
TileValidationReport,
|
|
16
|
+
ValidateTilesetOptions
|
|
17
|
+
} from '@loaders.gl/tile-converter/v5/core';
|
|
18
|
+
export {createTilesetConversionSource} from '@loaders.gl/tile-converter/v5/core';
|
|
19
|
+
export type {TilesetConversionSourceOptions} from '@loaders.gl/tile-converter/v5/core';
|
|
20
|
+
export {
|
|
21
|
+
createI3SConversionSpatialContext,
|
|
22
|
+
createTiles3DConversionSpatialContext
|
|
23
|
+
} from '@loaders.gl/tile-converter/v5/core';
|
|
24
|
+
export type {
|
|
25
|
+
I3SConversionSpatialContext,
|
|
26
|
+
Tiles3DConversionSpatialContext
|
|
27
|
+
} from '@loaders.gl/tile-converter/v5/core';
|
|
28
|
+
export {convertFeatureAttributesToArrowBatches} from '@loaders.gl/tile-converter/v5/adapters';
|
|
29
|
+
export type {
|
|
30
|
+
FeatureArrowBatchOptions,
|
|
31
|
+
TileFeatureAttributes
|
|
32
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
33
|
+
export {
|
|
34
|
+
encodePointCloudTile,
|
|
35
|
+
encodePointCloudTileWithMetadata
|
|
36
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
37
|
+
export type {
|
|
38
|
+
EncodePointCloudTileOptions,
|
|
39
|
+
EncodedPointCloudTile
|
|
40
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
41
|
+
export {traversePointCloudSource} from '@loaders.gl/tile-converter/v5/core';
|
|
42
|
+
export type {
|
|
43
|
+
PointCloudSourceTile,
|
|
44
|
+
TraversePointCloudSourceOptions
|
|
45
|
+
} from '@loaders.gl/tile-converter/v5/core';
|
|
46
|
+
export {
|
|
47
|
+
encodePointCloudSource,
|
|
48
|
+
encodePointCloudSourceTile
|
|
49
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
50
|
+
export type {
|
|
51
|
+
EncodedPointCloudSourceTile,
|
|
52
|
+
EncodePointCloudSourceOptions
|
|
53
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
54
|
+
export {convertPointCloudSource} from '@loaders.gl/tile-converter/v5/adapters';
|
|
55
|
+
export type {ConvertPointCloudSourceOptions} from '@loaders.gl/tile-converter/v5/adapters';
|
|
56
|
+
export {createManifestBackedTileConversionSink} from '@loaders.gl/tile-converter/v5/core';
|
|
57
|
+
export type {
|
|
58
|
+
ManifestBackedTileConversionSinkOptions,
|
|
59
|
+
TileResourceManifest,
|
|
60
|
+
TileResourceManifestEntry,
|
|
61
|
+
TileResourceManifestStore
|
|
62
|
+
} from '@loaders.gl/tile-converter/v5/core';
|
|
63
|
+
export {encodeMeshTile} from '@loaders.gl/tile-converter/v5/adapters';
|
|
64
|
+
export type {
|
|
65
|
+
MeshTileMaterial,
|
|
66
|
+
MeshTileOptions,
|
|
67
|
+
MeshTileTexture,
|
|
68
|
+
MeshTileSampler,
|
|
69
|
+
MeshTileTextureTransform
|
|
70
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
71
|
+
export {createMeshConversionCodec} from '@loaders.gl/tile-converter/v5/adapters';
|
|
72
|
+
export type {
|
|
73
|
+
MeshConversionInput,
|
|
74
|
+
EncodedMeshConversionResource,
|
|
75
|
+
MeshConversionCodecOptions
|
|
76
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
77
|
+
export {createSingleMeshTilesetSink} from '@loaders.gl/tile-converter/v5/adapters';
|
|
78
|
+
export type {
|
|
79
|
+
SingleMeshTilesetSink,
|
|
80
|
+
SingleMeshTilesetSinkOptions
|
|
81
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
82
|
+
|
|
83
|
+
export {
|
|
84
|
+
createTileConversionArchive,
|
|
85
|
+
encodeTileConversionArchiveInBatches
|
|
86
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
87
|
+
export type {TileConversionArchiveOptions} from '@loaders.gl/tile-converter/v5/adapters';
|
|
88
|
+
export {createSingleMeshTilesetArchive} from '@loaders.gl/tile-converter/v5/adapters';
|
|
89
|
+
export type {SingleMeshTilesetArchiveOptions} from '@loaders.gl/tile-converter/v5/adapters';
|
|
90
|
+
|
|
91
|
+
export {createMeshTilesetConversionSource} from '@loaders.gl/tile-converter/v5/adapters';
|
|
92
|
+
export type {
|
|
93
|
+
MeshSourceResource,
|
|
94
|
+
MeshTilesetSourceOptions,
|
|
95
|
+
MeshSourceFeatureOptions
|
|
96
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
97
|
+
export {
|
|
98
|
+
createI3SMeshConversionCodec,
|
|
99
|
+
createSingleMeshI3SSink
|
|
100
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
101
|
+
export type {
|
|
102
|
+
I3SMeshConversionResource,
|
|
103
|
+
I3SMeshConversionCodecOptions,
|
|
104
|
+
SingleMeshI3SSink
|
|
105
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
106
|
+
|
|
107
|
+
export {
|
|
108
|
+
createI3SMeshSink,
|
|
109
|
+
createTileConversionResourceFetcher
|
|
110
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
111
|
+
export type {
|
|
112
|
+
I3SMeshSink,
|
|
113
|
+
I3SMeshSinkOptions,
|
|
114
|
+
TileConversionResourceFetcherOptions,
|
|
115
|
+
MeshTileFeatures
|
|
116
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
117
|
+
|
|
118
|
+
export {createPointCloudTilesetSink} from '@loaders.gl/tile-converter/v5/adapters';
|
|
119
|
+
export type {
|
|
120
|
+
PointCloudTilesetSink,
|
|
121
|
+
PointCloudTilesetSinkOptions
|
|
122
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|
|
123
|
+
|
|
124
|
+
export {transformPointCloudSourceTile} from '@loaders.gl/tile-converter/v5/adapters';
|
|
125
|
+
export type {PointCloudSpatialOptions} from '@loaders.gl/tile-converter/v5/adapters';
|
|
126
|
+
|
|
127
|
+
export {createI3SMeshTilesetConversionSource} from '@loaders.gl/tile-converter/v5/adapters';
|
|
128
|
+
export type {
|
|
129
|
+
I3SMeshTilesetSourceOptions,
|
|
130
|
+
I3SMeshSourceFeatureOptions
|
|
131
|
+
} from '@loaders.gl/tile-converter/v5/adapters';
|