isard 1.16.0 → 2.1.0
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/CHANGELOG.md +80 -0
- package/README.md +5 -5
- package/dist/basemap/vectortiles/placed.js +7 -4
- package/dist/basemap/vectortiles/placed.js.map +1 -1
- package/dist/basemap/vectortiles/tiles.d.ts +1 -1
- package/dist/basemap/vectortiles/tiles.js.map +1 -1
- package/dist/basemap/vectortiles/vectors.d.ts +3 -1
- package/dist/basemap/vectortiles/vectors.js +2 -0
- package/dist/basemap/vectortiles/vectors.js.map +1 -1
- package/dist/basemap/vectortiles.d.ts +1 -3
- package/dist/basemap/vectortiles.js +1 -3
- package/dist/basemap/vectortiles.js.map +1 -1
- package/dist/basemap/workerpool.d.ts +1 -1
- package/dist/basemap/workerpool.js.map +1 -1
- package/dist/bind/layers.js +2 -2
- package/dist/bind/layers.js.map +1 -1
- package/dist/decoder.worker.js +4 -5
- package/dist/decoder.worker.js.map +6 -6
- package/dist/decoding/decoders.d.ts +1 -1
- package/dist/decoding/decoders.js.map +1 -1
- package/dist/decoding/loader.d.ts +6 -3
- package/dist/decoding/loader.js +7 -5
- package/dist/decoding/loader.js.map +1 -1
- package/dist/decoding/protocol.d.ts +3 -2
- package/dist/decoding/protocol.js.map +1 -1
- package/dist/engine-loader.d.ts +20 -18
- package/dist/engine-loader.js +45 -42
- package/dist/engine-loader.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js.map +1 -1
- package/dist/isard_grid_bg.wasm +0 -0
- package/dist/isard_tess_bg.wasm +0 -0
- package/dist/isard_tiles3d_bg.wasm +0 -0
- package/dist/isard_webgl2_bg.wasm +0 -0
- package/dist/isard_webgpu_bg.wasm +0 -0
- package/dist/layers/custom.d.ts +35 -29
- package/dist/layers/custom.js +60 -46
- package/dist/layers/custom.js.map +1 -1
- package/dist/layers/extrusions.d.ts +6 -1
- package/dist/layers/extrusions.js +15 -4
- package/dist/layers/extrusions.js.map +1 -1
- package/dist/layers/features.js.map +1 -1
- package/dist/layers/flow.js.map +1 -1
- package/dist/layers/glyphs.d.ts +1 -1
- package/dist/layers/glyphs.js.map +1 -1
- package/dist/layers/ground.d.ts +21 -14
- package/dist/layers/ground.js +30 -9
- package/dist/layers/ground.js.map +1 -1
- package/dist/layers/icons.d.ts +1 -1
- package/dist/layers/icons.js.map +1 -1
- package/dist/layers/layers.d.ts +1 -2
- package/dist/layers/layers.js +3 -12
- package/dist/layers/layers.js.map +1 -1
- package/dist/layers/models.d.ts +7 -1
- package/dist/layers/models.js +19 -5
- package/dist/layers/models.js.map +1 -1
- package/dist/layers/network.d.ts +1 -1
- package/dist/layers/network.js.map +1 -1
- package/dist/layers/panoramas.d.ts +1 -0
- package/dist/layers/panoramas.js +3 -2
- package/dist/layers/panoramas.js.map +1 -1
- package/dist/layers/pointclouds.d.ts +3 -3
- package/dist/layers/pointclouds.js +3 -7
- package/dist/layers/pointclouds.js.map +1 -1
- package/dist/layers/raster.js +5 -0
- package/dist/layers/raster.js.map +1 -1
- package/dist/layers/symbols.js.map +1 -1
- package/dist/layers/tiles3d.d.ts +5 -7
- package/dist/layers/tiles3d.js +9 -18
- package/dist/layers/tiles3d.js.map +1 -1
- package/dist/layers/vectors.d.ts +10 -5
- package/dist/layers/vectors.js +25 -16
- package/dist/layers/vectors.js.map +1 -1
- package/dist/map/engine-settings.d.ts +5 -2
- package/dist/map/engine-settings.js +13 -2
- package/dist/map/engine-settings.js.map +1 -1
- package/dist/map/engines.d.ts +11 -26
- package/dist/map/engines.js +10 -48
- package/dist/map/engines.js.map +1 -1
- package/dist/map/frame-loop.d.ts +1 -3
- package/dist/map/frame-loop.js +3 -3
- package/dist/map/frame-loop.js.map +1 -1
- package/dist/map/hover-pick.d.ts +9 -3
- package/dist/map/hover-pick.js +29 -6
- package/dist/map/hover-pick.js.map +1 -1
- package/dist/map/layer-stack.d.ts +7 -8
- package/dist/map/layer-stack.js +6 -9
- package/dist/map/layer-stack.js.map +1 -1
- package/dist/map/symbol-atlases.d.ts +5 -4
- package/dist/map/symbol-atlases.js +8 -13
- package/dist/map/symbol-atlases.js.map +1 -1
- package/dist/map/viewshed.d.ts +1 -1
- package/dist/map/viewshed.js.map +1 -1
- package/dist/map.d.ts +45 -26
- package/dist/map.js +141 -90
- package/dist/map.js.map +1 -1
- package/dist/react/IsardMap.d.ts +1 -1
- package/dist/react/IsardMap.js.map +1 -1
- package/dist/react/VectorGeometry.d.ts +4 -1
- package/dist/react/VectorGeometry.js +5 -1
- package/dist/react/VectorGeometry.js.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/settings.d.ts +2 -0
- package/dist/settings.js +1 -1
- package/dist/settings.js.map +1 -1
- package/dist/types.d.ts +52 -22
- package/dist/types.js.map +1 -1
- package/dist/ui/interaction.d.ts +1 -1
- package/dist/ui/interaction.js.map +1 -1
- package/dist/util/animation.d.ts +1 -1
- package/dist/util/animation.js.map +1 -1
- package/dist/wasm/isard_tiles3d.d.ts +181 -0
- package/dist/wasm/isard_tiles3d.js +387 -0
- package/dist/wasm/{isard_core.d.ts → isard_webgl2.d.ts} +387 -182
- package/dist/wasm/{isard_core.js → isard_webgl2.js} +2087 -324
- package/dist/wasm/{isard.d.ts → isard_webgpu.d.ts} +195 -358
- package/dist/wasm/{isard.js → isard_webgpu.js} +1320 -1042
- package/package.json +4 -3
- package/vite.js +5 -4
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CompressedTexture, DracoGeometry, DracoRequest, TextureFormats } from '../wasm/
|
|
1
|
+
import type { CompressedTexture, DracoGeometry, DracoRequest, TextureFormats } from '../wasm/isard_tiles3d.js';
|
|
2
2
|
/**
|
|
3
3
|
* Base URLs of the decoders (each ending with `/`).
|
|
4
4
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decoders.js","sourceRoot":"","sources":["../../src/decoding/decoders.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Optional decoders of the worker, loaded on first use from configurable URLs (the official builds three.js and\n * Cesium use): Draco geometry (`KHR_draco_mesh_compression`) and KTX2 / Basis Universal textures (`KHR_texture_basisu`),\n * transcoded to the best compressed format the GPU supports.\n */\nimport { isRecord } from '../util/guards.ts';\nimport type { CompressedTexture, DracoGeometry, DracoRequest, TextureFormats } from '../wasm/isard.js';\n\n/**\n * Base URLs of the decoders (each ending with `/`).\n *\n * The decoders are Emscripten builds published as classic scripts: the worker fetches the script and imports it as a\n * module from a `blob:` URL, so a Content Security Policy needs `blob:` in `script-src` (or `worker-src`) for 3D Tiles\n * that use Draco; it falls back on `new Function` (`'unsafe-eval'`) where `blob:` is refused. The Basis transcoder (KTX2)\n * needs `'unsafe-eval'` anyway: its own bindings (embind) build functions from strings. They are fetched from the default CDNs; to self-host them (offline, locked-down\n * networks, no third-party requests), copy the four files (`draco_wasm_wrapper_gltf.js`, `draco_decoder_gltf.wasm`\n * from the Draco release, `basis_transcoder.js`, `basis_transcoder.wasm` from three.js's `examples/jsm/libs/basis/`)\n * to your server and give their folders in `GeoMapOptions.decoders`.\n */\nexport interface DecoderUrls {\n /** Folder of `draco_wasm_wrapper_gltf.js` and `draco_decoder_gltf.wasm` (and, for Draco point clouds, of the full\n * decoder `draco_wasm_wrapper.js` and `draco_decoder.wasm`) */\n draco: string;\n /** Folder of `basis_transcoder.js` and `basis_transcoder.wasm` */\n basis: string;\n}\n\nexport const DEFAULT_DECODERS: DecoderUrls = {\n draco: 'https://www.gstatic.com/draco/versioned/decoders/1.5.7/',\n basis: 'https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/libs/basis/',\n};\n\n// ── Draco (the subset of its Emscripten API used here) ──\n\ninterface DracoStatus {\n ok(): boolean;\n error_msg(): string;\n}\ninterface DracoMesh {\n num_points(): number;\n num_faces(): number;\n}\ninterface DracoAttribute {\n num_components(): number;\n}\ninterface DracoDecoder {\n DecodeArrayToMesh(data: Int8Array, size: number, mesh: DracoMesh): DracoStatus;\n DecodeArrayToPointCloud(data: Int8Array, size: number, cloud: DracoMesh): DracoStatus;\n GetAttributeByUniqueId(mesh: DracoMesh, id: number): DracoAttribute;\n GetAttributeDataArrayForAllPoints(\n mesh: DracoMesh,\n attribute: DracoAttribute,\n type: number,\n bytes: number,\n pointer: number,\n ): boolean;\n GetTrianglesUInt32Array(mesh: DracoMesh, bytes: number, pointer: number): boolean;\n}\ninterface DracoModule {\n Decoder: new () => DracoDecoder;\n Mesh: new () => DracoMesh;\n PointCloud: new () => DracoMesh;\n DT_FLOAT32: number;\n HEAPF32: Float32Array;\n HEAPU32: Uint32Array;\n _malloc(bytes: number): number;\n _free(pointer: number): void;\n destroy(object: object): void;\n}\n\n// ── Basis Universal transcoder ──\n\ninterface KTX2File {\n isValid(): boolean;\n getLevels(): number;\n getHasAlpha(): boolean;\n startTranscoding(): boolean;\n getImageLevelInfo(level: number, layer: number, face: number): { origWidth: number; origHeight: number };\n getImageTranscodedSizeInBytes(level: number, layer: number, face: number, format: number): number;\n transcodeImage(\n target: Uint8Array,\n level: number,\n layer: number,\n face: number,\n format: number,\n alphaForOpaque: number,\n channel0: number,\n channel1: number,\n ): boolean;\n close(): void;\n delete(): void;\n}\ninterface BasisModule {\n initializeBasis(): void;\n KTX2File: new (data: Uint8Array) => KTX2File;\n}\n\ntype Factory<T> = (options: { wasmBinary: ArrayBuffer }) => Promise<T>;\n\n/** Loads an Emscripten factory published as a classic script (module workers have no importScripts): imported as a\n * module from a `blob:` URL (a Content Security Policy allowing `blob:` scripts is enough), else evaluated (where\n * `blob:` is refused: `'unsafe-eval'`, see `DecoderUrls`) */\nconst factory = async <T>(url: string, name: string): Promise<Factory<T>> => {\n const source = await (await fetch(url)).text();\n const blob = URL.createObjectURL(new Blob([`${source}\\nexport default ${name};`], { type: 'text/javascript' }));\n\n try {\n const module: unknown = await import(/* @vite-ignore */ blob);\n\n if (isRecord(module) && typeof module.default === 'function') return module.default as Factory<T>;\n } catch {\n // Refused (`blob:` not allowed): evaluated below\n } finally {\n URL.revokeObjectURL(blob);\n }\n\n return new Function(`${source}\\nreturn ${name};`)() as Factory<T>;\n};\n\nconst instantiate = async <T>(base: string, script: string, wasm: string, name: string): Promise<T> => {\n const [create, binary] = await Promise.all([\n factory<T>(`${base}${script}`, name),\n fetch(`${base}${wasm}`).then((r) => r.arrayBuffer()),\n ]);\n\n return create({ wasmBinary: binary });\n};\n\nlet draco: Promise<DracoModule> | undefined;\n/** The full Draco decoder: the glTF build decodes meshes only, not the point clouds */\nlet dracoPoints: Promise<DracoModule> | undefined;\nlet basis: Promise<BasisModule> | undefined;\n\n/** Decodes the Draco primitives of a tile (their points alone for point clouds) */\nexport const decodeDraco = async (urls: DecoderUrls, requests: DracoRequest[]): Promise<DracoGeometry[]> => {\n const meshes = requests.some((r) => !r.points);\n\n if (meshes) {\n draco ??= instantiate<DracoModule>(\n urls.draco,\n 'draco_wasm_wrapper_gltf.js',\n 'draco_decoder_gltf.wasm',\n 'DracoDecoderModule',\n );\n }\n if (requests.some((r) => r.points)) {\n dracoPoints ??= instantiate<DracoModule>(\n urls.draco,\n 'draco_wasm_wrapper.js',\n 'draco_decoder.wasm',\n 'DracoDecoderModule',\n );\n }\n\n const [forMeshes, forPoints] = await Promise.all([meshes ? draco : undefined, dracoPoints]);\n\n return requests.map((request) => {\n const module = request.points ? forPoints : forMeshes;\n\n if (!module) throw new Error('isard: the Draco decoder is not loaded');\n\n const decoder = new module.Decoder();\n const mesh = request.points ? new module.PointCloud() : new module.Mesh();\n\n try {\n const data = new Int8Array(request.data.buffer, request.data.byteOffset, request.data.byteLength);\n const status = request.points\n ? decoder.DecodeArrayToPointCloud(data, data.byteLength, mesh)\n : decoder.DecodeArrayToMesh(data, data.byteLength, mesh);\n\n if (!status.ok()) throw new Error(`Draco: ${status.error_msg()}`);\n\n const floats = (id: number): Float32Array => {\n const attribute = decoder.GetAttributeByUniqueId(mesh, id);\n const count = mesh.num_points() * attribute.num_components();\n const pointer = module._malloc(count * 4);\n\n try {\n decoder.GetAttributeDataArrayForAllPoints(mesh, attribute, module.DT_FLOAT32, count * 4, pointer);\n\n return module.HEAPF32.slice(pointer / 4, pointer / 4 + count);\n } finally {\n module._free(pointer);\n }\n };\n\n if (request.points) {\n const geometry: DracoGeometry = {\n mesh: request.mesh,\n primitive: request.primitive,\n positions: floats(request.position),\n };\n\n if (request.color !== undefined) geometry.colors = floats(request.color);\n if (request.normal !== undefined) geometry.normals = floats(request.normal);\n\n return geometry;\n }\n\n const triangles = (): Uint32Array => {\n const count = mesh.num_faces() * 3;\n const pointer = module._malloc(count * 4);\n\n try {\n decoder.GetTrianglesUInt32Array(mesh, count * 4, pointer);\n\n return module.HEAPU32.slice(pointer / 4, pointer / 4 + count);\n } finally {\n module._free(pointer);\n }\n };\n const indices = triangles();\n const geometry: DracoGeometry = {\n mesh: request.mesh,\n primitive: request.primitive,\n positions: floats(request.position),\n indices,\n };\n\n if (request.uv !== undefined) geometry.uvs = floats(request.uv);\n\n return geometry;\n } finally {\n module.destroy(mesh);\n module.destroy(decoder);\n }\n });\n};\n\n/** Basis target format and WebGL internal format, best first */\nconst target = (formats: TextureFormats, alpha: boolean): { basis: number; gl: number } => {\n if (formats.astc) return { basis: 10, gl: 0x93b0 }; // ASTC 4×4\n if (formats.bptc) return { basis: 6, gl: 0x8e8c }; // BC7\n if (formats.etc) return alpha ? { basis: 1, gl: 0x9278 } : { basis: 0, gl: 0x9274 }; // ETC2 RGBA / ETC1 as ETC2 RGB\n if (formats.s3tc) return alpha ? { basis: 3, gl: 0x83f3 } : { basis: 2, gl: 0x83f0 }; // BC3 / BC1\n\n return { basis: 13, gl: 0x8058 }; // RGBA8, uncompressed\n};\n\n/** Transcodes a KTX2 image for the GPU */\nexport const transcodeKtx2 = async (\n urls: DecoderUrls,\n formats: TextureFormats,\n bytes: Uint8Array,\n): Promise<CompressedTexture> => {\n basis ??= instantiate<BasisModule>(urls.basis, 'basis_transcoder.js', 'basis_transcoder.wasm', 'BASIS').then((m) => {\n m.initializeBasis();\n\n return m;\n });\n\n const module = await basis;\n const file = new module.KTX2File(bytes);\n\n try {\n if (!file.isValid() || !file.startTranscoding()) throw new Error('KTX2: invalid file');\n\n const { basis: format, gl } = target(formats, file.getHasAlpha());\n const levels: CompressedTexture['levels'] = Array.from({ length: file.getLevels() }, (_, level) => {\n const { origWidth: width, origHeight: height } = file.getImageLevelInfo(level, 0, 0);\n const data = new Uint8Array(file.getImageTranscodedSizeInBytes(level, 0, 0, format));\n\n if (!file.transcodeImage(data, level, 0, 0, format, 0, -1, -1)) throw new Error('KTX2: transcoding failed');\n\n return { width, height, data };\n });\n\n return { format: gl, levels };\n } finally {\n file.close();\n file.delete();\n }\n};\n"]}
|
|
1
|
+
{"version":3,"file":"decoders.js","sourceRoot":"","sources":["../../src/decoding/decoders.ts"],"names":[],"mappings":";;;;;;;;AAAA;;;;GAIG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAsB7C,MAAM,CAAC,MAAM,gBAAgB,GAAgB;IAC3C,KAAK,EAAE,yDAAyD;IAChE,KAAK,EAAE,qEAAqE;CAC7E,CAAC;AAqEF;;6DAE6D;AAC7D,MAAM,OAAO,GAAG,KAAK,EAAK,GAAW,EAAE,IAAY,EAAuB,EAAE;IAC1E,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,MAAM,oBAAoB,IAAI,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC;IAEhH,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,MAAM,MAAM,kCAAC,kBAAkB,CAAC,IAAI,EAAC,CAAC;QAE9D,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU;YAAE,OAAO,MAAM,CAAC,OAAqB,CAAC;IACpG,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;IACnD,CAAC;YAAS,CAAC;QACT,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,QAAQ,CAAC,GAAG,MAAM,YAAY,IAAI,GAAG,CAAC,EAAgB,CAAC;AACpE,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,KAAK,EAAK,IAAY,EAAE,MAAc,EAAE,IAAY,EAAE,IAAY,EAAc,EAAE;IACpG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzC,OAAO,CAAI,GAAG,IAAI,GAAG,MAAM,EAAE,EAAE,IAAI,CAAC;QACpC,KAAK,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;KACrD,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF,IAAI,KAAuC,CAAC;AAC5C,uFAAuF;AACvF,IAAI,WAA6C,CAAC;AAClD,IAAI,KAAuC,CAAC;AAE5C,mFAAmF;AACnF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,IAAiB,EAAE,QAAwB,EAA4B,EAAE;IACzG,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAE/C,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,KAAK,WAAW,CACnB,IAAI,CAAC,KAAK,EACV,4BAA4B,EAC5B,yBAAyB,EACzB,oBAAoB,CACrB,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACnC,WAAW,KAAK,WAAW,CACzB,IAAI,CAAC,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,CACrB,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IAE5F,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QAEtD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAEvE,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAE1E,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAClG,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;gBAC3B,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC;gBAC9D,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAE3D,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,UAAU,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YAElE,MAAM,MAAM,GAAG,CAAC,EAAU,EAAgB,EAAE;gBAC1C,MAAM,SAAS,GAAG,OAAO,CAAC,sBAAsB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,SAAS,CAAC,cAAc,EAAE,CAAC;gBAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;gBAE1C,IAAI,CAAC;oBACH,OAAO,CAAC,iCAAiC,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;oBAElG,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;gBAChE,CAAC;wBAAS,CAAC;oBACT,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC,CAAC;YAEF,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnB,MAAM,QAAQ,GAAkB;oBAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;iBACpC,CAAC;gBAEF,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;oBAAE,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACzE,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;oBAAE,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAE5E,OAAO,QAAQ,CAAC;YAClB,CAAC;YAED,MAAM,SAAS,GAAG,GAAgB,EAAE;gBAClC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;gBACnC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;gBAE1C,IAAI,CAAC;oBACH,OAAO,CAAC,uBAAuB,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;oBAE1D,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;gBAChE,CAAC;wBAAS,CAAC;oBACT,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC,CAAC;YACF,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAkB;gBAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACnC,OAAO;aACR,CAAC;YAEF,IAAI,OAAO,CAAC,EAAE,KAAK,SAAS;gBAAE,QAAQ,CAAC,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAEhE,OAAO,QAAQ,CAAC;QAClB,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACrB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,gEAAgE;AAChE,MAAM,MAAM,GAAG,CAAC,OAAuB,EAAE,KAAc,EAAiC,EAAE;IACxF,IAAI,OAAO,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,WAAW;IAC/D,IAAI,OAAO,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM;IACzD,IAAI,OAAO,CAAC,GAAG;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,+BAA+B;IACpH,IAAI,OAAO,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,YAAY;IAElG,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,sBAAsB;AAC1D,CAAC,CAAC;AAEF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,IAAiB,EACjB,OAAuB,EACvB,KAAiB,EACW,EAAE;IAC9B,KAAK,KAAK,WAAW,CAAc,IAAI,CAAC,KAAK,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QACjH,CAAC,CAAC,eAAe,EAAE,CAAC;QAEpB,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC;IAC3B,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExC,IAAI,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAEvF,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAClE,MAAM,MAAM,GAAgC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;YAChG,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACrF,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,6BAA6B,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YAErF,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAE5G,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAChC,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;AACH,CAAC,CAAC","sourcesContent":["/**\n * Optional decoders of the worker, loaded on first use from configurable URLs (the official builds three.js and\n * Cesium use): Draco geometry (`KHR_draco_mesh_compression`) and KTX2 / Basis Universal textures (`KHR_texture_basisu`),\n * transcoded to the best compressed format the GPU supports.\n */\nimport { isRecord } from '../util/guards.ts';\nimport type { CompressedTexture, DracoGeometry, DracoRequest, TextureFormats } from '../wasm/isard_tiles3d.js';\n\n/**\n * Base URLs of the decoders (each ending with `/`).\n *\n * The decoders are Emscripten builds published as classic scripts: the worker fetches the script and imports it as a\n * module from a `blob:` URL, so a Content Security Policy needs `blob:` in `script-src` (or `worker-src`) for 3D Tiles\n * that use Draco; it falls back on `new Function` (`'unsafe-eval'`) where `blob:` is refused. The Basis transcoder (KTX2)\n * needs `'unsafe-eval'` anyway: its own bindings (embind) build functions from strings. They are fetched from the default CDNs; to self-host them (offline, locked-down\n * networks, no third-party requests), copy the four files (`draco_wasm_wrapper_gltf.js`, `draco_decoder_gltf.wasm`\n * from the Draco release, `basis_transcoder.js`, `basis_transcoder.wasm` from three.js's `examples/jsm/libs/basis/`)\n * to your server and give their folders in `GeoMapOptions.decoders`.\n */\nexport interface DecoderUrls {\n /** Folder of `draco_wasm_wrapper_gltf.js` and `draco_decoder_gltf.wasm` (and, for Draco point clouds, of the full\n * decoder `draco_wasm_wrapper.js` and `draco_decoder.wasm`) */\n draco: string;\n /** Folder of `basis_transcoder.js` and `basis_transcoder.wasm` */\n basis: string;\n}\n\nexport const DEFAULT_DECODERS: DecoderUrls = {\n draco: 'https://www.gstatic.com/draco/versioned/decoders/1.5.7/',\n basis: 'https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/libs/basis/',\n};\n\n// ── Draco (the subset of its Emscripten API used here) ──\n\ninterface DracoStatus {\n ok(): boolean;\n error_msg(): string;\n}\ninterface DracoMesh {\n num_points(): number;\n num_faces(): number;\n}\ninterface DracoAttribute {\n num_components(): number;\n}\ninterface DracoDecoder {\n DecodeArrayToMesh(data: Int8Array, size: number, mesh: DracoMesh): DracoStatus;\n DecodeArrayToPointCloud(data: Int8Array, size: number, cloud: DracoMesh): DracoStatus;\n GetAttributeByUniqueId(mesh: DracoMesh, id: number): DracoAttribute;\n GetAttributeDataArrayForAllPoints(\n mesh: DracoMesh,\n attribute: DracoAttribute,\n type: number,\n bytes: number,\n pointer: number,\n ): boolean;\n GetTrianglesUInt32Array(mesh: DracoMesh, bytes: number, pointer: number): boolean;\n}\ninterface DracoModule {\n Decoder: new () => DracoDecoder;\n Mesh: new () => DracoMesh;\n PointCloud: new () => DracoMesh;\n DT_FLOAT32: number;\n HEAPF32: Float32Array;\n HEAPU32: Uint32Array;\n _malloc(bytes: number): number;\n _free(pointer: number): void;\n destroy(object: object): void;\n}\n\n// ── Basis Universal transcoder ──\n\ninterface KTX2File {\n isValid(): boolean;\n getLevels(): number;\n getHasAlpha(): boolean;\n startTranscoding(): boolean;\n getImageLevelInfo(level: number, layer: number, face: number): { origWidth: number; origHeight: number };\n getImageTranscodedSizeInBytes(level: number, layer: number, face: number, format: number): number;\n transcodeImage(\n target: Uint8Array,\n level: number,\n layer: number,\n face: number,\n format: number,\n alphaForOpaque: number,\n channel0: number,\n channel1: number,\n ): boolean;\n close(): void;\n delete(): void;\n}\ninterface BasisModule {\n initializeBasis(): void;\n KTX2File: new (data: Uint8Array) => KTX2File;\n}\n\ntype Factory<T> = (options: { wasmBinary: ArrayBuffer }) => Promise<T>;\n\n/** Loads an Emscripten factory published as a classic script (module workers have no importScripts): imported as a\n * module from a `blob:` URL (a Content Security Policy allowing `blob:` scripts is enough), else evaluated (where\n * `blob:` is refused: `'unsafe-eval'`, see `DecoderUrls`) */\nconst factory = async <T>(url: string, name: string): Promise<Factory<T>> => {\n const source = await (await fetch(url)).text();\n const blob = URL.createObjectURL(new Blob([`${source}\\nexport default ${name};`], { type: 'text/javascript' }));\n\n try {\n const module: unknown = await import(/* @vite-ignore */ blob);\n\n if (isRecord(module) && typeof module.default === 'function') return module.default as Factory<T>;\n } catch {\n // Refused (`blob:` not allowed): evaluated below\n } finally {\n URL.revokeObjectURL(blob);\n }\n\n return new Function(`${source}\\nreturn ${name};`)() as Factory<T>;\n};\n\nconst instantiate = async <T>(base: string, script: string, wasm: string, name: string): Promise<T> => {\n const [create, binary] = await Promise.all([\n factory<T>(`${base}${script}`, name),\n fetch(`${base}${wasm}`).then((r) => r.arrayBuffer()),\n ]);\n\n return create({ wasmBinary: binary });\n};\n\nlet draco: Promise<DracoModule> | undefined;\n/** The full Draco decoder: the glTF build decodes meshes only, not the point clouds */\nlet dracoPoints: Promise<DracoModule> | undefined;\nlet basis: Promise<BasisModule> | undefined;\n\n/** Decodes the Draco primitives of a tile (their points alone for point clouds) */\nexport const decodeDraco = async (urls: DecoderUrls, requests: DracoRequest[]): Promise<DracoGeometry[]> => {\n const meshes = requests.some((r) => !r.points);\n\n if (meshes) {\n draco ??= instantiate<DracoModule>(\n urls.draco,\n 'draco_wasm_wrapper_gltf.js',\n 'draco_decoder_gltf.wasm',\n 'DracoDecoderModule',\n );\n }\n if (requests.some((r) => r.points)) {\n dracoPoints ??= instantiate<DracoModule>(\n urls.draco,\n 'draco_wasm_wrapper.js',\n 'draco_decoder.wasm',\n 'DracoDecoderModule',\n );\n }\n\n const [forMeshes, forPoints] = await Promise.all([meshes ? draco : undefined, dracoPoints]);\n\n return requests.map((request) => {\n const module = request.points ? forPoints : forMeshes;\n\n if (!module) throw new Error('isard: the Draco decoder is not loaded');\n\n const decoder = new module.Decoder();\n const mesh = request.points ? new module.PointCloud() : new module.Mesh();\n\n try {\n const data = new Int8Array(request.data.buffer, request.data.byteOffset, request.data.byteLength);\n const status = request.points\n ? decoder.DecodeArrayToPointCloud(data, data.byteLength, mesh)\n : decoder.DecodeArrayToMesh(data, data.byteLength, mesh);\n\n if (!status.ok()) throw new Error(`Draco: ${status.error_msg()}`);\n\n const floats = (id: number): Float32Array => {\n const attribute = decoder.GetAttributeByUniqueId(mesh, id);\n const count = mesh.num_points() * attribute.num_components();\n const pointer = module._malloc(count * 4);\n\n try {\n decoder.GetAttributeDataArrayForAllPoints(mesh, attribute, module.DT_FLOAT32, count * 4, pointer);\n\n return module.HEAPF32.slice(pointer / 4, pointer / 4 + count);\n } finally {\n module._free(pointer);\n }\n };\n\n if (request.points) {\n const geometry: DracoGeometry = {\n mesh: request.mesh,\n primitive: request.primitive,\n positions: floats(request.position),\n };\n\n if (request.color !== undefined) geometry.colors = floats(request.color);\n if (request.normal !== undefined) geometry.normals = floats(request.normal);\n\n return geometry;\n }\n\n const triangles = (): Uint32Array => {\n const count = mesh.num_faces() * 3;\n const pointer = module._malloc(count * 4);\n\n try {\n decoder.GetTrianglesUInt32Array(mesh, count * 4, pointer);\n\n return module.HEAPU32.slice(pointer / 4, pointer / 4 + count);\n } finally {\n module._free(pointer);\n }\n };\n const indices = triangles();\n const geometry: DracoGeometry = {\n mesh: request.mesh,\n primitive: request.primitive,\n positions: floats(request.position),\n indices,\n };\n\n if (request.uv !== undefined) geometry.uvs = floats(request.uv);\n\n return geometry;\n } finally {\n module.destroy(mesh);\n module.destroy(decoder);\n }\n });\n};\n\n/** Basis target format and WebGL internal format, best first */\nconst target = (formats: TextureFormats, alpha: boolean): { basis: number; gl: number } => {\n if (formats.astc) return { basis: 10, gl: 0x93b0 }; // ASTC 4×4\n if (formats.bptc) return { basis: 6, gl: 0x8e8c }; // BC7\n if (formats.etc) return alpha ? { basis: 1, gl: 0x9278 } : { basis: 0, gl: 0x9274 }; // ETC2 RGBA / ETC1 as ETC2 RGB\n if (formats.s3tc) return alpha ? { basis: 3, gl: 0x83f3 } : { basis: 2, gl: 0x83f0 }; // BC3 / BC1\n\n return { basis: 13, gl: 0x8058 }; // RGBA8, uncompressed\n};\n\n/** Transcodes a KTX2 image for the GPU */\nexport const transcodeKtx2 = async (\n urls: DecoderUrls,\n formats: TextureFormats,\n bytes: Uint8Array,\n): Promise<CompressedTexture> => {\n basis ??= instantiate<BasisModule>(urls.basis, 'basis_transcoder.js', 'basis_transcoder.wasm', 'BASIS').then((m) => {\n m.initializeBasis();\n\n return m;\n });\n\n const module = await basis;\n const file = new module.KTX2File(bytes);\n\n try {\n if (!file.isValid() || !file.startTranscoding()) throw new Error('KTX2: invalid file');\n\n const { basis: format, gl } = target(formats, file.getHasAlpha());\n const levels: CompressedTexture['levels'] = Array.from({ length: file.getLevels() }, (_, level) => {\n const { origWidth: width, origHeight: height } = file.getImageLevelInfo(level, 0, 0);\n const data = new Uint8Array(file.getImageTranscodedSizeInBytes(level, 0, 0, format));\n\n if (!file.transcodeImage(data, level, 0, 0, format, 0, -1, -1)) throw new Error('KTX2: transcoding failed');\n\n return { width, height, data };\n });\n\n return { format: gl, levels };\n } finally {\n file.close();\n file.delete();\n }\n};\n"]}
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
* Pool of decoding workers for 3D Tiles content and point clouds. The engine calls `load`, `loadPoints` and `abort`
|
|
3
3
|
* (`TileLoaderLike`); the main thread then only uploads the decoded arrays to the GPU.
|
|
4
4
|
*/
|
|
5
|
-
import type { DecodedTile, TextureFormats, TileLoaderLike } from '../wasm/
|
|
5
|
+
import type { DecodedTile, TextureFormats, TileLoaderLike } from '../wasm/isard_tiles3d.js';
|
|
6
6
|
import type { DecoderUrls } from './decoders.ts';
|
|
7
7
|
export declare class TileLoader implements TileLoaderLike {
|
|
8
|
-
|
|
8
|
+
/** URL of the 3D Tiles module, for the workers */
|
|
9
|
+
private readonly tiles3d;
|
|
9
10
|
private readonly workerUrl;
|
|
10
11
|
private readonly size;
|
|
11
12
|
private readonly decoders;
|
|
@@ -20,7 +21,9 @@ export declare class TileLoader implements TileLoaderLike {
|
|
|
20
21
|
private failed;
|
|
21
22
|
/** The page's request headers, sent to the workers as they change */
|
|
22
23
|
private readonly unfollow;
|
|
23
|
-
constructor(
|
|
24
|
+
constructor(
|
|
25
|
+
/** URL of the 3D Tiles module, for the workers */
|
|
26
|
+
tiles3d: string, workerUrl: string | URL, size: number, decoders: DecoderUrls, formats: TextureFormats,
|
|
24
27
|
/** URL of the point cloud module, for the workers */
|
|
25
28
|
points?: string);
|
|
26
29
|
/** Called by the engine: fetch and decode off the main thread, on the least busy worker */
|
package/dist/decoding/loader.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { headerRules, onHeaderRules } from "../util/requests.js";
|
|
6
6
|
export class TileLoader {
|
|
7
|
-
|
|
7
|
+
tiles3d;
|
|
8
8
|
workerUrl;
|
|
9
9
|
size;
|
|
10
10
|
decoders;
|
|
@@ -22,10 +22,12 @@ export class TileLoader {
|
|
|
22
22
|
this.send(worker, { type: 'headers', rules });
|
|
23
23
|
});
|
|
24
24
|
});
|
|
25
|
-
constructor(
|
|
25
|
+
constructor(
|
|
26
|
+
/** URL of the 3D Tiles module, for the workers */
|
|
27
|
+
tiles3d, workerUrl, size, decoders, formats,
|
|
26
28
|
/** URL of the point cloud module, for the workers */
|
|
27
29
|
points = '') {
|
|
28
|
-
this.
|
|
30
|
+
this.tiles3d = tiles3d;
|
|
29
31
|
this.workerUrl = workerUrl;
|
|
30
32
|
this.size = size;
|
|
31
33
|
this.decoders = decoders;
|
|
@@ -84,8 +86,8 @@ export class TileLoader {
|
|
|
84
86
|
this.fail(worker, `the decoding worker ${this.workerUrl} failed${event.message ? `: ${event.message}` : ''}`);
|
|
85
87
|
};
|
|
86
88
|
worker.onmessageerror = () => this.fail(worker, `the decoding worker ${this.workerUrl} sent an unreadable message`);
|
|
87
|
-
const {
|
|
88
|
-
this.send(worker, { type: 'init',
|
|
89
|
+
const { tiles3d, decoders, formats, points } = this;
|
|
90
|
+
this.send(worker, { type: 'init', tiles3d, decoders, formats, points });
|
|
89
91
|
const rules = headerRules();
|
|
90
92
|
if (rules.length > 0)
|
|
91
93
|
this.send(worker, { type: 'headers', rules });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/decoding/loader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pool of decoding workers for 3D Tiles content and point clouds. The engine calls `load`, `loadPoints` and `abort`\n * (`TileLoaderLike`); the main thread then only uploads the decoded arrays to the GPU.\n */\n\nimport { headerRules, onHeaderRules } from '../util/requests.ts';\nimport type { DecodedTile, TextureFormats, TileLoaderLike } from '../wasm/isard.js';\nimport type { DecoderUrls } from './decoders.ts';\nimport type { WorkerReply, WorkerRequest } from './protocol.ts';\n\ninterface Pending {\n resolve: (result: DecodedTile | Uint8Array<ArrayBuffer>) => void;\n reject: (error: Error) => void;\n worker: Worker;\n}\n\nexport class TileLoader implements TileLoaderLike {\n private workers: Worker[] = [];\n /** Requests in flight per worker */\n private readonly busy = new Map<Worker, number>();\n private readonly pending = new Map<number, Pending>();\n /** Every worker failed: why */\n private failed: Error | undefined;\n /** The page's request headers, sent to the workers as they change */\n private readonly unfollow = onHeaderRules((rules) => {\n this.workers.forEach((worker) => {\n this.send(worker, { type: 'headers', rules });\n });\n });\n\n constructor(\n private readonly module: WebAssembly.Module,\n private readonly workerUrl: string | URL,\n private readonly size: number,\n private readonly decoders: DecoderUrls,\n private readonly formats: TextureFormats,\n /** URL of the point cloud module, for the workers */\n private readonly points: string = '',\n ) {}\n\n /** Called by the engine: fetch and decode off the main thread, on the least busy worker */\n load(\n id: number,\n url: string,\n transform: Float64Array,\n yUp: boolean,\n reload: boolean,\n priority?: 'high' | 'low',\n ): Promise<DecodedTile> {\n if (this.failed) return Promise.reject(this.failed);\n\n const worker = this.leastBusy();\n\n this.busy.set(worker, (this.busy.get(worker) ?? 0) + 1);\n\n return new Promise((resolve, reject) => {\n this.pending.set(id, { resolve: resolve as Pending['resolve'], reject, worker });\n this.send(worker, { type: 'load', id, url, transform, yUp, reload, ...(priority ? { priority } : {}) });\n });\n }\n\n /** Called by the engine: the points of a COPC node, fetched (a range request) and decoded off the main thread */\n loadPoints(\n id: number,\n url: string,\n offset: number,\n size: number,\n laz: Uint8Array,\n layout: Float64Array,\n grid: Float64Array,\n count: number,\n priority?: 'high' | 'low',\n ): Promise<Uint8Array<ArrayBuffer>> {\n if (this.failed) return Promise.reject(this.failed);\n\n const worker = this.leastBusy();\n\n this.busy.set(worker, (this.busy.get(worker) ?? 0) + 1);\n\n return new Promise((resolve, reject) => {\n this.pending.set(id, { resolve: resolve as Pending['resolve'], reject, worker });\n\n const message = { type: 'points', id, url, offset, size, laz, layout, grid, count } as const;\n\n this.send(worker, { ...message, ...(priority ? { priority } : {}) });\n });\n }\n\n abort(id: number): void {\n const pending = this.pending.get(id);\n\n if (pending) this.send(pending.worker, { type: 'abort', id });\n }\n\n destroy(): void {\n this.unfollow();\n this.workers.forEach((worker) => {\n worker.terminate();\n });\n this.workers = [];\n this.busy.clear();\n this.pending.forEach(({ reject }) => {\n reject(new Error('isard: the decoding workers are destroyed'));\n });\n this.pending.clear();\n }\n\n /** Workers start with the first tile: a map without 3D Tiles costs nothing */\n private leastBusy(): Worker {\n if (this.workers.length === 0) {\n Array.from({ length: this.size }).forEach(() => {\n const worker = new Worker(this.workerUrl, { type: 'module' });\n\n worker.onmessage = (event: MessageEvent<WorkerReply>) => this.receive(worker, event.data);\n // A worker that fails to load (a bundler serving it from elsewhere) or to read a message fails its requests\n worker.onerror = (event) => {\n event.preventDefault();\n this.fail(worker, `the decoding worker ${this.workerUrl} failed${event.message ? `: ${event.message}` : ''}`);\n };\n worker.onmessageerror = () =>\n this.fail(worker, `the decoding worker ${this.workerUrl} sent an unreadable message`);\n\n const { module, decoders, formats, points } = this;\n\n this.send(worker, { type: 'init', module, decoders, formats, points });\n\n const rules = headerRules();\n\n if (rules.length > 0) this.send(worker, { type: 'headers', rules });\n this.workers.push(worker);\n this.busy.set(worker, 0);\n });\n }\n\n const load = (worker: Worker) => this.busy.get(worker) ?? 0;\n\n return this.workers.reduce((best, worker) => (load(worker) < load(best) ? worker : best));\n }\n\n private send(worker: Worker, message: WorkerRequest): void {\n worker.postMessage(message);\n }\n\n private receive(worker: Worker, reply: WorkerReply): void {\n this.busy.set(worker, Math.max(0, (this.busy.get(worker) ?? 1) - 1));\n\n const pending = this.pending.get(reply.id);\n\n if (!pending) return;\n this.pending.delete(reply.id);\n if (reply.type === 'tile') pending.resolve(reply.tile);\n else if (reply.type === 'points') pending.resolve(reply.vertices);\n else if (reply.aborted) pending.reject(new DOMException(`tile ${reply.id} aborted`, 'AbortError'));\n else pending.reject(new Error(reply.error));\n }\n\n /** Rejects the requests of a failed worker */\n private fail(worker: Worker, message: string): void {\n const error = new Error(\n `isard: ${message}. If a bundler moves the worker, give its URL in the \\`workerUrl\\` option (see \"With a bundler\" in the guide)`,\n );\n\n this.pending.forEach((pending, id) => {\n if (pending.worker !== worker) return;\n this.pending.delete(id);\n pending.reject(error);\n });\n // Out of the pool: when none is left, the next requests fail at once\n worker.terminate();\n this.workers = this.workers.filter((w) => w !== worker);\n this.busy.delete(worker);\n if (this.workers.length === 0) this.failed = error;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/decoding/loader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pool of decoding workers for 3D Tiles content and point clouds. The engine calls `load`, `loadPoints` and `abort`\n * (`TileLoaderLike`); the main thread then only uploads the decoded arrays to the GPU.\n */\n\nimport { headerRules, onHeaderRules } from '../util/requests.ts';\nimport type { DecodedTile, TextureFormats, TileLoaderLike } from '../wasm/isard_tiles3d.js';\nimport type { DecoderUrls } from './decoders.ts';\nimport type { WorkerReply, WorkerRequest } from './protocol.ts';\n\ninterface Pending {\n resolve: (result: DecodedTile | Uint8Array<ArrayBuffer>) => void;\n reject: (error: Error) => void;\n worker: Worker;\n}\n\nexport class TileLoader implements TileLoaderLike {\n private workers: Worker[] = [];\n /** Requests in flight per worker */\n private readonly busy = new Map<Worker, number>();\n private readonly pending = new Map<number, Pending>();\n /** Every worker failed: why */\n private failed: Error | undefined;\n /** The page's request headers, sent to the workers as they change */\n private readonly unfollow = onHeaderRules((rules) => {\n this.workers.forEach((worker) => {\n this.send(worker, { type: 'headers', rules });\n });\n });\n\n constructor(\n /** URL of the 3D Tiles module, for the workers */\n private readonly tiles3d: string,\n private readonly workerUrl: string | URL,\n private readonly size: number,\n private readonly decoders: DecoderUrls,\n private readonly formats: TextureFormats,\n /** URL of the point cloud module, for the workers */\n private readonly points: string = '',\n ) {}\n\n /** Called by the engine: fetch and decode off the main thread, on the least busy worker */\n load(\n id: number,\n url: string,\n transform: Float64Array,\n yUp: boolean,\n reload: boolean,\n priority?: 'high' | 'low',\n ): Promise<DecodedTile> {\n if (this.failed) return Promise.reject(this.failed);\n\n const worker = this.leastBusy();\n\n this.busy.set(worker, (this.busy.get(worker) ?? 0) + 1);\n\n return new Promise((resolve, reject) => {\n this.pending.set(id, { resolve: resolve as Pending['resolve'], reject, worker });\n this.send(worker, { type: 'load', id, url, transform, yUp, reload, ...(priority ? { priority } : {}) });\n });\n }\n\n /** Called by the engine: the points of a COPC node, fetched (a range request) and decoded off the main thread */\n loadPoints(\n id: number,\n url: string,\n offset: number,\n size: number,\n laz: Uint8Array,\n layout: Float64Array,\n grid: Float64Array,\n count: number,\n priority?: 'high' | 'low',\n ): Promise<Uint8Array<ArrayBuffer>> {\n if (this.failed) return Promise.reject(this.failed);\n\n const worker = this.leastBusy();\n\n this.busy.set(worker, (this.busy.get(worker) ?? 0) + 1);\n\n return new Promise((resolve, reject) => {\n this.pending.set(id, { resolve: resolve as Pending['resolve'], reject, worker });\n\n const message = { type: 'points', id, url, offset, size, laz, layout, grid, count } as const;\n\n this.send(worker, { ...message, ...(priority ? { priority } : {}) });\n });\n }\n\n abort(id: number): void {\n const pending = this.pending.get(id);\n\n if (pending) this.send(pending.worker, { type: 'abort', id });\n }\n\n destroy(): void {\n this.unfollow();\n this.workers.forEach((worker) => {\n worker.terminate();\n });\n this.workers = [];\n this.busy.clear();\n this.pending.forEach(({ reject }) => {\n reject(new Error('isard: the decoding workers are destroyed'));\n });\n this.pending.clear();\n }\n\n /** Workers start with the first tile: a map without 3D Tiles costs nothing */\n private leastBusy(): Worker {\n if (this.workers.length === 0) {\n Array.from({ length: this.size }).forEach(() => {\n const worker = new Worker(this.workerUrl, { type: 'module' });\n\n worker.onmessage = (event: MessageEvent<WorkerReply>) => this.receive(worker, event.data);\n // A worker that fails to load (a bundler serving it from elsewhere) or to read a message fails its requests\n worker.onerror = (event) => {\n event.preventDefault();\n this.fail(worker, `the decoding worker ${this.workerUrl} failed${event.message ? `: ${event.message}` : ''}`);\n };\n worker.onmessageerror = () =>\n this.fail(worker, `the decoding worker ${this.workerUrl} sent an unreadable message`);\n\n const { tiles3d, decoders, formats, points } = this;\n\n this.send(worker, { type: 'init', tiles3d, decoders, formats, points });\n\n const rules = headerRules();\n\n if (rules.length > 0) this.send(worker, { type: 'headers', rules });\n this.workers.push(worker);\n this.busy.set(worker, 0);\n });\n }\n\n const load = (worker: Worker) => this.busy.get(worker) ?? 0;\n\n return this.workers.reduce((best, worker) => (load(worker) < load(best) ? worker : best));\n }\n\n private send(worker: Worker, message: WorkerRequest): void {\n worker.postMessage(message);\n }\n\n private receive(worker: Worker, reply: WorkerReply): void {\n this.busy.set(worker, Math.max(0, (this.busy.get(worker) ?? 1) - 1));\n\n const pending = this.pending.get(reply.id);\n\n if (!pending) return;\n this.pending.delete(reply.id);\n if (reply.type === 'tile') pending.resolve(reply.tile);\n else if (reply.type === 'points') pending.resolve(reply.vertices);\n else if (reply.aborted) pending.reject(new DOMException(`tile ${reply.id} aborted`, 'AbortError'));\n else pending.reject(new Error(reply.error));\n }\n\n /** Rejects the requests of a failed worker */\n private fail(worker: Worker, message: string): void {\n const error = new Error(\n `isard: ${message}. If a bundler moves the worker, give its URL in the \\`workerUrl\\` option (see \"With a bundler\" in the guide)`,\n );\n\n this.pending.forEach((pending, id) => {\n if (pending.worker !== worker) return;\n this.pending.delete(id);\n pending.reject(error);\n });\n // Out of the pool: when none is left, the next requests fail at once\n worker.terminate();\n this.workers = this.workers.filter((w) => w !== worker);\n this.busy.delete(worker);\n if (this.workers.length === 0) this.failed = error;\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Messages between the main thread and the decoding workers */
|
|
2
2
|
import type { HeaderRules } from '../util/requests.ts';
|
|
3
|
-
import type { DecodedTile, TextureFormats } from '../wasm/
|
|
3
|
+
import type { DecodedTile, TextureFormats } from '../wasm/isard_tiles3d.js';
|
|
4
4
|
import type { DecoderUrls } from './decoders.ts';
|
|
5
5
|
export type WorkerRequest =
|
|
6
6
|
/** The page's request headers (`setRequestHeaders`) */
|
|
@@ -9,7 +9,8 @@ export type WorkerRequest =
|
|
|
9
9
|
rules: HeaderRules;
|
|
10
10
|
} | {
|
|
11
11
|
type: 'init';
|
|
12
|
-
module
|
|
12
|
+
/** URL of the 3D Tiles module (`isard_tiles3d_bg.wasm`), loaded with the first tile */
|
|
13
|
+
tiles3d: string;
|
|
13
14
|
decoders: DecoderUrls;
|
|
14
15
|
formats: TextureFormats;
|
|
15
16
|
/** URL of the point cloud module (`isard_points_bg.wasm`), loaded with the first COPC chunk */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/decoding/protocol.ts"],"names":[],"mappings":"AAAA,gEAAgE","sourcesContent":["/** Messages between the main thread and the decoding workers */\n\nimport type { HeaderRules } from '../util/requests.ts';\nimport type { DecodedTile, TextureFormats } from '../wasm/
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/decoding/protocol.ts"],"names":[],"mappings":"AAAA,gEAAgE","sourcesContent":["/** Messages between the main thread and the decoding workers */\n\nimport type { HeaderRules } from '../util/requests.ts';\nimport type { DecodedTile, TextureFormats } from '../wasm/isard_tiles3d.js';\nimport type { DecoderUrls } from './decoders.ts';\n\nexport type WorkerRequest =\n /** The page's request headers (`setRequestHeaders`) */\n | { type: 'headers'; rules: HeaderRules }\n | {\n type: 'init';\n /** URL of the 3D Tiles module (`isard_tiles3d_bg.wasm`), loaded with the first tile */\n tiles3d: string;\n decoders: DecoderUrls;\n formats: TextureFormats;\n /** URL of the point cloud module (`isard_points_bg.wasm`), loaded with the first COPC chunk */\n points: string;\n }\n | {\n type: 'load';\n id: number;\n url: string;\n transform: Float64Array;\n yUp: boolean;\n reload: boolean;\n priority?: 'high' | 'low';\n }\n | {\n type: 'points';\n id: number;\n url: string;\n offset: number;\n size: number;\n laz: Uint8Array;\n layout: Float64Array;\n grid: Float64Array;\n count: number;\n priority?: 'high' | 'low';\n }\n | { type: 'abort'; id: number };\n\nexport type WorkerReply =\n | { type: 'tile'; id: number; tile: DecodedTile }\n | { type: 'points'; id: number; vertices: Uint8Array<ArrayBuffer> }\n | { type: 'error'; id: number; error: string; aborted: boolean };\n"]}
|
package/dist/engine-loader.d.ts
CHANGED
|
@@ -1,39 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The two builds of the engine, downloaded, compiled and instantiated once per page; the
|
|
3
|
-
*
|
|
2
|
+
* The two builds of the engine (WebGPU, its WebGL2 fallback), downloaded, compiled and instantiated once per page; the
|
|
3
|
+
* decoding workers of 3D Tiles; the engine of a destroyed map.
|
|
4
4
|
*/
|
|
5
5
|
import { TileLoader } from './decoding/loader.ts';
|
|
6
6
|
import type { GeoMapOptions } from './types.ts';
|
|
7
|
-
import type { Camera, Engine } from './wasm/
|
|
8
|
-
/** The class of
|
|
9
|
-
export type EngineClass =
|
|
7
|
+
import type { Camera, Engine, Engine as WebGl2Engine } from './wasm/isard_webgpu.js';
|
|
8
|
+
/** The class of the engine: made asynchronously, its device asked for (it has no constructor); its statics */
|
|
9
|
+
export type EngineClass = Pick<typeof WebGl2Engine, 'customMatrix' | 'geoidHeight'> & {
|
|
10
|
+
create: (canvas: HTMLCanvasElement, redraw: () => void, antialias?: boolean) => Promise<Engine>;
|
|
11
|
+
};
|
|
10
12
|
/** An engine loaded: its compiled module and its class */
|
|
11
13
|
export interface Bindings {
|
|
12
14
|
module: WebAssembly.Module;
|
|
13
15
|
Engine: EngineClass;
|
|
14
16
|
}
|
|
15
|
-
/**
|
|
16
|
-
export type EngineKind = '
|
|
17
|
+
/** The engine on wgpu through WebGPU, or through wgpu's WebGL2 fallback */
|
|
18
|
+
export type EngineKind = 'webgpu' | 'webgl2';
|
|
19
|
+
/** The engine on wgpu a map runs (#146): WebGPU where the browser gives an adapter, else wgpu's WebGL2 fallback;
|
|
20
|
+
* `renderer` forces one */
|
|
21
|
+
export declare const rendererKind: (renderer?: "auto" | "webgpu" | "webgl2") => Promise<"webgpu" | "webgl2">;
|
|
17
22
|
/** The files a map loads at run time, next to the module unless given elsewhere */
|
|
18
|
-
export type AssetFile = '
|
|
23
|
+
export type AssetFile = 'isard_webgpu_bg.wasm' | 'isard_webgl2_bg.wasm' | 'isard_points_bg.wasm' | 'isard_tiles3d_bg.wasm' | 'isard_tess_bg.wasm' | 'isard_grid_bg.wasm' | 'decoder.worker.js' | 'basemap.worker.js';
|
|
19
24
|
/**
|
|
20
25
|
* Where a file of isard is loaded from: its own option, else in the folder `assetsUrl` (the option, or the page's
|
|
21
26
|
* as `isard/vite` sets it), else next to the module (`import.meta.url`)
|
|
22
27
|
*/
|
|
23
28
|
export declare const assetUrl: (file: AssetFile, explicit: string | URL | undefined, assetsUrl?: string | URL) => string | URL;
|
|
24
29
|
/** Where a build of the engine is loaded from: the option, the assets' folder, or next to the module */
|
|
25
|
-
export declare const engineUrl: (kind: EngineKind, options: Pick<GeoMapOptions, "
|
|
30
|
+
export declare const engineUrl: (kind: EngineKind, options: Pick<GeoMapOptions, "webgpuWasmUrl" | "webgl2WasmUrl" | "assetsUrl">) => string | URL;
|
|
26
31
|
/** A build compiled and instantiated with its bindings (once per page, unless it failed) */
|
|
27
32
|
export declare const loadEngine: (kind: EngineKind, url: string | URL) => Promise<Bindings>;
|
|
28
|
-
/** The full engine for a map on the core one, resolved in a task of its own, not in the one that instantiated it:
|
|
29
|
-
* the map rebuilt on it there, two shorter tasks */
|
|
30
|
-
export declare const loadFullEngineLater: (url: string | URL) => Promise<Bindings>;
|
|
31
|
-
/** Downloads and compiles the full engine when the page is idle, without running it; a failure is left to the first
|
|
32
|
-
* 3D Tiles layer, which tries again */
|
|
33
|
-
export declare const preloadFullEngine: (url: string | URL, wanted: () => boolean) => void;
|
|
34
33
|
/** Where the workers load the point cloud module from (`isard_points_bg.wasm`, the LAZ decoder): the option, or next
|
|
35
34
|
* to the module; absolute, the workers being elsewhere */
|
|
36
35
|
export declare const pointsUrl: (options: Pick<GeoMapOptions, "pointsWasmUrl" | "assetsUrl">) => string;
|
|
36
|
+
/** Where the decoding workers load the 3D Tiles module from (`isard_tiles3d_bg.wasm`: a tile's content decoded for
|
|
37
|
+
* the GPU): the option, or next to the module; absolute, the workers being elsewhere */
|
|
38
|
+
export declare const tiles3dUrl: (options: Pick<GeoMapOptions, "tiles3dWasmUrl" | "assetsUrl">) => string;
|
|
37
39
|
/** Where the basemap workers load the tessellation module from (`isard_tess_bg.wasm`: the vector tiles of `vectors()`
|
|
38
40
|
* made ready for the GPU off the main thread): the option, or next to the module; absolute, the workers being
|
|
39
41
|
* elsewhere */
|
|
@@ -41,9 +43,9 @@ export declare const tessUrl: (options: Pick<GeoMapOptions, "tessWasmUrl" | "ass
|
|
|
41
43
|
/** Where the workers load the grid module from (`isard_grid_bg.wasm`: GRIB2 and NetCDF files read into grids): the
|
|
42
44
|
* option, or next to the module (absolute: the workers resolve it against their own URL otherwise) */
|
|
43
45
|
export declare const gridUrl: (options: Pick<GeoMapOptions, "gridWasmUrl" | "assetsUrl">) => string;
|
|
44
|
-
/** The decoding workers of 3D Tiles and point clouds,
|
|
45
|
-
*
|
|
46
|
-
export declare const startTileLoader: (
|
|
46
|
+
/** The decoding workers of 3D Tiles and point clouds, unless turned off (`workers: false` or 0, or no workers in this
|
|
47
|
+
* environment); without a count, as many as the map's starting quality allows */
|
|
48
|
+
export declare const startTileLoader: (options: Pick<GeoMapOptions, "workers" | "workerUrl" | "decoders" | "pointsWasmUrl" | "tiles3dWasmUrl" | "assetsUrl" | "quality">, engine: Engine) => TileLoader | undefined;
|
|
47
49
|
/** The engine of a map that has none, destroyed or while its context is lost: every method a no-op returning
|
|
48
50
|
* undefined, but the camera (the last one set: the next engine takes it) and the bounds, which late callers read */
|
|
49
51
|
export declare const destroyedEngine: (camera: Camera) => Engine;
|
package/dist/engine-loader.js
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The two builds of the engine, downloaded, compiled and instantiated once per page; the
|
|
3
|
-
*
|
|
2
|
+
* The two builds of the engine (WebGPU, its WebGL2 fallback), downloaded, compiled and instantiated once per page; the
|
|
3
|
+
* decoding workers of 3D Tiles; the engine of a destroyed map.
|
|
4
4
|
*/
|
|
5
5
|
import { defaultWorkerCount } from "./basemap/workerpool.js";
|
|
6
6
|
import { DEFAULT_DECODERS } from "./decoding/decoders.js";
|
|
7
7
|
import { TileLoader } from "./decoding/loader.js";
|
|
8
8
|
import { QUALITY, startLevel } from "./map/quality.js";
|
|
9
|
-
/** The
|
|
10
|
-
*
|
|
11
|
-
|
|
9
|
+
/** The engine on wgpu a map runs (#146): WebGPU where the browser gives an adapter, else wgpu's WebGL2 fallback;
|
|
10
|
+
* `renderer` forces one */
|
|
11
|
+
export const rendererKind = async (renderer = 'auto') => {
|
|
12
|
+
if (renderer !== 'auto')
|
|
13
|
+
return renderer;
|
|
14
|
+
const gpu = typeof navigator === 'undefined' ? undefined : Reflect.get(navigator, 'gpu');
|
|
15
|
+
const request = gpu && typeof gpu === 'object' ? Reflect.get(gpu, 'requestAdapter') : undefined;
|
|
16
|
+
if (typeof request !== 'function')
|
|
17
|
+
return 'webgl2';
|
|
18
|
+
try {
|
|
19
|
+
return (await Reflect.apply(request, gpu, [])) ? 'webgpu' : 'webgl2';
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return 'webgl2';
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
/** The two builds of the engine, each compiled once per page: through WebGPU, or through its WebGL2 fallback (a module
|
|
26
|
+
* of its own, loaded where a browser has no WebGPU) */
|
|
12
27
|
const engines = {};
|
|
13
|
-
/**
|
|
14
|
-
* compiles the full engine ahead, its first 3D Tiles layer then only instantiates it */
|
|
28
|
+
/** Their modules compiled */
|
|
15
29
|
const modules = {};
|
|
16
30
|
/** @internal Forgets the engines loaded (tests) */
|
|
17
31
|
export const forgetEngines = () => {
|
|
18
|
-
['
|
|
32
|
+
['webgpu', 'webgl2'].forEach((kind) => {
|
|
19
33
|
delete engines[kind];
|
|
20
34
|
delete modules[kind];
|
|
21
35
|
});
|
|
@@ -39,12 +53,14 @@ export const assetUrl = (file, explicit, assetsUrl) => {
|
|
|
39
53
|
return new URL(file, base ? new URL(dir, base) : dir);
|
|
40
54
|
}
|
|
41
55
|
switch (file) {
|
|
42
|
-
case '
|
|
43
|
-
return new URL('./
|
|
44
|
-
case '
|
|
45
|
-
return new URL('./
|
|
56
|
+
case 'isard_webgpu_bg.wasm':
|
|
57
|
+
return new URL('./isard_webgpu_bg.wasm', import.meta.url);
|
|
58
|
+
case 'isard_webgl2_bg.wasm':
|
|
59
|
+
return new URL('./isard_webgl2_bg.wasm', import.meta.url);
|
|
46
60
|
case 'isard_points_bg.wasm':
|
|
47
61
|
return new URL('./isard_points_bg.wasm', import.meta.url);
|
|
62
|
+
case 'isard_tiles3d_bg.wasm':
|
|
63
|
+
return new URL('./isard_tiles3d_bg.wasm', import.meta.url);
|
|
48
64
|
case 'isard_tess_bg.wasm':
|
|
49
65
|
return new URL('./isard_tess_bg.wasm', import.meta.url);
|
|
50
66
|
case 'isard_grid_bg.wasm':
|
|
@@ -56,11 +72,9 @@ export const assetUrl = (file, explicit, assetsUrl) => {
|
|
|
56
72
|
}
|
|
57
73
|
};
|
|
58
74
|
/** Where a build of the engine is loaded from: the option, the assets' folder, or next to the module */
|
|
59
|
-
export const engineUrl = (kind, options) =>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
: assetUrl('isard_core_bg.wasm', options.coreWasmUrl, options.assetsUrl);
|
|
63
|
-
};
|
|
75
|
+
export const engineUrl = (kind, options) => kind === 'webgpu'
|
|
76
|
+
? assetUrl('isard_webgpu_bg.wasm', options.webgpuWasmUrl, options.assetsUrl)
|
|
77
|
+
: assetUrl('isard_webgl2_bg.wasm', options.webgl2WasmUrl, options.assetsUrl);
|
|
64
78
|
/** Downloads and compiles a build (once per page, unless it failed: a later call tries again) */
|
|
65
79
|
const compileEngine = (kind, url) => {
|
|
66
80
|
const compiled = modules[kind];
|
|
@@ -74,6 +88,8 @@ const compileEngine = (kind, url) => {
|
|
|
74
88
|
modules[kind] = compiling;
|
|
75
89
|
return compiling;
|
|
76
90
|
};
|
|
91
|
+
/** The bindings of a build, by dynamic import: an application bundles the ones it loads only */
|
|
92
|
+
const bindingsOf = (kind) => kind === 'webgpu' ? import('./wasm/isard_webgpu.js') : import('./wasm/isard_webgl2.js');
|
|
77
93
|
/** A build compiled and instantiated with its bindings (once per page, unless it failed) */
|
|
78
94
|
export const loadEngine = (kind, url) => {
|
|
79
95
|
const loaded = engines[kind];
|
|
@@ -81,10 +97,7 @@ export const loadEngine = (kind, url) => {
|
|
|
81
97
|
return loaded;
|
|
82
98
|
const loading = (async () => {
|
|
83
99
|
// The bindings by dynamic import: an application bundles the ones it loads only
|
|
84
|
-
const [module, bindings] = await Promise.all([
|
|
85
|
-
compileEngine(kind, url),
|
|
86
|
-
kind === 'core' ? import('./wasm/isard_core.js') : import('./wasm/isard.js'),
|
|
87
|
-
]);
|
|
100
|
+
const [module, bindings] = await Promise.all([compileEngine(kind, url), bindingsOf(kind)]);
|
|
88
101
|
await bindings.default({ module_or_path: module });
|
|
89
102
|
return { module, Engine: bindings.Engine };
|
|
90
103
|
})().catch((error) => {
|
|
@@ -94,23 +107,6 @@ export const loadEngine = (kind, url) => {
|
|
|
94
107
|
engines[kind] = loading;
|
|
95
108
|
return loading;
|
|
96
109
|
};
|
|
97
|
-
/** The full engine for a map on the core one, resolved in a task of its own, not in the one that instantiated it:
|
|
98
|
-
* the map rebuilt on it there, two shorter tasks */
|
|
99
|
-
export const loadFullEngineLater = (url) => {
|
|
100
|
-
return loadEngine('full', url).then((bindings) => new Promise((resolve) => setTimeout(() => resolve(bindings), 0)));
|
|
101
|
-
};
|
|
102
|
-
/** Downloads and compiles the full engine when the page is idle, without running it; a failure is left to the first
|
|
103
|
-
* 3D Tiles layer, which tries again */
|
|
104
|
-
export const preloadFullEngine = (url, wanted) => {
|
|
105
|
-
const start = () => {
|
|
106
|
-
if (wanted())
|
|
107
|
-
compileEngine('full', url).catch(() => undefined);
|
|
108
|
-
};
|
|
109
|
-
if (typeof requestIdleCallback === 'function')
|
|
110
|
-
requestIdleCallback(start, { timeout: 2000 });
|
|
111
|
-
else
|
|
112
|
-
setTimeout(start, 0);
|
|
113
|
-
};
|
|
114
110
|
const compile = async (url) => {
|
|
115
111
|
const response = await fetch(url);
|
|
116
112
|
// The engine named: a page fails here first
|
|
@@ -131,6 +127,13 @@ export const pointsUrl = (options) => {
|
|
|
131
127
|
const base = typeof document === 'undefined' ? undefined : document.baseURI;
|
|
132
128
|
return base ? new URL(url, base).href : String(url);
|
|
133
129
|
};
|
|
130
|
+
/** Where the decoding workers load the 3D Tiles module from (`isard_tiles3d_bg.wasm`: a tile's content decoded for
|
|
131
|
+
* the GPU): the option, or next to the module; absolute, the workers being elsewhere */
|
|
132
|
+
export const tiles3dUrl = (options) => {
|
|
133
|
+
const url = assetUrl('isard_tiles3d_bg.wasm', options.tiles3dWasmUrl, options.assetsUrl);
|
|
134
|
+
const base = typeof document === 'undefined' ? undefined : document.baseURI;
|
|
135
|
+
return base ? new URL(url, base).href : String(url);
|
|
136
|
+
};
|
|
134
137
|
/** Where the basemap workers load the tessellation module from (`isard_tess_bg.wasm`: the vector tiles of `vectors()`
|
|
135
138
|
* made ready for the GPU off the main thread): the option, or next to the module; absolute, the workers being
|
|
136
139
|
* elsewhere */
|
|
@@ -146,14 +149,14 @@ export const gridUrl = (options) => {
|
|
|
146
149
|
const base = typeof document === 'undefined' ? undefined : document.baseURI;
|
|
147
150
|
return base ? new URL(url, base).href : String(url);
|
|
148
151
|
};
|
|
149
|
-
/** The decoding workers of 3D Tiles and point clouds,
|
|
150
|
-
*
|
|
151
|
-
export const startTileLoader = (
|
|
152
|
+
/** The decoding workers of 3D Tiles and point clouds, unless turned off (`workers: false` or 0, or no workers in this
|
|
153
|
+
* environment); without a count, as many as the map's starting quality allows */
|
|
154
|
+
export const startTileLoader = (options, engine) => {
|
|
152
155
|
const { workers: count, workerUrl, decoders } = options;
|
|
153
156
|
const workers = count ?? defaultWorkerCount(QUALITY[startLevel(options.quality)].workers);
|
|
154
157
|
if (workers === false || workers <= 0 || typeof Worker === 'undefined')
|
|
155
158
|
return undefined;
|
|
156
|
-
return new TileLoader(
|
|
159
|
+
return new TileLoader(tiles3dUrl(options), assetUrl('decoder.worker.js', workerUrl, options.assetsUrl), workers, { ...DEFAULT_DECODERS, ...decoders }, engine.textureFormats(), pointsUrl(options));
|
|
157
160
|
};
|
|
158
161
|
/** The engine of a map that has none, destroyed or while its context is lost: every method a no-op returning
|
|
159
162
|
* undefined, but the camera (the last one set: the next engine takes it) and the bounds, which late callers read */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine-loader.js","sourceRoot":"","sources":["../src/engine-loader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The two builds of the engine, downloaded, compiled and instantiated once per page; the decoding workers of 3D Tiles\n * that run the full one; the engine of a destroyed map.\n */\n\nimport { defaultWorkerCount } from './basemap/workerpool.ts';\nimport { DEFAULT_DECODERS } from './decoding/decoders.ts';\nimport { TileLoader } from './decoding/loader.ts';\nimport { QUALITY, startLevel } from './map/quality.ts';\nimport type { GeoMapOptions } from './types.ts';\nimport type { Camera, Engine } from './wasm/isard.js';\n\n/** The class of an engine build: its constructor and its static `customMatrix` (custom layers) */\nexport type EngineClass = (new (\n canvas: HTMLCanvasElement,\n redraw: () => void,\n antialias?: boolean,\n) => Engine) &\n Pick<typeof Engine, 'customMatrix' | 'geoidHeight'>;\n\n/** An engine loaded: its compiled module and its class */\nexport interface Bindings {\n module: WebAssembly.Module;\n Engine: EngineClass;\n}\n\n/** `core`: the engine without 3D Tiles; `full`: with them */\nexport type EngineKind = 'core' | 'full';\n\n/** The two builds of the engine, each compiled once per page: `core` without 3D Tiles (a third smaller), loaded by\n * every map; `full` with them, loaded for the first 3D Tiles layer, its module shared with the decoding workers. The\n * core engine has the same API but the 3D Tiles methods: its class is typed as the full one. */\nconst engines: { core?: Promise<Bindings>; full?: Promise<Bindings> } = {};\n/** The modules compiled (downloaded and compiled off the main thread, not instantiated): `tiles3d: 'preload'`\n * compiles the full engine ahead, its first 3D Tiles layer then only instantiates it */\nconst modules: { core?: Promise<WebAssembly.Module>; full?: Promise<WebAssembly.Module> } = {};\n\n/** @internal Forgets the engines loaded (tests) */\nexport const forgetEngines = (): void => {\n (['core', 'full'] as const).forEach((kind) => {\n delete engines[kind];\n delete modules[kind];\n });\n};\n\n/** The files a map loads at run time, next to the module unless given elsewhere */\nexport type AssetFile =\n | 'isard_bg.wasm'\n | 'isard_core_bg.wasm'\n | 'isard_points_bg.wasm'\n | 'isard_tess_bg.wasm'\n | 'isard_grid_bg.wasm'\n | 'decoder.worker.js'\n | 'basemap.worker.js';\n\n/** The folder the assets are served from for the whole page, as `isard/vite` sets it; undefined: next to the module */\nconst pageAssets = (): string | undefined => {\n const url: unknown = Reflect.get(globalThis, 'isardAssetsUrl');\n\n return typeof url === 'string' ? url : undefined;\n};\n\n/**\n * Where a file of isard is loaded from: its own option, else in the folder `assetsUrl` (the option, or the page's\n * as `isard/vite` sets it), else next to the module (`import.meta.url`)\n */\nexport const assetUrl = (\n file: AssetFile,\n explicit: string | URL | undefined,\n assetsUrl?: string | URL,\n): string | URL => {\n if (explicit) return explicit;\n\n const folder = assetsUrl ?? pageAssets();\n\n if (folder) {\n const base = typeof document === 'undefined' ? undefined : document.baseURI;\n const dir = String(folder).endsWith('/') ? String(folder) : `${String(folder)}/`;\n\n return new URL(file, base ? new URL(dir, base) : dir);\n }\n switch (file) {\n case 'isard_bg.wasm':\n return new URL('./isard_bg.wasm', import.meta.url);\n case 'isard_core_bg.wasm':\n return new URL('./isard_core_bg.wasm', import.meta.url);\n case 'isard_points_bg.wasm':\n return new URL('./isard_points_bg.wasm', import.meta.url);\n case 'isard_tess_bg.wasm':\n return new URL('./isard_tess_bg.wasm', import.meta.url);\n case 'isard_grid_bg.wasm':\n return new URL('./isard_grid_bg.wasm', import.meta.url);\n case 'decoder.worker.js':\n return new URL('./decoder.worker.js', import.meta.url);\n default:\n return new URL('./basemap.worker.js', import.meta.url);\n }\n};\n\n/** Where a build of the engine is loaded from: the option, the assets' folder, or next to the module */\nexport const engineUrl = (\n kind: EngineKind,\n options: Pick<GeoMapOptions, 'wasmUrl' | 'coreWasmUrl' | 'assetsUrl'>,\n): string | URL => {\n return kind === 'full'\n ? assetUrl('isard_bg.wasm', options.wasmUrl, options.assetsUrl)\n : assetUrl('isard_core_bg.wasm', options.coreWasmUrl, options.assetsUrl);\n};\n\n/** Downloads and compiles a build (once per page, unless it failed: a later call tries again) */\nconst compileEngine = (kind: EngineKind, url: string | URL): Promise<WebAssembly.Module> => {\n const compiled = modules[kind];\n\n if (compiled) return compiled;\n\n const compiling = compile(url).catch((error: unknown) => {\n // A later call tries again (a network error, a wrong URL fixed)\n delete modules[kind];\n throw error;\n });\n\n modules[kind] = compiling;\n\n return compiling;\n};\n\n/** A build compiled and instantiated with its bindings (once per page, unless it failed) */\nexport const loadEngine = (kind: EngineKind, url: string | URL): Promise<Bindings> => {\n const loaded = engines[kind];\n\n if (loaded) return loaded;\n\n const loading = (async () => {\n // The bindings by dynamic import: an application bundles the ones it loads only\n const [module, bindings] = await Promise.all([\n compileEngine(kind, url),\n kind === 'core' ? import('./wasm/isard_core.js') : import('./wasm/isard.js'),\n ]);\n\n await bindings.default({ module_or_path: module });\n\n return { module, Engine: bindings.Engine as unknown as EngineClass };\n })().catch((error: unknown) => {\n delete engines[kind];\n throw error;\n });\n\n engines[kind] = loading;\n\n return loading;\n};\n\n/** The full engine for a map on the core one, resolved in a task of its own, not in the one that instantiated it:\n * the map rebuilt on it there, two shorter tasks */\nexport const loadFullEngineLater = (url: string | URL): Promise<Bindings> => {\n return loadEngine('full', url).then(\n (bindings) => new Promise<Bindings>((resolve) => setTimeout(() => resolve(bindings), 0)),\n );\n};\n\n/** Downloads and compiles the full engine when the page is idle, without running it; a failure is left to the first\n * 3D Tiles layer, which tries again */\nexport const preloadFullEngine = (url: string | URL, wanted: () => boolean): void => {\n const start = () => {\n if (wanted()) compileEngine('full', url).catch(() => undefined);\n };\n\n if (typeof requestIdleCallback === 'function') requestIdleCallback(start, { timeout: 2000 });\n else setTimeout(start, 0);\n};\n\nconst compile = async (url: string | URL): Promise<WebAssembly.Module> => {\n const response = await fetch(url);\n\n // The engine named: a page fails here first\n if (!response.ok) throw new Error(`isard: failed to load the engine from ${url}: ${response.status}`);\n try {\n return await WebAssembly.compileStreaming(response.clone());\n } catch {\n // Servers that do not send application/wasm\n return WebAssembly.compile(await response.arrayBuffer());\n }\n};\n\n/** Where the workers load the point cloud module from (`isard_points_bg.wasm`, the LAZ decoder): the option, or next\n * to the module; absolute, the workers being elsewhere */\nexport const pointsUrl = (options: Pick<GeoMapOptions, 'pointsWasmUrl' | 'assetsUrl'>): string => {\n const url = assetUrl('isard_points_bg.wasm', options.pointsWasmUrl, options.assetsUrl);\n const base = typeof document === 'undefined' ? undefined : document.baseURI;\n\n return base ? new URL(url, base).href : String(url);\n};\n\n/** Where the basemap workers load the tessellation module from (`isard_tess_bg.wasm`: the vector tiles of `vectors()`\n * made ready for the GPU off the main thread): the option, or next to the module; absolute, the workers being\n * elsewhere */\nexport const tessUrl = (options: Pick<GeoMapOptions, 'tessWasmUrl' | 'assetsUrl'>): string => {\n const url = assetUrl('isard_tess_bg.wasm', options.tessWasmUrl, options.assetsUrl);\n const base = typeof document === 'undefined' ? undefined : document.baseURI;\n\n return base ? new URL(url, base).href : String(url);\n};\n\n/** Where the workers load the grid module from (`isard_grid_bg.wasm`: GRIB2 and NetCDF files read into grids): the\n * option, or next to the module (absolute: the workers resolve it against their own URL otherwise) */\nexport const gridUrl = (options: Pick<GeoMapOptions, 'gridWasmUrl' | 'assetsUrl'>): string => {\n const url = assetUrl('isard_grid_bg.wasm', options.gridWasmUrl, options.assetsUrl);\n const base = typeof document === 'undefined' ? undefined : document.baseURI;\n\n return base ? new URL(url, base).href : String(url);\n};\n\n/** The decoding workers of 3D Tiles and point clouds, running the full engine's module, unless turned off (`workers:\n * false` or 0, or no workers in this environment); without a count, as many as the map's starting quality allows */\nexport const startTileLoader = (\n module: WebAssembly.Module,\n options: Pick<GeoMapOptions, 'workers' | 'workerUrl' | 'decoders' | 'pointsWasmUrl' | 'assetsUrl' | 'quality'>,\n engine: Engine,\n): TileLoader | undefined => {\n const { workers: count, workerUrl, decoders } = options;\n const workers = count ?? defaultWorkerCount(QUALITY[startLevel(options.quality)].workers);\n\n if (workers === false || workers <= 0 || typeof Worker === 'undefined') return undefined;\n\n return new TileLoader(\n module,\n assetUrl('decoder.worker.js', workerUrl, options.assetsUrl),\n workers,\n { ...DEFAULT_DECODERS, ...decoders },\n engine.textureFormats(),\n pointsUrl(options),\n );\n};\n\n/** The engine of a map that has none, destroyed or while its context is lost: every method a no-op returning\n * undefined, but the camera (the last one set: the next engine takes it) and the bounds, which late callers read */\nexport const destroyedEngine = (camera: Camera): Engine => {\n const state = { camera };\n\n return new Proxy(\n {},\n {\n get: (_, name) => {\n if (name === 'camera') return () => state.camera;\n if (name === 'setCamera') {\n return (lon: number, lat: number, zoom: number, pitch: number, bearing: number) => {\n state.camera = { ...state.camera, center: [lon, lat], zoom, pitch, bearing };\n };\n }\n if (name === 'bounds') return () => Float64Array.of(-180, -85, 180, 85);\n\n return () => undefined;\n },\n },\n ) as Engine;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"engine-loader.js","sourceRoot":"","sources":["../src/engine-loader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The two builds of the engine (WebGPU, its WebGL2 fallback), downloaded, compiled and instantiated once per page; the\n * decoding workers of 3D Tiles; the engine of a destroyed map.\n */\n\nimport { defaultWorkerCount } from './basemap/workerpool.ts';\nimport { DEFAULT_DECODERS } from './decoding/decoders.ts';\nimport { TileLoader } from './decoding/loader.ts';\nimport { QUALITY, startLevel } from './map/quality.ts';\nimport type { GeoMapOptions } from './types.ts';\nimport type { Camera, Engine, Engine as WebGl2Engine } from './wasm/isard_webgpu.js';\n\n/** The class of the engine: made asynchronously, its device asked for (it has no constructor); its statics */\nexport type EngineClass = Pick<typeof WebGl2Engine, 'customMatrix' | 'geoidHeight'> & {\n create: (canvas: HTMLCanvasElement, redraw: () => void, antialias?: boolean) => Promise<Engine>;\n};\n\n/** An engine loaded: its compiled module and its class */\nexport interface Bindings {\n module: WebAssembly.Module;\n Engine: EngineClass;\n}\n\n/** The engine on wgpu through WebGPU, or through wgpu's WebGL2 fallback */\nexport type EngineKind = 'webgpu' | 'webgl2';\n\n/** The engine on wgpu a map runs (#146): WebGPU where the browser gives an adapter, else wgpu's WebGL2 fallback;\n * `renderer` forces one */\nexport const rendererKind = async (renderer: 'auto' | 'webgpu' | 'webgl2' = 'auto'): Promise<'webgpu' | 'webgl2'> => {\n if (renderer !== 'auto') return renderer;\n\n const gpu: unknown = typeof navigator === 'undefined' ? undefined : Reflect.get(navigator, 'gpu');\n const request: unknown = gpu && typeof gpu === 'object' ? Reflect.get(gpu, 'requestAdapter') : undefined;\n\n if (typeof request !== 'function') return 'webgl2';\n try {\n return (await Reflect.apply(request, gpu, [])) ? 'webgpu' : 'webgl2';\n } catch {\n return 'webgl2';\n }\n};\n\n/** The two builds of the engine, each compiled once per page: through WebGPU, or through its WebGL2 fallback (a module\n * of its own, loaded where a browser has no WebGPU) */\nconst engines: Partial<Record<EngineKind, Promise<Bindings>>> = {};\n/** Their modules compiled */\nconst modules: Partial<Record<EngineKind, Promise<WebAssembly.Module>>> = {};\n\n/** @internal Forgets the engines loaded (tests) */\nexport const forgetEngines = (): void => {\n (['webgpu', 'webgl2'] as const).forEach((kind) => {\n delete engines[kind];\n delete modules[kind];\n });\n};\n\n/** The files a map loads at run time, next to the module unless given elsewhere */\nexport type AssetFile =\n | 'isard_webgpu_bg.wasm'\n | 'isard_webgl2_bg.wasm'\n | 'isard_points_bg.wasm'\n | 'isard_tiles3d_bg.wasm'\n | 'isard_tess_bg.wasm'\n | 'isard_grid_bg.wasm'\n | 'decoder.worker.js'\n | 'basemap.worker.js';\n\n/** The folder the assets are served from for the whole page, as `isard/vite` sets it; undefined: next to the module */\nconst pageAssets = (): string | undefined => {\n const url: unknown = Reflect.get(globalThis, 'isardAssetsUrl');\n\n return typeof url === 'string' ? url : undefined;\n};\n\n/**\n * Where a file of isard is loaded from: its own option, else in the folder `assetsUrl` (the option, or the page's\n * as `isard/vite` sets it), else next to the module (`import.meta.url`)\n */\nexport const assetUrl = (\n file: AssetFile,\n explicit: string | URL | undefined,\n assetsUrl?: string | URL,\n): string | URL => {\n if (explicit) return explicit;\n\n const folder = assetsUrl ?? pageAssets();\n\n if (folder) {\n const base = typeof document === 'undefined' ? undefined : document.baseURI;\n const dir = String(folder).endsWith('/') ? String(folder) : `${String(folder)}/`;\n\n return new URL(file, base ? new URL(dir, base) : dir);\n }\n switch (file) {\n case 'isard_webgpu_bg.wasm':\n return new URL('./isard_webgpu_bg.wasm', import.meta.url);\n case 'isard_webgl2_bg.wasm':\n return new URL('./isard_webgl2_bg.wasm', import.meta.url);\n case 'isard_points_bg.wasm':\n return new URL('./isard_points_bg.wasm', import.meta.url);\n case 'isard_tiles3d_bg.wasm':\n return new URL('./isard_tiles3d_bg.wasm', import.meta.url);\n case 'isard_tess_bg.wasm':\n return new URL('./isard_tess_bg.wasm', import.meta.url);\n case 'isard_grid_bg.wasm':\n return new URL('./isard_grid_bg.wasm', import.meta.url);\n case 'decoder.worker.js':\n return new URL('./decoder.worker.js', import.meta.url);\n default:\n return new URL('./basemap.worker.js', import.meta.url);\n }\n};\n\n/** Where a build of the engine is loaded from: the option, the assets' folder, or next to the module */\nexport const engineUrl = (\n kind: EngineKind,\n options: Pick<GeoMapOptions, 'webgpuWasmUrl' | 'webgl2WasmUrl' | 'assetsUrl'>,\n): string | URL =>\n kind === 'webgpu'\n ? assetUrl('isard_webgpu_bg.wasm', options.webgpuWasmUrl, options.assetsUrl)\n : assetUrl('isard_webgl2_bg.wasm', options.webgl2WasmUrl, options.assetsUrl);\n\n/** Downloads and compiles a build (once per page, unless it failed: a later call tries again) */\nconst compileEngine = (kind: EngineKind, url: string | URL): Promise<WebAssembly.Module> => {\n const compiled = modules[kind];\n\n if (compiled) return compiled;\n\n const compiling = compile(url).catch((error: unknown) => {\n // A later call tries again (a network error, a wrong URL fixed)\n delete modules[kind];\n throw error;\n });\n\n modules[kind] = compiling;\n\n return compiling;\n};\n\n/** The bindings of a build, by dynamic import: an application bundles the ones it loads only */\nconst bindingsOf = (kind: EngineKind) =>\n kind === 'webgpu' ? import('./wasm/isard_webgpu.js') : import('./wasm/isard_webgl2.js');\n\n/** A build compiled and instantiated with its bindings (once per page, unless it failed) */\nexport const loadEngine = (kind: EngineKind, url: string | URL): Promise<Bindings> => {\n const loaded = engines[kind];\n\n if (loaded) return loaded;\n\n const loading = (async () => {\n // The bindings by dynamic import: an application bundles the ones it loads only\n const [module, bindings] = await Promise.all([compileEngine(kind, url), bindingsOf(kind)]);\n\n await bindings.default({ module_or_path: module });\n\n return { module, Engine: bindings.Engine as unknown as EngineClass };\n })().catch((error: unknown) => {\n delete engines[kind];\n throw error;\n });\n\n engines[kind] = loading;\n\n return loading;\n};\n\nconst compile = async (url: string | URL): Promise<WebAssembly.Module> => {\n const response = await fetch(url);\n\n // The engine named: a page fails here first\n if (!response.ok) throw new Error(`isard: failed to load the engine from ${url}: ${response.status}`);\n try {\n return await WebAssembly.compileStreaming(response.clone());\n } catch {\n // Servers that do not send application/wasm\n return WebAssembly.compile(await response.arrayBuffer());\n }\n};\n\n/** Where the workers load the point cloud module from (`isard_points_bg.wasm`, the LAZ decoder): the option, or next\n * to the module; absolute, the workers being elsewhere */\nexport const pointsUrl = (options: Pick<GeoMapOptions, 'pointsWasmUrl' | 'assetsUrl'>): string => {\n const url = assetUrl('isard_points_bg.wasm', options.pointsWasmUrl, options.assetsUrl);\n const base = typeof document === 'undefined' ? undefined : document.baseURI;\n\n return base ? new URL(url, base).href : String(url);\n};\n\n/** Where the decoding workers load the 3D Tiles module from (`isard_tiles3d_bg.wasm`: a tile's content decoded for\n * the GPU): the option, or next to the module; absolute, the workers being elsewhere */\nexport const tiles3dUrl = (options: Pick<GeoMapOptions, 'tiles3dWasmUrl' | 'assetsUrl'>): string => {\n const url = assetUrl('isard_tiles3d_bg.wasm', options.tiles3dWasmUrl, options.assetsUrl);\n const base = typeof document === 'undefined' ? undefined : document.baseURI;\n\n return base ? new URL(url, base).href : String(url);\n};\n\n/** Where the basemap workers load the tessellation module from (`isard_tess_bg.wasm`: the vector tiles of `vectors()`\n * made ready for the GPU off the main thread): the option, or next to the module; absolute, the workers being\n * elsewhere */\nexport const tessUrl = (options: Pick<GeoMapOptions, 'tessWasmUrl' | 'assetsUrl'>): string => {\n const url = assetUrl('isard_tess_bg.wasm', options.tessWasmUrl, options.assetsUrl);\n const base = typeof document === 'undefined' ? undefined : document.baseURI;\n\n return base ? new URL(url, base).href : String(url);\n};\n\n/** Where the workers load the grid module from (`isard_grid_bg.wasm`: GRIB2 and NetCDF files read into grids): the\n * option, or next to the module (absolute: the workers resolve it against their own URL otherwise) */\nexport const gridUrl = (options: Pick<GeoMapOptions, 'gridWasmUrl' | 'assetsUrl'>): string => {\n const url = assetUrl('isard_grid_bg.wasm', options.gridWasmUrl, options.assetsUrl);\n const base = typeof document === 'undefined' ? undefined : document.baseURI;\n\n return base ? new URL(url, base).href : String(url);\n};\n\n/** The decoding workers of 3D Tiles and point clouds, unless turned off (`workers: false` or 0, or no workers in this\n * environment); without a count, as many as the map's starting quality allows */\nexport const startTileLoader = (\n options: Pick<\n GeoMapOptions,\n 'workers' | 'workerUrl' | 'decoders' | 'pointsWasmUrl' | 'tiles3dWasmUrl' | 'assetsUrl' | 'quality'\n >,\n engine: Engine,\n): TileLoader | undefined => {\n const { workers: count, workerUrl, decoders } = options;\n const workers = count ?? defaultWorkerCount(QUALITY[startLevel(options.quality)].workers);\n\n if (workers === false || workers <= 0 || typeof Worker === 'undefined') return undefined;\n\n return new TileLoader(\n tiles3dUrl(options),\n assetUrl('decoder.worker.js', workerUrl, options.assetsUrl),\n workers,\n { ...DEFAULT_DECODERS, ...decoders },\n engine.textureFormats(),\n pointsUrl(options),\n );\n};\n\n/** The engine of a map that has none, destroyed or while its context is lost: every method a no-op returning\n * undefined, but the camera (the last one set: the next engine takes it) and the bounds, which late callers read */\nexport const destroyedEngine = (camera: Camera): Engine => {\n const state = { camera };\n\n return new Proxy(\n {},\n {\n get: (_, name) => {\n if (name === 'camera') return () => state.camera;\n if (name === 'setCamera') {\n return (lon: number, lat: number, zoom: number, pitch: number, bearing: number) => {\n state.camera = { ...state.camera, center: [lon, lat], zoom, pitch, bearing };\n };\n }\n if (name === 'bounds') return () => Float64Array.of(-180, -85, 180, 85);\n\n return () => undefined;\n },\n },\n ) as Engine;\n};\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export type { FlowField, FlowOptions, FlowStyle, TimedField } from './layers/flo
|
|
|
47
47
|
export { FlowLayer, flowFieldFromImage, flowFieldsFromImage } from './layers/flow.ts';
|
|
48
48
|
export type { TextPart } from './layers/glyphs.ts';
|
|
49
49
|
export { DEFAULT_FONT, GLYPHS_URL } from './layers/glyphs.ts';
|
|
50
|
-
export type { GroundOptions, GroundTexture } from './layers/ground.ts';
|
|
50
|
+
export type { GroundOptions, GroundTexture, GroundUniform } from './layers/ground.ts';
|
|
51
51
|
export { GroundLayer } from './layers/ground.ts';
|
|
52
52
|
export type { ImageOptions, Pixels, SpriteIcon } from './layers/icons.ts';
|
|
53
53
|
export { Layer } from './layers/layers.ts';
|
|
@@ -67,7 +67,7 @@ export { type VectorFeature, VectorLayer, type VectorSublayer } from './layers/v
|
|
|
67
67
|
export type { HoverPicking } from './map/hover-pick.ts';
|
|
68
68
|
export { GeoMap, type LayerSpec } from './map.ts';
|
|
69
69
|
export { PANORAMAX_API, type PanoramaxPicture, type PanoramaxSequenceOptions, panoramaxPanoramas, panoramaxPhoto, panoramaxPicture, panoramaxSequence, panoramaxStyle, } from './panoramax.ts';
|
|
70
|
-
export type { AnimationOptions, AtmosphereOptions, Basemap, BasemapName, BodyOptions, CelestialBody, FeatureColor, FeatureHit, FirstPersonView, FlyToOptions, GeoMapOptions, LoadingMode, LonLat, MapEvents, MapHoverFeatureEvent, MapPointerEvent, NetworkOptions, NetworkStyle, PickOptions, Placement, Point, Projection, Quality, RasterGrid, RasterOptions, RasterStyle, SunOptions, SwipeOptions, TerrainEncoding, TerrainModel, TerrainOptions,
|
|
70
|
+
export type { AnimationOptions, AtmosphereOptions, Basemap, BasemapName, BodyOptions, CelestialBody, Drape, FeatureColor, FeatureHit, FirstPersonView, FlyToOptions, GeoMapOptions, LoadingMode, LonLat, MapEvents, MapGpuTimings, MapHoverFeatureEvent, MapMemory, MapPointerEvent, NetworkOptions, NetworkStyle, PickOptions, Placement, Point, Projection, Quality, RasterGrid, RasterOptions, RasterStyle, SunOptions, SwipeOptions, TerrainEncoding, TerrainModel, TerrainOptions, Tiles3dOptions, Tiles3dStyle, ViewshedOptions, } from './types.ts';
|
|
71
71
|
export { AttributionControl, type AttributionOptions, type Control, type ControlPosition, NavigationControl, type NavigationOptions, } from './ui/controls.ts';
|
|
72
72
|
export { MinimapControl, type MinimapOptions } from './ui/minimap.ts';
|
|
73
73
|
export { type Anchor, Marker, type MarkerEvent, type MarkerEvents, type MarkerOptions, Panel, type PanelOptions, Popup, type PopupEvents, type PopupOptions, } from './ui/overlay.ts';
|
|
@@ -76,4 +76,4 @@ export { SearchControl, type SearchOptions } from './ui/search.ts';
|
|
|
76
76
|
export { setRequestHeaders } from './util/requests.ts';
|
|
77
77
|
export type { RoofMode } from './util/roofs.ts';
|
|
78
78
|
export { sunPosition } from './util/sun.ts';
|
|
79
|
-
export type { Camera, NetworkStats, PickHit, PickResult, PointCloudInfo, PointCloudPoint, PointCloudStats, RasterLayerStats, Tiles3dStats, } from './wasm/
|
|
79
|
+
export type { Camera, NetworkStats, PickHit, PickResult, PointCloudInfo, PointCloudPoint, PointCloudStats, RasterLayerStats, Tiles3dStats, } from './wasm/isard_webgpu.js';
|