@loaders.gl/tile-converter 5.0.0-alpha.6 → 5.0.0-alpha.8
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/README.md +155 -0
- package/dist/converter.min.cjs +194 -194
- package/dist/i3s-server/bin/i3s-server.min.cjs +84 -84
- package/dist/index.cjs +35865 -0
- package/dist/index.js +35837 -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 +1962 -0
- package/dist/v5/browser.d.ts +18 -0
- package/dist/v5/browser.js +1927 -0
- package/dist/v5/conversion-api.d.ts +122 -0
- package/dist/v5/feature-arrow.d.ts +36 -0
- package/dist/v5/index.cjs +3975 -0
- package/dist/v5/index.d.ts +18 -0
- package/dist/v5/index.js +3928 -0
- package/dist/v5/point-cloud-conversion.d.ts +31 -0
- package/dist/v5/point-cloud-source-encoder.d.ts +49 -0
- package/dist/v5/point-cloud-source.d.ts +25 -0
- package/dist/v5/point-cloud.d.ts +24 -0
- package/dist/v5/resource-manifest.d.ts +58 -0
- package/dist/v5/spatial-conversion.d.ts +59 -0
- package/dist/v5/tileset-source.d.ts +21 -0
- package/package.json +41 -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/v4/i3s-converter/helpers/encode-string-attribute.ts +23 -0
- package/src/{i3s-converter → v4/i3s-converter}/helpers/geometry-converter.ts +15 -42
- 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/v5/browser-sink.ts +129 -0
- package/src/v5/browser-source.ts +155 -0
- package/src/v5/browser-tileset-source.ts +328 -0
- package/src/v5/browser.ts +54 -0
- package/src/v5/conversion-api.ts +287 -0
- package/src/v5/feature-arrow.ts +427 -0
- package/src/v5/index.ts +47 -0
- package/src/v5/point-cloud-conversion.ts +80 -0
- package/src/v5/point-cloud-source-encoder.ts +102 -0
- package/src/v5/point-cloud-source.ts +84 -0
- package/src/v5/point-cloud.ts +271 -0
- package/src/v5/resource-manifest.ts +213 -0
- package/src/v5/spatial-conversion.ts +305 -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/batch-ids-extensions.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/compress-util.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,31 @@
|
|
|
1
|
+
import type { PointCloudTilesetSource } from '@loaders.gl/tiles';
|
|
2
|
+
import type { TileConversionProgress, TileConversionReport, TileConversionSink } from './conversion-api.js';
|
|
3
|
+
import type { PointCloudSourceTile } from './point-cloud-source.js';
|
|
4
|
+
import type { EncodedPointCloudSourceTile, EncodePointCloudSourceOptions } from './point-cloud-source-encoder.js';
|
|
5
|
+
/** Point-cloud encoding options and an application-owned output destination. */
|
|
6
|
+
export interface ConvertPointCloudSourceOptions extends EncodePointCloudSourceOptions {
|
|
7
|
+
/** Destination receiving PNTS resources and their source placement metadata. */
|
|
8
|
+
readonly sink: TileConversionSink<EncodedPointCloudSourceTile>;
|
|
9
|
+
/** Input byte accounting for each visited source tile, including tiles with null content. */
|
|
10
|
+
readonly measureInputBytes: (sourceTile: PointCloudSourceTile) => number;
|
|
11
|
+
/** Maximum caller-measured bytes in one decoded source tile, checked before PNTS encoding. */
|
|
12
|
+
readonly maxInputResourceBytes?: number;
|
|
13
|
+
/** Maximum bytes in one encoded PNTS resource. Defaults to no limit. */
|
|
14
|
+
readonly maxOutputResourceBytes?: number;
|
|
15
|
+
/** Receive conversion progress, including resource counts and caller-measured input bytes. */
|
|
16
|
+
readonly onProgress?: (progress: TileConversionProgress) => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Converts a point-cloud source to PNTS resources through the v5 output-sink lifecycle.
|
|
20
|
+
*
|
|
21
|
+
* Each write is awaited before reading the next source tile. The destination is finalized only
|
|
22
|
+
* after traversal and writes succeed, and aborted on read, encoding, write, or cancellation errors.
|
|
23
|
+
* Input resource counts include empty tiles; output counts and byte sizes describe emitted PNTS
|
|
24
|
+
* resources. Applications supply input byte accounting because source tiles contain decoded Arrow
|
|
25
|
+
* data rather than transport bytes. The caller retains ownership of the input source.
|
|
26
|
+
*
|
|
27
|
+
* @param source - An I3S, COPC, or compatible point-cloud source to initialize and traverse.
|
|
28
|
+
* @param options - Destination, byte accounting, traversal limits, and per-tile encoding options.
|
|
29
|
+
* @returns The shared v5 conversion report after destination finalization.
|
|
30
|
+
*/
|
|
31
|
+
export declare function convertPointCloudSource(source: PointCloudTilesetSource, options: ConvertPointCloudSourceOptions): Promise<TileConversionReport>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { PointCloudBoundingVolume, PointCloudCoordinateSystem, PointCloudTilesetSource, TilesetSpatialReference } from '@loaders.gl/tiles';
|
|
2
|
+
import type { EncodePointCloudTileOptions } from './point-cloud.js';
|
|
3
|
+
import type { PointCloudSourceTile, TraversePointCloudSourceOptions } from './point-cloud-source.js';
|
|
4
|
+
/** Traversal and per-tile encoding options for a point-cloud source. */
|
|
5
|
+
export type EncodePointCloudSourceOptions = TraversePointCloudSourceOptions & {
|
|
6
|
+
/** Select encoder options for each source tile with content, using its header and decoded data. */
|
|
7
|
+
readonly getTileEncodingOptions?: (sourceTile: PointCloudSourceTile) => EncodePointCloudTileOptions;
|
|
8
|
+
};
|
|
9
|
+
/** A PNTS resource paired with the source placement metadata needed to package its tile. */
|
|
10
|
+
export type EncodedPointCloudSourceTile = {
|
|
11
|
+
/** Stable source tile identifier. */
|
|
12
|
+
readonly id: string;
|
|
13
|
+
/** Original source hierarchy and bounds. */
|
|
14
|
+
readonly header: PointCloudSourceTile['header'];
|
|
15
|
+
/** Encoded point-cloud tile content. */
|
|
16
|
+
readonly pnts: ArrayBuffer;
|
|
17
|
+
/** Number of point records encoded. */
|
|
18
|
+
readonly pointCount: number;
|
|
19
|
+
/** Coordinate system used by the returned point positions. */
|
|
20
|
+
readonly coordinateSystem: PointCloudCoordinateSystem;
|
|
21
|
+
/** Origin to add to source-relative point positions. */
|
|
22
|
+
readonly cartographicOrigin: readonly number[];
|
|
23
|
+
/** Optional placement transform supplied by the point-cloud source. */
|
|
24
|
+
readonly modelMatrix?: readonly number[];
|
|
25
|
+
/** Optional source or target CRS metadata. */
|
|
26
|
+
readonly spatialReference?: TilesetSpatialReference;
|
|
27
|
+
/** Optional output-frame tile bounds supplied by the source. */
|
|
28
|
+
readonly spatialBoundingVolume?: PointCloudBoundingVolume;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Encodes a point-cloud source as a stream of PNTS resources, one for each non-empty source tile.
|
|
32
|
+
*
|
|
33
|
+
* @param source - An I3S, COPC, or compatible point-cloud tileset source.
|
|
34
|
+
* @param options - Optional traversal depth limit, cancellation signal, and per-tile encoder options.
|
|
35
|
+
* @returns Encoded source tiles in deterministic depth-first order.
|
|
36
|
+
*/
|
|
37
|
+
export declare function encodePointCloudSource(source: PointCloudTilesetSource, options?: EncodePointCloudSourceOptions): AsyncIterableIterator<EncodedPointCloudSourceTile>;
|
|
38
|
+
/**
|
|
39
|
+
* Encodes one decoded source tile as PNTS and retains its hierarchy and placement metadata.
|
|
40
|
+
*
|
|
41
|
+
* Positions use the source coordinate system, with an optional RTC center subtracted before float32
|
|
42
|
+
* encoding and stored in the PNTS feature table. Source placement metadata is retained so callers
|
|
43
|
+
* can assemble the output tileset. This function does not transform the source CRS.
|
|
44
|
+
*
|
|
45
|
+
* @param sourceTile - Tile header and decoded Arrow point content from `traversePointCloudSource`.
|
|
46
|
+
* @param options - Optional RTC center, batch-table values, and constant color override.
|
|
47
|
+
* @returns An encoded source tile, or null when the source tile has no content.
|
|
48
|
+
*/
|
|
49
|
+
export declare function encodePointCloudSourceTile(sourceTile: PointCloudSourceTile, options?: EncodePointCloudTileOptions): EncodedPointCloudSourceTile | null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PointCloudTileContent, PointCloudTileHeader, PointCloudTilesetSource } from '@loaders.gl/tiles';
|
|
2
|
+
/** A source tile and its decoded point content, including null content when no payload exists. */
|
|
3
|
+
export type PointCloudSourceTile = {
|
|
4
|
+
/** Header with the source tile's hierarchy, bounds, and LOD metadata. */
|
|
5
|
+
readonly header: PointCloudTileHeader;
|
|
6
|
+
/** Arrow point data and its coordinate metadata, or null for an empty tile. */
|
|
7
|
+
readonly content: PointCloudTileContent | null;
|
|
8
|
+
};
|
|
9
|
+
/** Options for camera-independent point-cloud source traversal. */
|
|
10
|
+
export type TraversePointCloudSourceOptions = {
|
|
11
|
+
/** Stop descending after this source tile level. Defaults to the complete hierarchy. */
|
|
12
|
+
readonly maxDepth?: number;
|
|
13
|
+
/** Cancel traversal between source operations. */
|
|
14
|
+
readonly signal?: AbortSignal;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Reads a point-cloud source in deterministic depth-first order, independent of a render camera.
|
|
18
|
+
* Each yielded value retains its tile header and Arrow content metadata so callers can apply the
|
|
19
|
+
* source coordinate frame and placement when encoding output tiles.
|
|
20
|
+
*
|
|
21
|
+
* @param source - An I3S, COPC, or compatible point-cloud tileset source.
|
|
22
|
+
* @param options - Optional depth limit and cancellation signal.
|
|
23
|
+
* @returns One header and decoded payload for each reachable source tile.
|
|
24
|
+
*/
|
|
25
|
+
export declare function traversePointCloudSource(source: PointCloudTilesetSource, options?: TraversePointCloudSourceOptions): AsyncIterableIterator<PointCloudSourceTile>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Mesh, MeshArrowTable } from '@loaders.gl/schema';
|
|
2
|
+
/** Options for encoding one Arrow or mesh point batch as a 3D Tiles point tile. */
|
|
3
|
+
export interface EncodePointCloudTileOptions {
|
|
4
|
+
/** Optional origin subtracted from absolute positions and stored as the PNTS RTC_CENTER. */
|
|
5
|
+
readonly rtcCenter?: readonly [number, number, number];
|
|
6
|
+
/** Optional source-wide RGBA color stored as the PNTS CONSTANT_RGBA property. */
|
|
7
|
+
readonly constantRGBA?: readonly number[];
|
|
8
|
+
/** Optional per-point values indexed by the tile's `BATCH_ID` attribute. */
|
|
9
|
+
readonly batchTableJson?: Readonly<Record<string, readonly (string | number)[]>>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Encodes one mesh or Mesh Arrow point batch as a PNTS resource.
|
|
13
|
+
*
|
|
14
|
+
* The input position field must be named `POSITION` and contain xyz values. `COLOR_0` or `COLOR`
|
|
15
|
+
* is written when present; `constantRGBA` supplies a fallback PNTS `CONSTANT_RGBA` feature-table
|
|
16
|
+
* property. `NORMAL` and `BATCH_ID` are also written when present. Arrow batches should be passed
|
|
17
|
+
* one at a time so callers can bound memory and apply their own tiling and output policy.
|
|
18
|
+
* Unsupported attributes, including a second color attribute, fail instead of being discarded.
|
|
19
|
+
*
|
|
20
|
+
* @param pointBatch - Point data produced by a LAS, COPC, I3S, or other point source.
|
|
21
|
+
* @param options - Optional RTC center and batch-table values.
|
|
22
|
+
* @returns A 3D Tiles PNTS resource.
|
|
23
|
+
*/
|
|
24
|
+
export declare function encodePointCloudTile(pointBatch: Mesh | MeshArrowTable, options?: EncodePointCloudTileOptions): ArrayBuffer;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { TileConversionReport, TileConversionSink } from './conversion-api.js';
|
|
2
|
+
/** Durable record for one successfully written, deterministic output resource. */
|
|
3
|
+
export interface TileResourceManifestEntry {
|
|
4
|
+
/** Stable resource identifier supplied by the output profile. */
|
|
5
|
+
readonly resourceId: string;
|
|
6
|
+
/** Byte length of the output resource. */
|
|
7
|
+
readonly byteLength: number;
|
|
8
|
+
/** Stable caller-computed content fingerprint, such as a SHA-256 digest. */
|
|
9
|
+
readonly fingerprint: string;
|
|
10
|
+
}
|
|
11
|
+
/** Versioned progress record used to resume deterministic output packaging. */
|
|
12
|
+
export interface TileResourceManifest {
|
|
13
|
+
/** Manifest format version. */
|
|
14
|
+
readonly version: 1;
|
|
15
|
+
/** True only after the destination and report have been finalized successfully. */
|
|
16
|
+
readonly complete: boolean;
|
|
17
|
+
/** Resources durably written before interruption or completion. */
|
|
18
|
+
readonly resources: readonly TileResourceManifestEntry[];
|
|
19
|
+
/** Conversion summary saved after successful destination finalization. */
|
|
20
|
+
readonly report?: TileConversionReport;
|
|
21
|
+
}
|
|
22
|
+
/** Application-owned persistence for a conversion manifest. */
|
|
23
|
+
export interface TileResourceManifestStore {
|
|
24
|
+
/** Loads the previous manifest, or returns null when starting a new conversion. */
|
|
25
|
+
load(): Promise<TileResourceManifest | null>;
|
|
26
|
+
/** Atomically replaces the saved manifest with the supplied snapshot. */
|
|
27
|
+
save(manifest: TileResourceManifest): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
/** Options for decorating a resource sink with restart-safe manifest tracking. */
|
|
30
|
+
export interface ManifestBackedTileConversionSinkOptions<TResource> {
|
|
31
|
+
/** Output destination with deterministic, idempotent resource writes. */
|
|
32
|
+
readonly sink: TileConversionSink<TResource>;
|
|
33
|
+
/** Persistence adapter for snapshots written after each resource. */
|
|
34
|
+
readonly manifestStore: TileResourceManifestStore;
|
|
35
|
+
/** Stable profile-specific path or resource key. */
|
|
36
|
+
readonly getResourceId: (resource: TResource) => string;
|
|
37
|
+
/** Byte length used to detect changed content under an existing resource ID. */
|
|
38
|
+
readonly measureResourceBytes: (resource: TResource) => number;
|
|
39
|
+
/** Stable fingerprint used to detect changed content under an existing resource ID. */
|
|
40
|
+
readonly fingerprintResource: (resource: TResource) => string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Creates a sink that skips matching checkpointed resources when a process restarts.
|
|
44
|
+
*
|
|
45
|
+
* The destination must write resources idempotently by the ID returned from `getResourceId`.
|
|
46
|
+
* The manifest is persisted after every successful write; the store should replace snapshots
|
|
47
|
+
* atomically. Existing IDs must retain their byte length and fingerprint or the resumed job fails
|
|
48
|
+
* rather than silently mixing output from different conversion inputs. Writes are serialized even
|
|
49
|
+
* when callers issue them concurrently. Reports count resources processed by the current run,
|
|
50
|
+
* including writes skipped because the matching resource was already present. A graceful abort
|
|
51
|
+
* clears the manifest checkpoint before asking the destination to clean partial output, so the
|
|
52
|
+
* next run starts cleanly. A process interruption that does not call `abort` can resume from its
|
|
53
|
+
* last saved checkpoint.
|
|
54
|
+
*
|
|
55
|
+
* @param options - Destination, manifest store, stable IDs, byte measurement, and fingerprinting.
|
|
56
|
+
* @returns A `TileConversionSink` with resumable per-resource progress.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createManifestBackedTileConversionSink<TResource>(options: ManifestBackedTileConversionSinkOptions<TResource>): Promise<TileConversionSink<TResource>>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { CreateTilesetSpatialReferenceOptions, I3SSpatialBounds, I3STransformedPositions, Tiles3DSpatialBoundingVolume, TilesetSpatialOptions, TilesetSpatialReference } from '@loaders.gl/tiles';
|
|
2
|
+
/** Portable coordinate operations and output metadata for a 3D Tiles conversion. */
|
|
3
|
+
export interface Tiles3DConversionSpatialContext {
|
|
4
|
+
/** Source and selected target CRS, height reference, units, and transformation state. */
|
|
5
|
+
readonly spatialReference: TilesetSpatialReference;
|
|
6
|
+
/** Transform packed absolute xyz positions using double precision output. */
|
|
7
|
+
transformPositions(positions: ArrayLike<number>): Float64Array;
|
|
8
|
+
/** Transform packed normals using the corresponding source positions. */
|
|
9
|
+
transformNormals(normals: ArrayLike<number>, positions: ArrayLike<number>): Float32Array;
|
|
10
|
+
/** Rebuild a conservative bound in the selected target coordinate frame. */
|
|
11
|
+
transformBoundingVolume(volume: Tiles3DSpatialBoundingVolume, sourceTransform?: ArrayLike<number>): Tiles3DSpatialBoundingVolume;
|
|
12
|
+
}
|
|
13
|
+
/** Portable coordinate operations and output metadata for an I3S conversion. */
|
|
14
|
+
export interface I3SConversionSpatialContext {
|
|
15
|
+
/** Source and selected target CRS, height reference, units, and transformation state. */
|
|
16
|
+
readonly spatialReference: TilesetSpatialReference;
|
|
17
|
+
/** Transform absolute I3S positions after applying declared height units and placement. */
|
|
18
|
+
transformPositions(positions: ArrayLike<number>, sourceOrigin: ArrayLike<number>): I3STransformedPositions;
|
|
19
|
+
/** Transform absolute I3S positions when terrain or scene sampling is asynchronous. */
|
|
20
|
+
transformPositionsAsync(positions: ArrayLike<number>, sourceOrigin: ArrayLike<number>): Promise<I3STransformedPositions>;
|
|
21
|
+
/** Transform packed normals using the corresponding source positions. */
|
|
22
|
+
transformNormals(normals: ArrayLike<number>, positions: ArrayLike<number>, normalReferenceFrame?: string): Float32Array;
|
|
23
|
+
/** Rebuild a conservative I3S bound in the selected target frame. */
|
|
24
|
+
transformBoundingVolume(bounds: I3SSpatialBounds): I3SSpatialBounds | {
|
|
25
|
+
box?: number[];
|
|
26
|
+
region?: number[];
|
|
27
|
+
};
|
|
28
|
+
/** Rebuild a bound when terrain or scene sampling is asynchronous. */
|
|
29
|
+
transformBoundingVolumeAsync(bounds: I3SSpatialBounds): Promise<I3SSpatialBounds | {
|
|
30
|
+
box?: number[];
|
|
31
|
+
region?: number[];
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Creates the shared spatial operations used to write 3D Tiles in a selected CRS and height frame.
|
|
36
|
+
*
|
|
37
|
+
* Source discovery remains format-specific and should use `get3DTilesSpatialReference` or the
|
|
38
|
+
* initialized source's spatial metadata. Target choices on a normalized, transformable reference
|
|
39
|
+
* are retained unless overridden in `options`. Do not reuse a reference already marked
|
|
40
|
+
* `transformed`; that would apply the operation twice. The returned reference is the metadata to
|
|
41
|
+
* publish with transformed output; unresolved requests fail instead of guessing a CRS or height datum.
|
|
42
|
+
*
|
|
43
|
+
* @param discovered - Source CRS, units, coordinate epoch, and height metadata.
|
|
44
|
+
* @param options - Target CRS, height reference, and explicitly supplied geoid resources.
|
|
45
|
+
* @returns Shared position, normal, and bound operations with matching output metadata.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createTiles3DConversionSpatialContext(discovered: CreateTilesetSpatialReferenceOptions | TilesetSpatialReference, options?: TilesetSpatialOptions): Tiles3DConversionSpatialContext;
|
|
48
|
+
/**
|
|
49
|
+
* Creates the shared spatial operations used to write I3S in a selected CRS and height frame.
|
|
50
|
+
*
|
|
51
|
+
* I3S height units, vertical datum, elevation placement, and bounds use the same transformer as
|
|
52
|
+
* the source-backed tile runtime. Terrain or scene elevation providers are explicit application
|
|
53
|
+
* inputs and may make position and bound operations asynchronous.
|
|
54
|
+
*
|
|
55
|
+
* @param discovered - Source CRS, vertical units, height reference, and elevation mode.
|
|
56
|
+
* @param options - Target CRS, height reference, geoid, or explicit elevation providers.
|
|
57
|
+
* @returns Shared position, normal, bound, and output-metadata operations.
|
|
58
|
+
*/
|
|
59
|
+
export declare function createI3SConversionSpatialContext(discovered: CreateTilesetSpatialReferenceOptions | TilesetSpatialReference, options?: TilesetSpatialOptions): I3SConversionSpatialContext;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Tileset3D, TilesetContentTraversalItem, TilesetSourceMetadata, TraverseTilesetContentsOptions } from '@loaders.gl/tiles';
|
|
2
|
+
import type { TileConversionSource } from './conversion-api.js';
|
|
3
|
+
/** Decoded-content lifetime options for source-backed conversion. */
|
|
4
|
+
export type TilesetConversionSourceOptions = Pick<TraverseTilesetContentsOptions, 'unloadContent'>;
|
|
5
|
+
/**
|
|
6
|
+
* Adapts a source-backed tileset to the portable v5 conversion source contract.
|
|
7
|
+
*
|
|
8
|
+
* Inspection waits for initialization and returns the source's normalized metadata. Reading uses
|
|
9
|
+
* camera-independent shared traversal, retaining each placement and its ordered decoded contents.
|
|
10
|
+
* Source adapters own content, subtree, node-page, nested tileset, and archive resolution.
|
|
11
|
+
*
|
|
12
|
+
* Enable `unloadContent` on a dedicated runtime to release newly loaded payloads after the codec
|
|
13
|
+
* and awaited writes finish, or iteration closes on failure. Preloaded payloads remain attached.
|
|
14
|
+
* Applications own tileset destruction, format codecs, byte accounting, and output packaging.
|
|
15
|
+
* This adapter does not impose an aggregate input memory limit or transform coordinates.
|
|
16
|
+
*
|
|
17
|
+
* @param tileset - An initializing or initialized runtime backed by a 3D Tiles or I3S source.
|
|
18
|
+
* @param options - Optional cleanup of content loaded during conversion.
|
|
19
|
+
* @returns A source accepted by `inspectTileset` and `convertTileset`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createTilesetConversionSource(tileset: Tileset3D, options?: TilesetConversionSourceOptions): TileConversionSource<TilesetSourceMetadata, TilesetContentTraversalItem>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loaders.gl/tile-converter",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.8",
|
|
4
4
|
"description": "Converter",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -24,6 +24,16 @@
|
|
|
24
24
|
"types": "./dist/index.d.ts",
|
|
25
25
|
"import": "./dist/index.js",
|
|
26
26
|
"require": "./dist/index.cjs"
|
|
27
|
+
},
|
|
28
|
+
"./v5": {
|
|
29
|
+
"types": "./dist/v5/index.d.ts",
|
|
30
|
+
"import": "./dist/v5/index.js",
|
|
31
|
+
"require": "./dist/v5/index.cjs"
|
|
32
|
+
},
|
|
33
|
+
"./v5/browser": {
|
|
34
|
+
"types": "./dist/v5/browser.d.ts",
|
|
35
|
+
"import": "./dist/v5/browser.js",
|
|
36
|
+
"require": "./dist/v5/browser.cjs"
|
|
27
37
|
}
|
|
28
38
|
},
|
|
29
39
|
"sideEffects": false,
|
|
@@ -45,30 +55,35 @@
|
|
|
45
55
|
"process": false
|
|
46
56
|
},
|
|
47
57
|
"scripts": {
|
|
48
|
-
"pre-build": "npm run build-converter-bundle && npm run build-i3s-server-bundle && npm run copy-certificates",
|
|
49
|
-
"build-
|
|
50
|
-
"build-
|
|
51
|
-
"
|
|
58
|
+
"pre-build": "npm run build-package-entrypoints && npm run build-converter-bundle && npm run build-i3s-server-bundle && npm run copy-certificates",
|
|
59
|
+
"build-package-entrypoints": "esbuild src/index.ts --bundle --packages=external --platform=node --format=esm --outfile=dist/index.js && esbuild src/index.ts --bundle --packages=external --platform=node --format=cjs --outfile=dist/index.cjs && esbuild src/v5/index.ts --bundle --packages=external --platform=node --format=esm --outfile=dist/v5/index.js && esbuild src/v5/index.ts --bundle --packages=external --platform=node --format=cjs --outfile=dist/v5/index.cjs && esbuild src/v5/browser.ts --bundle --packages=external --platform=browser --format=esm --outfile=dist/v5/browser.js && esbuild src/v5/browser.ts --bundle --packages=external --platform=browser --format=cjs --outfile=dist/v5/browser.cjs && npm run build-v5-declarations",
|
|
60
|
+
"build-v5-declarations": "tsc --ignoreConfig --declaration --emitDeclarationOnly --skipLibCheck --target ES2022 --module NodeNext --moduleResolution NodeNext --rootDir src/v5 --outDir dist/v5 src/v5/index.ts src/v5/browser.ts",
|
|
61
|
+
"build-converter-bundle": "esbuild src/v4/converter-cli.ts --outfile=dist/converter.min.cjs --platform=node --target=esnext,node14 --external:join-images --minify --bundle --define:__VERSION__=\\\"$npm_package_version\\\"",
|
|
62
|
+
"build-i3s-server-bundle": "esbuild src/v4/i3s-server/bin/www.ts --outfile=dist/i3s-server/bin/i3s-server.min.cjs --platform=node --target=esnext,node14 --minify --bundle --define:__VERSION__=\\\"$npm_package_version\\\"",
|
|
63
|
+
"copy-certificates": "cp -R src/v4/i3s-server/certs dist/i3s-server"
|
|
52
64
|
},
|
|
53
65
|
"dependencies": {
|
|
54
|
-
"@loaders.gl/3d-tiles": "5.0.0-alpha.
|
|
55
|
-
"@loaders.gl/compression": "5.0.0-alpha.
|
|
56
|
-
"@loaders.gl/crypto": "5.0.0-alpha.
|
|
57
|
-
"@loaders.gl/draco": "5.0.0-alpha.
|
|
58
|
-
"@loaders.gl/gltf": "5.0.0-alpha.
|
|
59
|
-
"@loaders.gl/i3s": "5.0.0-alpha.
|
|
60
|
-
"@loaders.gl/images": "5.0.0-alpha.
|
|
61
|
-
"@loaders.gl/loader-utils": "5.0.0-alpha.
|
|
62
|
-
"@loaders.gl/polyfills": "5.0.0-alpha.
|
|
63
|
-
"@loaders.gl/
|
|
64
|
-
"@loaders.gl/
|
|
65
|
-
"@loaders.gl/
|
|
66
|
-
"@loaders.gl/
|
|
67
|
-
"@
|
|
68
|
-
"@
|
|
69
|
-
"@math.gl/
|
|
70
|
-
"@math.gl/
|
|
71
|
-
"@math.gl/
|
|
66
|
+
"@loaders.gl/3d-tiles": "5.0.0-alpha.8",
|
|
67
|
+
"@loaders.gl/compression": "5.0.0-alpha.8",
|
|
68
|
+
"@loaders.gl/crypto": "5.0.0-alpha.8",
|
|
69
|
+
"@loaders.gl/draco": "5.0.0-alpha.8",
|
|
70
|
+
"@loaders.gl/gltf": "5.0.0-alpha.8",
|
|
71
|
+
"@loaders.gl/i3s": "5.0.0-alpha.8",
|
|
72
|
+
"@loaders.gl/images": "5.0.0-alpha.8",
|
|
73
|
+
"@loaders.gl/loader-utils": "5.0.0-alpha.8",
|
|
74
|
+
"@loaders.gl/polyfills": "5.0.0-alpha.8",
|
|
75
|
+
"@loaders.gl/schema": "5.0.0-alpha.8",
|
|
76
|
+
"@loaders.gl/schema-utils": "5.0.0-alpha.8",
|
|
77
|
+
"@loaders.gl/textures": "5.0.0-alpha.8",
|
|
78
|
+
"@loaders.gl/tiles": "5.0.0-alpha.8",
|
|
79
|
+
"@loaders.gl/worker-utils": "5.0.0-alpha.8",
|
|
80
|
+
"@loaders.gl/zip": "5.0.0-alpha.8",
|
|
81
|
+
"@math.gl/core": "5.0.0-alpha.11",
|
|
82
|
+
"@math.gl/crs": "5.0.0-alpha.11",
|
|
83
|
+
"@math.gl/culling": "5.0.0-alpha.11",
|
|
84
|
+
"@math.gl/geoid": "5.0.0-alpha.11",
|
|
85
|
+
"@math.gl/geometry-utils": "5.0.0-alpha.11",
|
|
86
|
+
"@math.gl/geospatial": "5.0.0-alpha.11",
|
|
72
87
|
"ajv": "^8.12.0",
|
|
73
88
|
"archiver": "^5.0.0",
|
|
74
89
|
"cors": "^2.8.5",
|
|
@@ -77,7 +92,6 @@
|
|
|
77
92
|
"express": "~4.19.2",
|
|
78
93
|
"inquirer": "^8.0.0",
|
|
79
94
|
"json-map-transform": "^1.2.6",
|
|
80
|
-
"jszip": "^3.5.0",
|
|
81
95
|
"md5": "^2.3.0",
|
|
82
96
|
"morgan": "~1.9.1",
|
|
83
97
|
"uuid": "^9.0.0"
|
|
@@ -88,10 +102,11 @@
|
|
|
88
102
|
},
|
|
89
103
|
"devDependencies": {
|
|
90
104
|
"@types/express": "^4.17.17",
|
|
91
|
-
"@types/inquirer": "^9.0.7"
|
|
105
|
+
"@types/inquirer": "^9.0.7",
|
|
106
|
+
"typescript": "^6.0.3"
|
|
92
107
|
},
|
|
93
108
|
"peerDependencies": {
|
|
94
109
|
"@loaders.gl/core": "~5.0.0-alpha.0"
|
|
95
110
|
},
|
|
96
|
-
"gitHead": "
|
|
111
|
+
"gitHead": "bdc4536ea5b7d074ea362e372704cbdb180126cc"
|
|
97
112
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export {default as Tiles3DConverter} from './3d-tiles-converter/3d-tiles-converter';
|
|
1
|
+
export * from './v4/index.js';
|
|
@@ -14,6 +14,7 @@ import {load, isBrowser} from '@loaders.gl/core';
|
|
|
14
14
|
import {I3SLoader, I3SAttributeLoader, COORDINATE_SYSTEM} from '@loaders.gl/i3s';
|
|
15
15
|
import {Geoid} from '@math.gl/geoid';
|
|
16
16
|
|
|
17
|
+
import {validateI3SConversionSpatialReference} from './helpers/validate-i3s-spatial-reference';
|
|
17
18
|
import {PGMLoader} from '../pgm-loader';
|
|
18
19
|
import {i3sObbTo3dTilesObb} from './helpers/i3s-obb-to-3d-tiles-obb';
|
|
19
20
|
import {convertScreenThresholdToGeometricError} from '../lib/utils/lod-conversion-utils';
|
|
@@ -134,8 +135,6 @@ export default class Tiles3DConverter {
|
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
this.progress.startMonitoring();
|
|
138
|
-
|
|
139
138
|
this.sourceTileset = await loadFromArchive(
|
|
140
139
|
inputUrl,
|
|
141
140
|
I3SLoader,
|
|
@@ -151,6 +150,18 @@ export default class Tiles3DConverter {
|
|
|
151
150
|
return undefined;
|
|
152
151
|
}
|
|
153
152
|
|
|
153
|
+
try {
|
|
154
|
+
validateI3SConversionSpatialReference(this.sourceTileset);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
try {
|
|
157
|
+
await this.slpkFilesystem?.destroy();
|
|
158
|
+
} finally {
|
|
159
|
+
this.slpkFilesystem = null;
|
|
160
|
+
}
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
this.progress.startMonitoring();
|
|
164
|
+
|
|
154
165
|
const rootNode = this.sourceTileset?.root;
|
|
155
166
|
if (!rootNode.obb) {
|
|
156
167
|
rootNode.obb = createObbFromMbs(rootNode.mbs);
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// loaders.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {parseWKTCRS, type WKTCRSNode} from '@math.gl/crs';
|
|
6
|
+
import {getSpatialCoordinateFrame} from '@loaders.gl/tiles';
|
|
7
|
+
|
|
8
|
+
/** Horizontal CRS declarations consumed by the legacy I3S converter. */
|
|
9
|
+
export type I3SConversionSpatialReference = {
|
|
10
|
+
/** Layer-level horizontal coordinate reference system. */
|
|
11
|
+
spatialReference?: {
|
|
12
|
+
/** Original spatial reference identifier. */
|
|
13
|
+
wkid?: number;
|
|
14
|
+
/** Current spatial reference identifier. */
|
|
15
|
+
latestWkid?: number;
|
|
16
|
+
/** Custom spatial reference definition. */
|
|
17
|
+
wkt?: string;
|
|
18
|
+
};
|
|
19
|
+
/** Fallback CRS declaration on the layer extent. */
|
|
20
|
+
fullExtent?: {
|
|
21
|
+
/** Coordinate system shared by the extent and layer. */
|
|
22
|
+
spatialReference?: I3SConversionSpatialReference['spatialReference'];
|
|
23
|
+
};
|
|
24
|
+
/** Coordinate systems declared for node bounds and geometry. */
|
|
25
|
+
store?: {
|
|
26
|
+
/** Coordinate system used by node bounds. */
|
|
27
|
+
indexCRS?: string;
|
|
28
|
+
/** Coordinate system used by geometry positions. */
|
|
29
|
+
vertexCRS?: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Reject explicit horizontal CRS declarations that the legacy converter cannot transform.
|
|
35
|
+
* Undeclared CRS metadata retains the historical WGS-84 assumption.
|
|
36
|
+
* @param layer - Source layer metadata, before interpreting any coordinates as longitude/latitude.
|
|
37
|
+
*/
|
|
38
|
+
export function validateI3SConversionSpatialReference(layer: I3SConversionSpatialReference): void {
|
|
39
|
+
const spatialReferences = [layer.spatialReference, layer.fullExtent?.spatialReference];
|
|
40
|
+
const unsupportedSpatialReference = spatialReferences.find(spatialReference => {
|
|
41
|
+
if (!spatialReference) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
const identifier = spatialReference.latestWkid ?? spatialReference.wkid;
|
|
45
|
+
return (
|
|
46
|
+
(identifier !== undefined && identifier !== 4326 && identifier !== 4979) ||
|
|
47
|
+
(spatialReference.wkt !== undefined && !isWgs84GeographicWkt(spatialReference.wkt))
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
const declarations = [layer.store?.indexCRS, layer.store?.vertexCRS].filter(
|
|
51
|
+
(declaration): declaration is string => Boolean(declaration)
|
|
52
|
+
);
|
|
53
|
+
const unsupportedDeclaration = declarations.find(
|
|
54
|
+
declaration =>
|
|
55
|
+
!/^(?:EPSG:(?:4326|4979)|urn:ogc:def:crs:EPSG::(?:4326|4979)|https?:\/\/www\.opengis\.net\/def\/crs\/EPSG\/0\/(?:4326|4979)\/?)$/i.test(
|
|
56
|
+
declaration
|
|
57
|
+
)
|
|
58
|
+
);
|
|
59
|
+
if (unsupportedSpatialReference || unsupportedDeclaration) {
|
|
60
|
+
const identifier = unsupportedSpatialReference?.latestWkid ?? unsupportedSpatialReference?.wkid;
|
|
61
|
+
const description =
|
|
62
|
+
unsupportedDeclaration || (identifier !== undefined ? `EPSG:${identifier}` : 'custom WKT');
|
|
63
|
+
throw new Error(
|
|
64
|
+
`The legacy I3S-to-3D Tiles converter requires WGS-84 (EPSG:4326) input; received ${description}. Reproject the source I3S dataset to EPSG:4326 before conversion.`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Recognize geographic WGS-84 WKT with degree units and the Greenwich prime meridian. */
|
|
70
|
+
function isWgs84GeographicWkt(wellKnownText: string): boolean {
|
|
71
|
+
try {
|
|
72
|
+
if (getSpatialCoordinateFrame(wellKnownText) !== 'geographic') {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
const {root} = parseWKTCRS(wellKnownText);
|
|
76
|
+
const nodes = collectWktNodes(root);
|
|
77
|
+
const datum = root.values.find(
|
|
78
|
+
value =>
|
|
79
|
+
value.type === 'node' &&
|
|
80
|
+
['DATUM', 'ENSEMBLE', 'GEODETICDATUM'].includes(value.keyword.toUpperCase())
|
|
81
|
+
);
|
|
82
|
+
if (datum?.type !== 'node' || datum.values[0]?.type !== 'string') {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
const datumName = datum.values[0].value.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
86
|
+
if (
|
|
87
|
+
![
|
|
88
|
+
'wgs84',
|
|
89
|
+
'wgs1984',
|
|
90
|
+
'dwgs1984',
|
|
91
|
+
'worldgeodeticsystem1984',
|
|
92
|
+
'worldgeodeticsystem1984ensemble'
|
|
93
|
+
].includes(datumName)
|
|
94
|
+
) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
const angularUnits = nodes.filter(
|
|
98
|
+
node =>
|
|
99
|
+
['UNIT', 'ANGLEUNIT'].includes(node.keyword.toUpperCase()) &&
|
|
100
|
+
(node === root || root.values.includes(node) || node.keyword.toUpperCase() === 'ANGLEUNIT')
|
|
101
|
+
);
|
|
102
|
+
const primeMeridian = nodes.find(node => node.keyword.toUpperCase() === 'PRIMEM');
|
|
103
|
+
return (
|
|
104
|
+
angularUnits.length > 0 &&
|
|
105
|
+
angularUnits.every(
|
|
106
|
+
node =>
|
|
107
|
+
node.values[1]?.type === 'number' &&
|
|
108
|
+
Math.abs(node.values[1].value - Math.PI / 180) < 1e-12
|
|
109
|
+
) &&
|
|
110
|
+
(!primeMeridian ||
|
|
111
|
+
(primeMeridian.values[1]?.type === 'number' && primeMeridian.values[1].value === 0))
|
|
112
|
+
);
|
|
113
|
+
} catch {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Collect WKT nodes for semantic checks without inspecting quoted text as syntax. */
|
|
119
|
+
function collectWktNodes(node: WKTCRSNode): WKTCRSNode[] {
|
|
120
|
+
return [
|
|
121
|
+
node,
|
|
122
|
+
...node.values.flatMap(value => (value.type === 'node' ? collectWktNodes(value) : []))
|
|
123
|
+
];
|
|
124
|
+
}
|
|
@@ -48,13 +48,13 @@ export class DepsInstaller {
|
|
|
48
48
|
await this.installFromNpm('draco', 'draco-worker-node.js');
|
|
49
49
|
|
|
50
50
|
console.log('Installing "Draco Writer" worker'); // eslint-disable-line no-console
|
|
51
|
-
await this.installFromNpm('draco', 'draco-writer-worker-node.
|
|
51
|
+
await this.installFromNpm('draco', 'draco-writer-worker-node.cjs');
|
|
52
52
|
|
|
53
53
|
console.log('Installing "Basis Loader" worker'); // eslint-disable-line no-console
|
|
54
|
-
await this.installFromNpm('textures', 'basis-worker-node.
|
|
54
|
+
await this.installFromNpm('textures', 'basis-worker-node.cjs');
|
|
55
55
|
|
|
56
56
|
console.log('Installing "KTX2 Basis Writer" worker'); // eslint-disable-line no-console
|
|
57
|
-
await this.installFromNpm('textures', 'ktx2-basis-writer-worker-node.
|
|
57
|
+
await this.installFromNpm('textures', 'ktx2-basis-writer-worker-node.cjs');
|
|
58
58
|
|
|
59
59
|
console.log('Installing "Draco decoder" library'); // eslint-disable-line no-console
|
|
60
60
|
await this.installFromUrl(
|
|
@@ -101,13 +101,16 @@ export class DepsInstaller {
|
|
|
101
101
|
console.log('All dependencies were installed succesfully.'); // eslint-disable-line no-console
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
/** Download a published worker or library into the converter's local resource directory. */
|
|
104
105
|
private async installFromNpm(module: string, name: string, extraPath: string = '') {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
);
|
|
106
|
+
const resourcePath = ['dist', extraPath, name].filter(Boolean).join('/');
|
|
107
|
+
const resourceUrl = `https://unpkg.com/@loaders.gl/${module}@${VERSION}/${resourcePath}`;
|
|
108
|
+
const fileResponse = await fetchFile(resourceUrl);
|
|
108
109
|
|
|
109
110
|
if (fileResponse.status < 200 || fileResponse.status >= 300) {
|
|
110
|
-
throw new Error(
|
|
111
|
+
throw new Error(
|
|
112
|
+
`Failed to load resource ${name} from ${resourceUrl}: HTTP ${fileResponse.status}`
|
|
113
|
+
);
|
|
111
114
|
}
|
|
112
115
|
|
|
113
116
|
const fileData = await fileResponse.arrayBuffer();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encodes I3S string attributes as little-endian counts followed by UTF-8 strings.
|
|
3
|
+
* Each string's byte count includes its trailing null byte. Values retain the
|
|
4
|
+
* converter's existing JavaScript string coercion, including null and undefined.
|
|
5
|
+
*/
|
|
6
|
+
export function encodeStringAttribute(values: readonly unknown[]): ArrayBuffer {
|
|
7
|
+
const textEncoder = new TextEncoder();
|
|
8
|
+
const encodedValues = Array.from(values, value => textEncoder.encode(`${String(value)}\0`));
|
|
9
|
+
const stringByteLength = encodedValues.reduce((total, value) => total + value.byteLength, 0);
|
|
10
|
+
const headerByteLength = (2 + values.length) * Uint32Array.BYTES_PER_ELEMENT;
|
|
11
|
+
const output = new Uint8Array(headerByteLength + stringByteLength);
|
|
12
|
+
const header = new DataView(output.buffer);
|
|
13
|
+
header.setUint32(0, values.length, true);
|
|
14
|
+
header.setUint32(4, stringByteLength, true);
|
|
15
|
+
|
|
16
|
+
let byteOffset = headerByteLength;
|
|
17
|
+
for (const [index, encodedValue] of encodedValues.entries()) {
|
|
18
|
+
header.setUint32(8 + index * Uint32Array.BYTES_PER_ELEMENT, encodedValue.byteLength, true);
|
|
19
|
+
output.set(encodedValue, byteOffset);
|
|
20
|
+
byteOffset += encodedValue.byteLength;
|
|
21
|
+
}
|
|
22
|
+
return output.buffer;
|
|
23
|
+
}
|