isard 1.15.0 → 2.0.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 +70 -0
- package/README.md +4 -4
- 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/workerpool.d.ts +1 -1
- package/dist/basemap/workerpool.js.map +1 -1
- package/dist/bind/layers.js +3 -1
- 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_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.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 +20 -13
- package/dist/layers/ground.js +29 -8
- 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 +2 -11
- package/dist/layers/layers.js.map +1 -1
- package/dist/layers/models.js +0 -4
- 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 +1 -1
- package/dist/layers/pointclouds.js +0 -4
- package/dist/layers/pointclouds.js.map +1 -1
- package/dist/layers/raster.js +2 -2
- package/dist/layers/raster.js.map +1 -1
- package/dist/layers/symbols.js.map +1 -1
- package/dist/layers/tiles3d.d.ts +6 -2
- package/dist/layers/tiles3d.js +23 -5
- package/dist/layers/tiles3d.js.map +1 -1
- package/dist/layers/vectors.d.ts +4 -5
- package/dist/layers/vectors.js +7 -15
- package/dist/layers/vectors.js.map +1 -1
- package/dist/map/engine-settings.d.ts +1 -1
- 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 +2 -2
- package/dist/map/layer-stack.js +1 -3
- 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 +26 -20
- package/dist/map.js +97 -82
- 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/index.d.ts +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/types.d.ts +49 -18
- 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} +375 -184
- package/dist/wasm/{isard_core.js → isard_webgl2.js} +2167 -415
- package/dist/wasm/{isard.d.ts → isard_webgpu.d.ts} +183 -355
- package/dist/wasm/{isard.js → isard_webgpu.js} +1374 -1097
- 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
|
@@ -6,7 +6,7 @@ import type { PngEncoding } from '../basemap/terrain.ts';
|
|
|
6
6
|
import { type Settings, type TerrainLoader } from '../settings.ts';
|
|
7
7
|
import type { GeoMapOptions } from '../types.ts';
|
|
8
8
|
import { type HeaderRules } from '../util/requests.ts';
|
|
9
|
-
import type { Engine } from '../wasm/
|
|
9
|
+
import type { Engine } from '../wasm/isard_webgpu.js';
|
|
10
10
|
/** The settings of a map from its options; `earth`: the map is of the Earth */
|
|
11
11
|
export declare const mapSettings: (options: GeoMapOptions, earth: boolean, terrainLoader: (url: string, encoding: PngEncoding, floor?: number) => TerrainLoader) => Settings;
|
|
12
12
|
/** Gives a new engine the settings and the page's request headers */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine-settings.js","sourceRoot":"","sources":["../../src/map/engine-settings.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The settings of the map's engine: made from the options, given to each new engine (at creation, and again after a\n * context loss or once the engine with 3D Tiles is loaded), with the page's request headers.\n */\n\nimport { SEA } from '../basemap/basemaps.ts';\nimport type { PngEncoding } from '../basemap/terrain.ts';\nimport {\n atmosphereSettings,\n bodySettings,\n haloSettings,\n rgb,\n type Settings,\n type TerrainLoader,\n terrainSettings,\n} from '../settings.ts';\nimport type { GeoMapOptions } from '../types.ts';\nimport { type HeaderRules, headerRules } from '../util/requests.ts';\nimport type { Engine } from '../wasm/
|
|
1
|
+
{"version":3,"file":"engine-settings.js","sourceRoot":"","sources":["../../src/map/engine-settings.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The settings of the map's engine: made from the options, given to each new engine (at creation, and again after a\n * context loss or once the engine with 3D Tiles is loaded), with the page's request headers.\n */\n\nimport { SEA } from '../basemap/basemaps.ts';\nimport type { PngEncoding } from '../basemap/terrain.ts';\nimport {\n atmosphereSettings,\n bodySettings,\n haloSettings,\n rgb,\n type Settings,\n type TerrainLoader,\n terrainSettings,\n} from '../settings.ts';\nimport type { GeoMapOptions } from '../types.ts';\nimport { type HeaderRules, headerRules } from '../util/requests.ts';\nimport type { Engine } from '../wasm/isard_webgpu.js';\n\n/** The settings of a map from its options; `earth`: the map is of the Earth */\nexport const mapSettings = (\n options: GeoMapOptions,\n earth: boolean,\n terrainLoader: (url: string, encoding: PngEncoding, floor?: number) => TerrainLoader,\n): Settings => {\n const body = bodySettings(options.body);\n\n return {\n body,\n zoomRange: [options.minZoom ?? 0, options.maxZoom ?? 22],\n maxPitch: options.maxPitch ?? 70,\n globe: (options.projection ?? 'globe') === 'globe',\n sky: options.sky ?? true,\n atmosphere: atmosphereSettings(options.atmosphere),\n terrain: terrainSettings(options.terrain, options.body, body.radius, terrainLoader),\n loading: options.loading ?? 'immediate',\n background: rgb(options.background ?? (earth ? '#f2f2f0' : '#000000')),\n globeColor: earth ? SEA['osm-positron'] : rgb(body.color),\n };\n};\n\n/** Gives a new engine the settings and the page's request headers */\nexport const applySettings = (engine: Engine, settings: Settings): void => {\n // The body first: the layers' shaders may take its size\n const { radius, flattening, atmosphere: air, relief } = settings.body;\n\n engine.setBody(radius, flattening, haloSettings(air), ...relief);\n sendHeaders(engine, headerRules());\n\n const { zoomRange, maxPitch, globe, sky, atmosphere, terrain, loading, background, globeColor } = settings;\n\n engine.setZoomRange(...zoomRange);\n engine.setMaxPitch(maxPitch);\n engine.setGlobe(globe);\n engine.setSky(sky);\n engine.setAtmosphere(atmosphere);\n engine.setTerrain(terrain?.url, terrain?.exaggeration ?? 1, terrain?.maxZoom, terrain?.geoid, terrain?.loader);\n engine.setImmediateLoading(loading === 'immediate');\n engine.setBackground(...background);\n engine.setGlobeColor(...globeColor);\n};\n\n/** The page's request headers to an engine (its own requests: raster tiles, tilesets, point clouds) */\nexport const sendHeaders = (engine: Engine, rules: HeaderRules): void => {\n engine.setRequestHeaders(\n rules.map(([prefix]) => prefix),\n Uint32Array.from(rules, ([, headers]) => Object.keys(headers).length),\n rules.flatMap(([, headers]) => Object.entries(headers).flat()),\n );\n};\n"]}
|
package/dist/map/engines.d.ts
CHANGED
|
@@ -1,41 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* The engine a map runs, made asynchronously (its device asked for), and the workers decoding its 3D Tiles, started
|
|
3
|
+
* with the first one.
|
|
4
4
|
*/
|
|
5
5
|
import { type EngineClass } from '../engine-loader.ts';
|
|
6
6
|
import type { Settings } from '../settings.ts';
|
|
7
7
|
import type { GeoMapOptions } from '../types.ts';
|
|
8
|
-
import type { Engine } from '../wasm/
|
|
9
|
-
/** What
|
|
10
|
-
export type Tiles3dEngineOptions = Pick<GeoMapOptions, '
|
|
11
|
-
/** The engine class of a map
|
|
8
|
+
import type { Engine } from '../wasm/isard_webgpu.js';
|
|
9
|
+
/** What making the engine and its workers needs */
|
|
10
|
+
export type Tiles3dEngineOptions = Pick<GeoMapOptions, 'workers' | 'workerUrl' | 'decoders' | 'pointsWasmUrl' | 'tiles3dWasmUrl' | 'assetsUrl' | 'quality' | 'antialias'>;
|
|
11
|
+
/** The engine class of a map (the engine on wgpu, through WebGPU or its WebGL2 fallback: one module, 3D Tiles
|
|
12
|
+
* included) and the workers decoding its 3D Tiles, started with the first engine */
|
|
12
13
|
export declare class MapEngines {
|
|
13
|
-
|
|
14
|
-
/** The class of the engine: without 3D Tiles until a 3D Tiles layer is added, unless asked for from the start */
|
|
15
|
-
private engineClass;
|
|
16
|
-
/** The module of the engine with 3D Tiles once it runs the map (the decoding workers run it too) */
|
|
17
|
-
private module;
|
|
14
|
+
private readonly engineClass;
|
|
18
15
|
private loader;
|
|
19
16
|
private readonly options;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
constructor(engineClass: EngineClass, module: WebAssembly.Module | undefined, options: Tiles3dEngineOptions, gone: () => boolean);
|
|
24
|
-
/** The engine with 3D Tiles runs the map */
|
|
25
|
-
get tiles3d(): boolean;
|
|
26
|
-
/** The engine with 3D Tiles is loading, for the 3D Tiles layers added on the core engine */
|
|
27
|
-
get upgrading(): Promise<void> | undefined;
|
|
28
|
-
/** A new engine drawing on `canvas`, with the settings and the decoding workers of 3D Tiles if it has them */
|
|
29
|
-
create(canvas: HTMLCanvasElement, redraw: () => void, settings: Settings): Engine;
|
|
17
|
+
constructor(engineClass: EngineClass, options: Tiles3dEngineOptions);
|
|
18
|
+
/** A new engine drawing on `canvas` (its device asked for), with the settings and the decoding workers */
|
|
19
|
+
create(canvas: HTMLCanvasElement, redraw: () => void, settings: Settings): Promise<Engine>;
|
|
30
20
|
/** Height of the geoid above the ellipsoid at a position, in metres */
|
|
31
21
|
geoidHeight(lon: number, lat: number): number;
|
|
32
22
|
/** The matrix of a custom layer's model at a position */
|
|
33
23
|
customMatrix(lon: number, lat: number, altitude: number): Float32Array | undefined;
|
|
34
|
-
/** Loads the engine with 3D Tiles, once at a time: `loaded` once it is the map's class, `failed` with the error;
|
|
35
|
-
* neither if the map is gone by then */
|
|
36
|
-
upgrade(loaded: () => void, failed: (error: unknown) => void): void;
|
|
37
|
-
/** Downloads and compiles the engine with 3D Tiles without running it, unless the map is gone or has it by then */
|
|
38
|
-
preload(): void;
|
|
39
24
|
/** Stops the decoding workers */
|
|
40
25
|
destroy(): void;
|
|
41
26
|
}
|
package/dist/map/engines.js
CHANGED
|
@@ -1,41 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* The engine a map runs, made asynchronously (its device asked for), and the workers decoding its 3D Tiles, started
|
|
3
|
+
* with the first one.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { startTileLoader } from "../engine-loader.js";
|
|
6
6
|
import { applySettings } from "./engine-settings.js";
|
|
7
|
-
/** The engine class of a map
|
|
7
|
+
/** The engine class of a map (the engine on wgpu, through WebGPU or its WebGL2 fallback: one module, 3D Tiles
|
|
8
|
+
* included) and the workers decoding its 3D Tiles, started with the first engine */
|
|
8
9
|
export class MapEngines {
|
|
9
|
-
/** The class of the engine: without 3D Tiles until a 3D Tiles layer is added, unless asked for from the start */
|
|
10
10
|
engineClass;
|
|
11
|
-
/** The module of the engine with 3D Tiles once it runs the map (the decoding workers run it too) */
|
|
12
|
-
module;
|
|
13
|
-
#upgrading;
|
|
14
11
|
loader;
|
|
15
12
|
options;
|
|
16
|
-
|
|
17
|
-
gone;
|
|
18
|
-
/** `module`: the module of the engine with 3D Tiles if `engineClass` is that engine */
|
|
19
|
-
constructor(engineClass, module, options, gone) {
|
|
13
|
+
constructor(engineClass, options) {
|
|
20
14
|
this.engineClass = engineClass;
|
|
21
|
-
this.module = module;
|
|
22
15
|
this.options = { ...options };
|
|
23
|
-
this.gone = gone;
|
|
24
16
|
}
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
/** The engine with 3D Tiles is loading, for the 3D Tiles layers added on the core engine */
|
|
30
|
-
get upgrading() {
|
|
31
|
-
return this.#upgrading;
|
|
32
|
-
}
|
|
33
|
-
/** A new engine drawing on `canvas`, with the settings and the decoding workers of 3D Tiles if it has them */
|
|
34
|
-
create(canvas, redraw, settings) {
|
|
35
|
-
const engine = new this.engineClass(canvas, redraw);
|
|
17
|
+
/** A new engine drawing on `canvas` (its device asked for), with the settings and the decoding workers */
|
|
18
|
+
async create(canvas, redraw, settings) {
|
|
19
|
+
const engine = await this.engineClass.create(canvas, redraw, this.options.antialias);
|
|
36
20
|
applySettings(engine, settings);
|
|
37
|
-
|
|
38
|
-
this.loader ??= this.module && startTileLoader(this.module, this.options, engine);
|
|
21
|
+
this.loader ??= startTileLoader(this.options, engine);
|
|
39
22
|
if (this.loader)
|
|
40
23
|
engine.setTileLoader(this.loader);
|
|
41
24
|
return engine;
|
|
@@ -48,27 +31,6 @@ export class MapEngines {
|
|
|
48
31
|
customMatrix(lon, lat, altitude) {
|
|
49
32
|
return this.engineClass.customMatrix(lon, lat, altitude);
|
|
50
33
|
}
|
|
51
|
-
/** Loads the engine with 3D Tiles, once at a time: `loaded` once it is the map's class, `failed` with the error;
|
|
52
|
-
* neither if the map is gone by then */
|
|
53
|
-
upgrade(loaded, failed) {
|
|
54
|
-
this.#upgrading ??= loadFullEngineLater(engineUrl('full', this.options)).then(({ module, Engine }) => {
|
|
55
|
-
this.#upgrading = undefined;
|
|
56
|
-
if (this.gone())
|
|
57
|
-
return;
|
|
58
|
-
this.engineClass = Engine;
|
|
59
|
-
this.module = module;
|
|
60
|
-
loaded();
|
|
61
|
-
}, (error) => {
|
|
62
|
-
this.#upgrading = undefined;
|
|
63
|
-
if (this.gone())
|
|
64
|
-
return;
|
|
65
|
-
failed(error);
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
/** Downloads and compiles the engine with 3D Tiles without running it, unless the map is gone or has it by then */
|
|
69
|
-
preload() {
|
|
70
|
-
preloadFullEngine(engineUrl('full', this.options), () => !this.gone() && !this.module);
|
|
71
|
-
}
|
|
72
34
|
/** Stops the decoding workers */
|
|
73
35
|
destroy() {
|
|
74
36
|
this.loader?.destroy();
|
package/dist/map/engines.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engines.js","sourceRoot":"","sources":["../../src/map/engines.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"engines.js","sourceRoot":"","sources":["../../src/map/engines.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAoB,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAIxE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAQrD;oFACoF;AACpF,MAAM,OAAO,UAAU;IACJ,WAAW,CAAc;IAClC,MAAM,CAAyB;IACtB,OAAO,CAAuB;IAE/C,YAAY,WAAwB,EAAE,OAA6B;QACjE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;IAChC,CAAC;IAED,0GAA0G;IAC1G,KAAK,CAAC,MAAM,CAAC,MAAyB,EAAE,MAAkB,EAAE,QAAkB;QAC5E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAErF,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,KAAK,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACtD,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAEnD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,uEAAuE;IACvE,WAAW,CAAC,GAAW,EAAE,GAAW;QAClC,OAAO,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChD,CAAC;IAED,yDAAyD;IACzD,YAAY,CAAC,GAAW,EAAE,GAAW,EAAE,QAAgB;QACrD,OAAO,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC3D,CAAC;IAED,iCAAiC;IACjC,OAAO;QACL,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IACzB,CAAC;CACF","sourcesContent":["/**\n * The engine a map runs, made asynchronously (its device asked for), and the workers decoding its 3D Tiles, started\n * with the first one.\n */\n\nimport type { TileLoader } from '../decoding/loader.ts';\nimport { type EngineClass, startTileLoader } from '../engine-loader.ts';\nimport type { Settings } from '../settings.ts';\nimport type { GeoMapOptions } from '../types.ts';\nimport type { Engine } from '../wasm/isard_webgpu.js';\nimport { applySettings } from './engine-settings.ts';\n\n/** What making the engine and its workers needs */\nexport type Tiles3dEngineOptions = Pick<\n GeoMapOptions,\n 'workers' | 'workerUrl' | 'decoders' | 'pointsWasmUrl' | 'tiles3dWasmUrl' | 'assetsUrl' | 'quality' | 'antialias'\n>;\n\n/** The engine class of a map (the engine on wgpu, through WebGPU or its WebGL2 fallback: one module, 3D Tiles\n * included) and the workers decoding its 3D Tiles, started with the first engine */\nexport class MapEngines {\n private readonly engineClass: EngineClass;\n private loader: TileLoader | undefined;\n private readonly options: Tiles3dEngineOptions;\n\n constructor(engineClass: EngineClass, options: Tiles3dEngineOptions) {\n this.engineClass = engineClass;\n this.options = { ...options };\n }\n\n /** A new engine drawing on `canvas` (its device asked for), with the settings and the decoding workers */\n async create(canvas: HTMLCanvasElement, redraw: () => void, settings: Settings): Promise<Engine> {\n const engine = await this.engineClass.create(canvas, redraw, this.options.antialias);\n\n applySettings(engine, settings);\n this.loader ??= startTileLoader(this.options, engine);\n if (this.loader) engine.setTileLoader(this.loader);\n\n return engine;\n }\n\n /** Height of the geoid above the ellipsoid at a position, in metres */\n geoidHeight(lon: number, lat: number): number {\n return this.engineClass.geoidHeight(lon, lat);\n }\n\n /** The matrix of a custom layer's model at a position */\n customMatrix(lon: number, lat: number, altitude: number): Float32Array | undefined {\n return this.engineClass.customMatrix(lon, lat, altitude);\n }\n\n /** Stops the decoding workers */\n destroy(): void {\n this.loader?.destroy();\n }\n}\n"]}
|
package/dist/map/frame-loop.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { Point } from '../types.ts';
|
|
7
7
|
import type { Step } from '../util/animation.ts';
|
|
8
|
-
import type { Camera, Engine } from '../wasm/
|
|
8
|
+
import type { Camera, Engine } from '../wasm/isard_webgpu.js';
|
|
9
9
|
import type { MapListeners } from './events.ts';
|
|
10
10
|
/** What the frame loop needs of its map */
|
|
11
11
|
export interface FrameHost {
|
|
@@ -19,8 +19,6 @@ export interface FrameHost {
|
|
|
19
19
|
interacting(): boolean;
|
|
20
20
|
/** Custom layers are drawn: they read the camera of the frame */
|
|
21
21
|
customLayers(): boolean;
|
|
22
|
-
/** The engine with 3D Tiles is loading: not idle */
|
|
23
|
-
upgrading(): boolean;
|
|
24
22
|
/** Work the page waits on for what it draws (the vector tiles cut in the workers, uploaded over frames): not idle */
|
|
25
23
|
working(): boolean;
|
|
26
24
|
/** The frame is drawn: what follows it (the overlays placed, the hover picking asked for at `hovered`) */
|
package/dist/map/frame-loop.js
CHANGED
|
@@ -131,9 +131,9 @@ export class FrameLoop {
|
|
|
131
131
|
// A move goes on until a frame finds the camera still: that frame sends 'moveend'
|
|
132
132
|
if (this.animation || (moved && this.moving))
|
|
133
133
|
this.request();
|
|
134
|
-
// Idle: nothing loading (
|
|
135
|
-
//
|
|
136
|
-
if (loading || host.
|
|
134
|
+
// Idle: nothing loading (nor the page's work for what it draws), no animation, no frame asked for (uploads
|
|
135
|
+
// waiting, fades, listeners)
|
|
136
|
+
if (loading || host.working() || this.animation || this.requested !== 0) {
|
|
137
137
|
this.#settled = false;
|
|
138
138
|
}
|
|
139
139
|
else if (!this.#settled) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frame-loop.js","sourceRoot":"","sources":["../../src/map/frame-loop.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The frame loop of a map: frames drawn on demand only (an idle map costs nothing), the running animation stepped in\n * each, and the events of a frame sent with it: the camera's moves, the pointer's position (coalesced to one per\n * frame, so the values computed for it are drawn in the same frame), 'render', and 'idle' once everything is loaded.\n */\n\nimport type { Point } from '../types.ts';\nimport type { Step } from '../util/animation.ts';\nimport type { Camera, Engine } from '../wasm/isard.js';\nimport type { MapListeners } from './events.ts';\n\n/** What the frame loop needs of its map */\nexport interface FrameHost {\n /** The map's engine of the moment */\n engine(): Engine;\n /** The map's camera */\n camera(): Camera;\n /** The WebGL context is lost: nothing is drawn */\n lost(): boolean;\n /** The pointer or the keys are moving the camera: no 'moveend' yet */\n interacting(): boolean;\n /** Custom layers are drawn: they read the camera of the frame */\n customLayers(): boolean;\n /** The engine with 3D Tiles is loading: not idle */\n upgrading(): boolean;\n /** Work the page waits on for what it draws (the vector tiles cut in the workers, uploaded over frames): not idle */\n working(): boolean;\n /** The frame is drawn: what follows it (the overlays placed, the hover picking asked for at `hovered`) */\n drawn(hovered: Point | undefined): void;\n}\n\n/** The frames of a map, asked for and drawn */\nexport class FrameLoop {\n private readonly host: FrameHost;\n private readonly listeners: MapListeners;\n /** Frame asked for, 0 if none */\n private requested = 0;\n private inFrame = false;\n private animation: Step | undefined;\n /** The pointer's position for the next frame */\n private hoverPoint: Point | undefined;\n private lastCamera = '';\n /** The camera moved since the last 'moveend' */\n private moving = false;\n #settled = false;\n #camera: Camera | undefined;\n\n /** `listeners`: the map's, told of the frame's events */\n constructor(host: FrameHost, listeners: MapListeners) {\n this.host = host;\n this.listeners = listeners;\n }\n\n /** The last frame found everything loaded ('idle' sent) */\n get settled(): boolean {\n return this.#settled;\n }\n\n /** The camera of the frame being drawn: what `getCamera` gives the custom layers while the engine is busy */\n get camera(): Camera | undefined {\n return this.#camera;\n }\n\n /** Asks for a frame; several calls before the next frame draw it once */\n request(): void {\n // Changes made by listeners during a frame are drawn by that frame; nothing is drawn without a context\n if (this.inFrame || this.host.lost()) return;\n this.requested ||= requestAnimationFrame((now) => this.frame(now));\n }\n\n /** Asks for a frame that sends 'idle' once everything is loaded, even if the last one already did: the waiters of\n * `whenIdle` on a map already idle (else no frame would change from loading to loaded, and none would send it) */\n requestIdle(): void {\n this.#settled = false;\n this.request();\n }\n\n /** Runs `step` every frame until it returns false; replaces the running animation */\n animate(step: Step | undefined): void {\n // A flight cut short no longer needs its destination\n if (this.animation) this.host.engine().clearPreload();\n this.animation = step;\n this.request();\n }\n\n /** The pointer's position for the next frame (undefined: none) */\n hover(point: Point | undefined): void {\n this.hoverPoint = point;\n }\n\n /** Draws a frame now, in place of the one asked for (a resized canvas is cleared: waiting one frame would flash) */\n drawNow(): void {\n cancelAnimationFrame(this.requested);\n this.frame(performance.now());\n }\n\n /** Cancels the frame asked for (the context is lost); a new one can be asked for */\n cancel(): void {\n cancelAnimationFrame(this.requested);\n this.requested = 0;\n }\n\n /** Cancels the frame asked for, for good (the map is destroyed): it stays marked as asked for */\n stop(): void {\n cancelAnimationFrame(this.requested);\n }\n\n private frame(now: number): void {\n this.requested = 0;\n try {\n this.inFrame = true;\n this.draw(now);\n } finally {\n // Whatever throws in a frame, the next ones are still drawn\n this.inFrame = false;\n }\n }\n\n private draw(now: number): void {\n if (this.animation && !this.animation(now)) this.animation = undefined;\n\n const { host, listeners } = this;\n const camera = host.camera();\n const key = `${camera.center}|${camera.zoom}|${camera.pitch}|${camera.bearing}`;\n const moved = key !== this.lastCamera;\n\n if (moved) {\n // The first frame is no move\n if (!this.moving && this.lastCamera !== '') {\n this.moving = true;\n listeners.emit('movestart', camera);\n }\n this.lastCamera = key;\n listeners.emit('move', camera);\n } else if (this.moving && !this.animation && !host.interacting()) {\n this.moving = false;\n listeners.emit('moveend', camera);\n }\n\n // Values for the pointer position are computed before drawing, in the same frame\n const hovered = this.hoverPoint;\n\n if (hovered) {\n this.hoverPoint = undefined;\n // The position under the pointer for its listeners only (a 'hoverfeature' alone does not need it)\n if (listeners.has('hover')) {\n listeners.emit('hover', { point: hovered, lonLat: host.engine().ground(hovered[0], hovered[1]) });\n }\n }\n\n const t0 = performance.now();\n\n // The engine asks for the next frame while it draws (uploads past the frame budget, fades): not ignored\n this.inFrame = false;\n // As the engine has it now (a listener may have moved it), for the custom layers drawn in the frame\n this.#camera = host.customLayers() ? host.engine().camera() : undefined;\n\n const render = (): boolean => {\n try {\n return host.engine().render();\n } finally {\n this.#camera = undefined;\n }\n };\n const loading = render();\n\n this.inFrame = true;\n host.drawn(hovered);\n listeners.emit('render', { ms: performance.now() - t0 });\n this.inFrame = false;\n // A move goes on until a frame finds the camera still: that frame sends 'moveend'\n if (this.animation || (moved && this.moving)) this.request();\n // Idle: nothing loading (the engine with 3D Tiles neither, nor the page's work for what it draws), no animation,\n // no frame asked for (uploads waiting, fades, listeners)\n if (loading || host.upgrading() || host.working() || this.animation || this.requested !== 0) {\n this.#settled = false;\n } else if (!this.#settled) {\n this.#settled = true;\n listeners.emit('idle', {});\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"frame-loop.js","sourceRoot":"","sources":["../../src/map/frame-loop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyBH,+CAA+C;AAC/C,MAAM,OAAO,SAAS;IACH,IAAI,CAAY;IAChB,SAAS,CAAe;IACzC,iCAAiC;IACzB,SAAS,GAAG,CAAC,CAAC;IACd,OAAO,GAAG,KAAK,CAAC;IAChB,SAAS,CAAmB;IACpC,gDAAgD;IACxC,UAAU,CAAoB;IAC9B,UAAU,GAAG,EAAE,CAAC;IACxB,gDAAgD;IACxC,MAAM,GAAG,KAAK,CAAC;IACvB,QAAQ,GAAG,KAAK,CAAC;IACjB,OAAO,CAAqB;IAE5B,yDAAyD;IACzD,YAAY,IAAe,EAAE,SAAuB;QAClD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,2DAA2D;IAC3D,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,6GAA6G;IAC7G,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,yEAAyE;IACzE,OAAO;QACL,uGAAuG;QACvG,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO;QAC7C,IAAI,CAAC,SAAS,KAAK,qBAAqB,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC;IAED;sHACkH;IAClH,WAAW;QACT,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,qFAAqF;IACrF,OAAO,CAAC,IAAsB;QAC5B,qDAAqD;QACrD,IAAI,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,CAAC;QACtD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,kEAAkE;IAClE,KAAK,CAAC,KAAwB;QAC5B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED,oHAAoH;IACpH,OAAO;QACL,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,oFAAoF;IACpF,MAAM;QACJ,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,iGAAiG;IACjG,IAAI;QACF,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAEO,KAAK,CAAC,GAAW;QACvB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;gBAAS,CAAC;YACT,4DAA4D;YAC5D,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAEO,IAAI,CAAC,GAAW;QACtB,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAEvE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAChF,MAAM,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC,UAAU,CAAC;QAEtC,IAAI,KAAK,EAAE,CAAC;YACV,6BAA6B;YAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;gBAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YACtC,CAAC;YACD,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;YACtB,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACjE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACpC,CAAC;QAED,iFAAiF;QACjF,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;QAEhC,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;YAC5B,kGAAkG;YAClG,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3B,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACpG,CAAC;QACH,CAAC;QAED,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAE7B,wGAAwG;QACxG,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,oGAAoG;QACpG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAExE,MAAM,MAAM,GAAG,GAAY,EAAE;YAC3B,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;YAChC,CAAC;oBAAS,CAAC;gBACT,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;YAC3B,CAAC;QACH,CAAC,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;QAEzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpB,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,kFAAkF;QAClF,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC;YAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QAC7D,2GAA2G;QAC3G,6BAA6B;QAC7B,IAAI,OAAO,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACxB,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACrB,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;CACF","sourcesContent":["/**\n * The frame loop of a map: frames drawn on demand only (an idle map costs nothing), the running animation stepped in\n * each, and the events of a frame sent with it: the camera's moves, the pointer's position (coalesced to one per\n * frame, so the values computed for it are drawn in the same frame), 'render', and 'idle' once everything is loaded.\n */\n\nimport type { Point } from '../types.ts';\nimport type { Step } from '../util/animation.ts';\nimport type { Camera, Engine } from '../wasm/isard_webgpu.js';\nimport type { MapListeners } from './events.ts';\n\n/** What the frame loop needs of its map */\nexport interface FrameHost {\n /** The map's engine of the moment */\n engine(): Engine;\n /** The map's camera */\n camera(): Camera;\n /** The WebGL context is lost: nothing is drawn */\n lost(): boolean;\n /** The pointer or the keys are moving the camera: no 'moveend' yet */\n interacting(): boolean;\n /** Custom layers are drawn: they read the camera of the frame */\n customLayers(): boolean;\n /** Work the page waits on for what it draws (the vector tiles cut in the workers, uploaded over frames): not idle */\n working(): boolean;\n /** The frame is drawn: what follows it (the overlays placed, the hover picking asked for at `hovered`) */\n drawn(hovered: Point | undefined): void;\n}\n\n/** The frames of a map, asked for and drawn */\nexport class FrameLoop {\n private readonly host: FrameHost;\n private readonly listeners: MapListeners;\n /** Frame asked for, 0 if none */\n private requested = 0;\n private inFrame = false;\n private animation: Step | undefined;\n /** The pointer's position for the next frame */\n private hoverPoint: Point | undefined;\n private lastCamera = '';\n /** The camera moved since the last 'moveend' */\n private moving = false;\n #settled = false;\n #camera: Camera | undefined;\n\n /** `listeners`: the map's, told of the frame's events */\n constructor(host: FrameHost, listeners: MapListeners) {\n this.host = host;\n this.listeners = listeners;\n }\n\n /** The last frame found everything loaded ('idle' sent) */\n get settled(): boolean {\n return this.#settled;\n }\n\n /** The camera of the frame being drawn: what `getCamera` gives the custom layers while the engine is busy */\n get camera(): Camera | undefined {\n return this.#camera;\n }\n\n /** Asks for a frame; several calls before the next frame draw it once */\n request(): void {\n // Changes made by listeners during a frame are drawn by that frame; nothing is drawn without a context\n if (this.inFrame || this.host.lost()) return;\n this.requested ||= requestAnimationFrame((now) => this.frame(now));\n }\n\n /** Asks for a frame that sends 'idle' once everything is loaded, even if the last one already did: the waiters of\n * `whenIdle` on a map already idle (else no frame would change from loading to loaded, and none would send it) */\n requestIdle(): void {\n this.#settled = false;\n this.request();\n }\n\n /** Runs `step` every frame until it returns false; replaces the running animation */\n animate(step: Step | undefined): void {\n // A flight cut short no longer needs its destination\n if (this.animation) this.host.engine().clearPreload();\n this.animation = step;\n this.request();\n }\n\n /** The pointer's position for the next frame (undefined: none) */\n hover(point: Point | undefined): void {\n this.hoverPoint = point;\n }\n\n /** Draws a frame now, in place of the one asked for (a resized canvas is cleared: waiting one frame would flash) */\n drawNow(): void {\n cancelAnimationFrame(this.requested);\n this.frame(performance.now());\n }\n\n /** Cancels the frame asked for (the context is lost); a new one can be asked for */\n cancel(): void {\n cancelAnimationFrame(this.requested);\n this.requested = 0;\n }\n\n /** Cancels the frame asked for, for good (the map is destroyed): it stays marked as asked for */\n stop(): void {\n cancelAnimationFrame(this.requested);\n }\n\n private frame(now: number): void {\n this.requested = 0;\n try {\n this.inFrame = true;\n this.draw(now);\n } finally {\n // Whatever throws in a frame, the next ones are still drawn\n this.inFrame = false;\n }\n }\n\n private draw(now: number): void {\n if (this.animation && !this.animation(now)) this.animation = undefined;\n\n const { host, listeners } = this;\n const camera = host.camera();\n const key = `${camera.center}|${camera.zoom}|${camera.pitch}|${camera.bearing}`;\n const moved = key !== this.lastCamera;\n\n if (moved) {\n // The first frame is no move\n if (!this.moving && this.lastCamera !== '') {\n this.moving = true;\n listeners.emit('movestart', camera);\n }\n this.lastCamera = key;\n listeners.emit('move', camera);\n } else if (this.moving && !this.animation && !host.interacting()) {\n this.moving = false;\n listeners.emit('moveend', camera);\n }\n\n // Values for the pointer position are computed before drawing, in the same frame\n const hovered = this.hoverPoint;\n\n if (hovered) {\n this.hoverPoint = undefined;\n // The position under the pointer for its listeners only (a 'hoverfeature' alone does not need it)\n if (listeners.has('hover')) {\n listeners.emit('hover', { point: hovered, lonLat: host.engine().ground(hovered[0], hovered[1]) });\n }\n }\n\n const t0 = performance.now();\n\n // The engine asks for the next frame while it draws (uploads past the frame budget, fades): not ignored\n this.inFrame = false;\n // As the engine has it now (a listener may have moved it), for the custom layers drawn in the frame\n this.#camera = host.customLayers() ? host.engine().camera() : undefined;\n\n const render = (): boolean => {\n try {\n return host.engine().render();\n } finally {\n this.#camera = undefined;\n }\n };\n const loading = render();\n\n this.inFrame = true;\n host.drawn(hovered);\n listeners.emit('render', { ms: performance.now() - t0 });\n this.inFrame = false;\n // A move goes on until a frame finds the camera still: that frame sends 'moveend'\n if (this.animation || (moved && this.moving)) this.request();\n // Idle: nothing loading (nor the page's work for what it draws), no animation, no frame asked for (uploads\n // waiting, fades, listeners)\n if (loading || host.working() || this.animation || this.requested !== 0) {\n this.#settled = false;\n } else if (!this.#settled) {\n this.#settled = true;\n listeners.emit('idle', {});\n }\n }\n}\n"]}
|
package/dist/map/hover-pick.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The picking of what is under
|
|
3
|
-
*
|
|
2
|
+
* The picking of what is under a point, without stalling the GPU: the engine draws its picking pass at once, its
|
|
3
|
+
* answer is read on a later frame, when the GPU is done. For 'hoverfeature' (the latest request only) and for
|
|
4
|
+
* `map.pick` (`pickOnce`).
|
|
4
5
|
*/
|
|
5
6
|
import type { Layer } from '../layers/layers.ts';
|
|
6
7
|
import type { Point } from '../types.ts';
|
|
7
|
-
import type { Engine, PickResult } from '../wasm/
|
|
8
|
+
import type { Engine, PickResult } from '../wasm/isard_webgpu.js';
|
|
9
|
+
/** What the engine finds under a point (CSS pixels), within `radius` CSS pixels, in the layers of `only` if given;
|
|
10
|
+
* undefined if it cannot pick, or no answer came in time */
|
|
11
|
+
export declare const pickOnce: (engine: () => Engine, point: Point, radius: number, only: Uint32Array | undefined) => Promise<PickResult | undefined>;
|
|
8
12
|
/** What 'hoverfeature' looks for: within `radius` CSS pixels, in `layers` only if given */
|
|
9
13
|
export interface HoverPicking {
|
|
10
14
|
radius?: number;
|
|
@@ -20,6 +24,8 @@ export declare class HoverPick {
|
|
|
20
24
|
private poll;
|
|
21
25
|
/** Polls under way: given up after `MAX_POLLS` (an answer that never comes) */
|
|
22
26
|
private polls;
|
|
27
|
+
/** The request whose answer is awaited */
|
|
28
|
+
private id;
|
|
23
29
|
/** `engine`: the map's engine of the moment; `answer`: called with what the engine found */
|
|
24
30
|
constructor(engine: () => Engine, lost: () => boolean, answer: (result: PickResult) => void);
|
|
25
31
|
/** Asks the engine what is under the pointer; its answer, read without waiting for the GPU, comes on a later frame */
|
package/dist/map/hover-pick.js
CHANGED
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The picking of what is under
|
|
3
|
-
*
|
|
2
|
+
* The picking of what is under a point, without stalling the GPU: the engine draws its picking pass at once, its
|
|
3
|
+
* answer is read on a later frame, when the GPU is done. For 'hoverfeature' (the latest request only) and for
|
|
4
|
+
* `map.pick` (`pickOnce`).
|
|
4
5
|
*/
|
|
5
|
-
/** Frames
|
|
6
|
+
/** Frames a picking waits for its answer at most (usually one or two) */
|
|
6
7
|
const MAX_POLLS = 30;
|
|
8
|
+
/** What the engine finds under a point (CSS pixels), within `radius` CSS pixels, in the layers of `only` if given;
|
|
9
|
+
* undefined if it cannot pick, or no answer came in time */
|
|
10
|
+
export const pickOnce = (engine, point, radius, only) => {
|
|
11
|
+
const id = engine().requestPick(point[0], point[1], radius, only);
|
|
12
|
+
if (!id)
|
|
13
|
+
return Promise.resolve(undefined);
|
|
14
|
+
return new Promise((resolve) => {
|
|
15
|
+
let polls = 0;
|
|
16
|
+
const next = () => {
|
|
17
|
+
const result = engine().pollPick(id);
|
|
18
|
+
polls += 1;
|
|
19
|
+
if (result || polls >= MAX_POLLS)
|
|
20
|
+
resolve(result);
|
|
21
|
+
else
|
|
22
|
+
requestAnimationFrame(next);
|
|
23
|
+
};
|
|
24
|
+
requestAnimationFrame(next);
|
|
25
|
+
});
|
|
26
|
+
};
|
|
7
27
|
/** The hover picking of a map: one request in flight at most, its answer polled frame after frame */
|
|
8
28
|
export class HoverPick {
|
|
9
29
|
engine;
|
|
@@ -14,6 +34,8 @@ export class HoverPick {
|
|
|
14
34
|
poll = 0;
|
|
15
35
|
/** Polls under way: given up after `MAX_POLLS` (an answer that never comes) */
|
|
16
36
|
polls = 0;
|
|
37
|
+
/** The request whose answer is awaited */
|
|
38
|
+
id = 0;
|
|
17
39
|
/** `engine`: the map's engine of the moment; `answer`: called with what the engine found */
|
|
18
40
|
constructor(engine, lost, answer) {
|
|
19
41
|
this.engine = engine;
|
|
@@ -23,12 +45,13 @@ export class HoverPick {
|
|
|
23
45
|
/** Asks the engine what is under the pointer; its answer, read without waiting for the GPU, comes on a later frame */
|
|
24
46
|
request(point, { radius = 0, layers }) {
|
|
25
47
|
const only = layers && Uint32Array.from(layers.map((l) => l.id));
|
|
48
|
+
this.id = this.engine().requestPick(point[0], point[1], radius, only);
|
|
26
49
|
// The engine cannot pick (no request in flight): the poll under way would wait for nothing
|
|
27
|
-
if (!this.
|
|
50
|
+
if (!this.id) {
|
|
28
51
|
this.cancel();
|
|
29
52
|
return;
|
|
30
53
|
}
|
|
31
|
-
// A new request replaces the one
|
|
54
|
+
// A new request replaces the one awaited: one poll loop at most
|
|
32
55
|
this.polls = 0;
|
|
33
56
|
if (!this.poll)
|
|
34
57
|
this.poll = requestAnimationFrame(this.next);
|
|
@@ -42,7 +65,7 @@ export class HoverPick {
|
|
|
42
65
|
this.poll = 0;
|
|
43
66
|
if (this.lost())
|
|
44
67
|
return;
|
|
45
|
-
const result = this.engine().pollPick();
|
|
68
|
+
const result = this.engine().pollPick(this.id);
|
|
46
69
|
if (!result) {
|
|
47
70
|
// The GPU is not done yet (usually a frame): asked again next frame, without drawing; given up at last
|
|
48
71
|
this.polls += 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hover-pick.js","sourceRoot":"","sources":["../../src/map/hover-pick.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hover-pick.js","sourceRoot":"","sources":["../../src/map/hover-pick.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The picking of what is under a point, without stalling the GPU: the engine draws its picking pass at once, its\n * answer is read on a later frame, when the GPU is done. For 'hoverfeature' (the latest request only) and for\n * `map.pick` (`pickOnce`).\n */\n\nimport type { Layer } from '../layers/layers.ts';\nimport type { Point } from '../types.ts';\nimport type { Engine, PickResult } from '../wasm/isard_webgpu.js';\n\n/** Frames a picking waits for its answer at most (usually one or two) */\nconst MAX_POLLS = 30;\n\n/** What the engine finds under a point (CSS pixels), within `radius` CSS pixels, in the layers of `only` if given;\n * undefined if it cannot pick, or no answer came in time */\nexport const pickOnce = (\n engine: () => Engine,\n point: Point,\n radius: number,\n only: Uint32Array | undefined,\n): Promise<PickResult | undefined> => {\n const id = engine().requestPick(point[0], point[1], radius, only);\n\n if (!id) return Promise.resolve(undefined);\n\n return new Promise((resolve) => {\n let polls = 0;\n const next = () => {\n const result: PickResult | undefined = engine().pollPick(id);\n\n polls += 1;\n if (result || polls >= MAX_POLLS) resolve(result);\n else requestAnimationFrame(next);\n };\n\n requestAnimationFrame(next);\n });\n};\n\n/** What 'hoverfeature' looks for: within `radius` CSS pixels, in `layers` only if given */\nexport interface HoverPicking {\n radius?: number;\n layers?: readonly Layer[];\n}\n\n/** The hover picking of a map: one request in flight at most, its answer polled frame after frame */\nexport class HoverPick {\n private readonly engine: () => Engine;\n /** The WebGL context is lost: no answer will come */\n private readonly lost: () => boolean;\n private readonly answer: (result: PickResult) => void;\n /** Frame polling the engine for the answer, 0 if none */\n private poll = 0;\n /** Polls under way: given up after `MAX_POLLS` (an answer that never comes) */\n private polls = 0;\n /** The request whose answer is awaited */\n private id = 0;\n\n /** `engine`: the map's engine of the moment; `answer`: called with what the engine found */\n constructor(engine: () => Engine, lost: () => boolean, answer: (result: PickResult) => void) {\n this.engine = engine;\n this.lost = lost;\n this.answer = answer;\n }\n\n /** Asks the engine what is under the pointer; its answer, read without waiting for the GPU, comes on a later frame */\n request(point: Point, { radius = 0, layers }: HoverPicking): void {\n const only = layers && Uint32Array.from(layers.map((l) => l.id));\n\n this.id = this.engine().requestPick(point[0], point[1], radius, only);\n // The engine cannot pick (no request in flight): the poll under way would wait for nothing\n if (!this.id) {\n this.cancel();\n\n return;\n }\n // A new request replaces the one awaited: one poll loop at most\n this.polls = 0;\n if (!this.poll) this.poll = requestAnimationFrame(this.next);\n }\n\n /** Stops waiting for the answer */\n cancel(): void {\n cancelAnimationFrame(this.poll);\n this.poll = 0;\n }\n\n private readonly next = (): void => {\n this.poll = 0;\n if (this.lost()) return;\n\n const result: PickResult | undefined = this.engine().pollPick(this.id);\n\n if (!result) {\n // The GPU is not done yet (usually a frame): asked again next frame, without drawing; given up at last\n this.polls += 1;\n if (this.polls < MAX_POLLS) this.poll = requestAnimationFrame(this.next);\n\n return;\n }\n this.answer(result);\n };\n}\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* in the order but not in the engine yet, and the order recreates the layers in a new engine after a context loss.
|
|
4
4
|
*/
|
|
5
5
|
import type { Layer } from '../layers/layers.ts';
|
|
6
|
-
import type { Engine } from '../wasm/
|
|
6
|
+
import type { Engine } from '../wasm/isard_webgpu.js';
|
|
7
7
|
/** A map's layers in drawing order, bottom first, and those kept on top */
|
|
8
8
|
export declare class LayerStack {
|
|
9
9
|
/** Layers in drawing order (bottom first), to recreate them after a context loss */
|
|
@@ -26,7 +26,7 @@ export declare class LayerStack {
|
|
|
26
26
|
toBottom(layer: Layer): void;
|
|
27
27
|
/** Creates the layers in a new engine, in order, but those still `waiting` (for the engine with 3D Tiles); a layer
|
|
28
28
|
* that fails is reported and left out */
|
|
29
|
-
reattach(engine: Engine
|
|
29
|
+
reattach(engine: Engine): void;
|
|
30
30
|
/** Frees what the layers hold beside the engine (custom layers' WebGL objects, models' data) */
|
|
31
31
|
dispose(): void;
|
|
32
32
|
/** Takes a layer out of the drawing order (to put it back elsewhere, or for good) */
|
package/dist/map/layer-stack.js
CHANGED
|
@@ -54,14 +54,12 @@ export class LayerStack {
|
|
|
54
54
|
}
|
|
55
55
|
/** Creates the layers in a new engine, in order, but those still `waiting` (for the engine with 3D Tiles); a layer
|
|
56
56
|
* that fails is reported and left out */
|
|
57
|
-
reattach(engine
|
|
57
|
+
reattach(engine) {
|
|
58
58
|
// No layer refers to an id of the old engine while the others are created
|
|
59
59
|
this.layers.forEach((layer) => {
|
|
60
60
|
layer.forgetEngine();
|
|
61
61
|
});
|
|
62
62
|
this.layers.forEach((layer) => {
|
|
63
|
-
if (waiting(layer))
|
|
64
|
-
return;
|
|
65
63
|
try {
|
|
66
64
|
layer.attach(engine);
|
|
67
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer-stack.js","sourceRoot":"","sources":["../../src/map/layer-stack.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,2EAA2E;AAC3E,MAAM,OAAO,UAAU;IACrB,oFAAoF;IAC3E,MAAM,GAAY,EAAE,CAAC;IAC9B,iCAAiC;IACxB,KAAK,GAAG,IAAI,GAAG,EAAS,CAAC;IACjB,MAAM,CAAe;IAEtC,+CAA+C;IAC/C,YAAY,MAAoB;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,GAAG,CAAC,KAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,mFAAmF;IACnF,GAAG,CAAC,KAAY;QACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAExB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;QAEtE,IAAI,GAAG;YAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,8BAA8B;IAC9B,MAAM,CAAC,KAAY;QACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,qDAAqD;IACrD,IAAI,CAAC,KAAY,EAAE,MAAyB;QAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEnB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;QAElD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QACjC,IAAI,KAAK,CAAC,EAAE,IAAI,CAAC;YAAE,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED,6GAA6G;IAC7G,OAAO,CAAC,KAAY,EAAE,GAAW;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAE7B,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAExB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAEzC,IAAI,KAAK,IAAI,CAAC;YAAE,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,yCAAyC;IACzC,QAAQ,CAAC,KAAY;QACnB,IAAI,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED;6CACyC;IACzC,QAAQ,CAAC,MAAc
|
|
1
|
+
{"version":3,"file":"layer-stack.js","sourceRoot":"","sources":["../../src/map/layer-stack.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The drawing order of a map's layers, kept beside the engine's: the layers waiting for the engine with 3D Tiles are\n * in the order but not in the engine yet, and the order recreates the layers in a new engine after a context loss.\n */\n\nimport type { Layer } from '../layers/layers.ts';\nimport type { Engine } from '../wasm/isard_webgpu.js';\nimport { report } from './checks.ts';\n\n/** A map's layers in drawing order, bottom first, and those kept on top */\nexport class LayerStack {\n /** Layers in drawing order (bottom first), to recreate them after a context loss */\n readonly layers: Layer[] = [];\n /** Layers new layers go under */\n readonly onTop = new Set<Layer>();\n private readonly engine: () => Engine;\n\n /** `engine`: the map's engine of the moment */\n constructor(engine: () => Engine) {\n this.engine = engine;\n }\n\n has(layer: Layer): boolean {\n return this.layers.includes(layer);\n }\n\n /** Puts a new layer on top, under the layers kept on top (the basemap's labels) */\n add(layer: Layer): void {\n this.layers.push(layer);\n\n const top = this.layers.find((l) => this.onTop.has(l) && l !== layer);\n\n if (top) this.move(layer, top);\n }\n\n /** Forgets a removed layer */\n forget(layer: Layer): void {\n this.unlist(layer);\n this.onTop.delete(layer);\n }\n\n /** Moves a layer under `before`, or on top of all */\n move(layer: Layer, before: Layer | undefined): void {\n this.unlist(layer);\n\n const index = before ? this.layers.indexOf(before) : -1;\n const at = index < 0 ? this.layers.length : index;\n\n this.layers.splice(at, 0, layer);\n if (layer.id >= 0) this.engine().moveLayer(layer.id, this.engineIndex(at));\n }\n\n /** A layer made again in the engine under a new id: `old` removed, the new one moved to the layer's place */\n replace(layer: Layer, old: number): void {\n const engine = this.engine();\n\n engine.removeLayer(old);\n\n const index = this.layers.indexOf(layer);\n\n if (index >= 0) engine.moveLayer(layer.id, this.engineIndex(index));\n }\n\n /** Moves a layer under all the others */\n toBottom(layer: Layer): void {\n this.engine().moveLayer(layer.id, 0);\n this.unlist(layer);\n this.layers.unshift(layer);\n }\n\n /** Creates the layers in a new engine, in order, but those still `waiting` (for the engine with 3D Tiles); a layer\n * that fails is reported and left out */\n reattach(engine: Engine): void {\n // No layer refers to an id of the old engine while the others are created\n this.layers.forEach((layer) => {\n layer.forgetEngine();\n });\n this.layers.forEach((layer) => {\n try {\n layer.attach(engine);\n } catch (error) {\n report(error);\n }\n });\n // Links between layers, once every layer has its new id (buildings colored by a network above them)\n this.layers.forEach((layer) => {\n if (layer.id < 0) return;\n try {\n layer.relink(engine);\n } catch (error) {\n report(error);\n }\n });\n }\n\n /** Frees what the layers hold beside the engine (custom layers' WebGL objects, models' data) */\n dispose(): void {\n this.layers.forEach((layer) => {\n layer.dispose();\n });\n }\n\n /** Takes a layer out of the drawing order (to put it back elsewhere, or for good) */\n private unlist(layer: Layer): void {\n const index = this.layers.indexOf(layer);\n\n if (index >= 0) this.layers.splice(index, 1);\n }\n\n /** Index in the engine of the layer at `index`: the layers waiting for the engine with 3D Tiles are not in it yet */\n private engineIndex(index: number): number {\n return this.layers.slice(0, index).filter((layer) => layer.id >= 0).length;\n }\n}\n"]}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/** The atlases of a map's symbol layers, the glyphs and the icons: created on first use, moved to each new engine. */
|
|
2
2
|
import { Glyphs } from '../layers/glyphs.ts';
|
|
3
3
|
import { Icons, type ImageOptions, type Pixels } from '../layers/icons.ts';
|
|
4
|
-
import type { Engine } from '../wasm/
|
|
4
|
+
import type { Engine } from '../wasm/isard_webgpu.js';
|
|
5
5
|
/** The glyphs and icons of a map */
|
|
6
6
|
export declare class SymbolAtlases {
|
|
7
7
|
#private;
|
|
8
|
-
private readonly
|
|
8
|
+
private readonly maxSize;
|
|
9
9
|
private readonly glyphsUrl;
|
|
10
10
|
private readonly engine;
|
|
11
|
-
/** `
|
|
12
|
-
|
|
11
|
+
/** `maxSize`: the largest texture the engine takes (undefined if unknown); `glyphsUrl`: the map's option; `engine`:
|
|
12
|
+
* the map's engine of the moment */
|
|
13
|
+
constructor(maxSize: () => number | undefined, glyphsUrl: string | undefined, engine: () => Engine);
|
|
13
14
|
/** The glyphs of the symbol layers, loaded on first use */
|
|
14
15
|
get glyphs(): Glyphs;
|
|
15
16
|
/** The icons of the symbol layers: the application's images and the vector basemaps' sprites */
|
|
@@ -1,30 +1,25 @@
|
|
|
1
1
|
/** The atlases of a map's symbol layers, the glyphs and the icons: created on first use, moved to each new engine. */
|
|
2
2
|
import { Glyphs } from "../layers/glyphs.js";
|
|
3
3
|
import { Icons, readPixels } from "../layers/icons.js";
|
|
4
|
-
/** The largest texture the canvas's WebGL context takes, undefined if unknown: the atlases stay within it */
|
|
5
|
-
const maxTextureSize = (canvas) => {
|
|
6
|
-
const gl = canvas.getContext('webgl2');
|
|
7
|
-
const max = gl?.getParameter(gl.MAX_TEXTURE_SIZE);
|
|
8
|
-
return typeof max === 'number' ? max : undefined;
|
|
9
|
-
};
|
|
10
4
|
/** The glyphs and icons of a map */
|
|
11
5
|
export class SymbolAtlases {
|
|
12
|
-
|
|
6
|
+
maxSize;
|
|
13
7
|
glyphsUrl;
|
|
14
8
|
engine;
|
|
15
9
|
#glyphs;
|
|
16
10
|
#icons;
|
|
17
|
-
/** `
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
/** `maxSize`: the largest texture the engine takes (undefined if unknown); `glyphsUrl`: the map's option; `engine`:
|
|
12
|
+
* the map's engine of the moment */
|
|
13
|
+
constructor(maxSize, glyphsUrl, engine) {
|
|
14
|
+
this.maxSize = maxSize;
|
|
20
15
|
this.glyphsUrl = glyphsUrl;
|
|
21
16
|
this.engine = engine;
|
|
22
17
|
}
|
|
23
18
|
/** The glyphs of the symbol layers, loaded on first use */
|
|
24
19
|
get glyphs() {
|
|
25
20
|
if (!this.#glyphs) {
|
|
26
|
-
// The engine's
|
|
27
|
-
this.#glyphs = new Glyphs(this.glyphsUrl,
|
|
21
|
+
// The engine's device: the atlas stays within its texture size limit
|
|
22
|
+
this.#glyphs = new Glyphs(this.glyphsUrl, this.maxSize());
|
|
28
23
|
this.#glyphs.attach(this.engine());
|
|
29
24
|
}
|
|
30
25
|
return this.#glyphs;
|
|
@@ -32,7 +27,7 @@ export class SymbolAtlases {
|
|
|
32
27
|
/** The icons of the symbol layers: the application's images and the vector basemaps' sprites */
|
|
33
28
|
get icons() {
|
|
34
29
|
if (!this.#icons) {
|
|
35
|
-
this.#icons = new Icons(
|
|
30
|
+
this.#icons = new Icons(this.maxSize());
|
|
36
31
|
this.#icons.attach(this.engine());
|
|
37
32
|
}
|
|
38
33
|
return this.#icons;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbol-atlases.js","sourceRoot":"","sources":["../../src/map/symbol-atlases.ts"],"names":[],"mappings":"AAAA,sHAAsH;AAEtH,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAkC,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGvF,
|
|
1
|
+
{"version":3,"file":"symbol-atlases.js","sourceRoot":"","sources":["../../src/map/symbol-atlases.ts"],"names":[],"mappings":"AAAA,sHAAsH;AAEtH,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAkC,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGvF,oCAAoC;AACpC,MAAM,OAAO,aAAa;IACP,OAAO,CAA2B;IAClC,SAAS,CAAqB;IAC9B,MAAM,CAAe;IACtC,OAAO,CAAqB;IAC5B,MAAM,CAAoB;IAE1B;wCACoC;IACpC,YAAY,OAAiC,EAAE,SAA6B,EAAE,MAAoB;QAChG,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,2DAA2D;IAC3D,IAAI,MAAM;QACR,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,qEAAqE;YACrE,IAAI,CAAC,OAAO,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1D,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,gGAAgG;IAChG,IAAI,KAAK;QACP,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACpC,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,0FAA0F;IAC1F,QAAQ,CACN,IAAY,EACZ,KAAuE,EACvE,OAAqB;QAErB,MAAM,MAAM,GAAG,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAE3D,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,gBAAgB,CAAC,CAAC;QACvE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,QAAQ,CAAC,IAAY;QACnB,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC;IACzC,CAAC;IAED,WAAW,CAAC,IAAY;QACtB,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,mHAAmH;IACnH,MAAM,CAAC,MAAc;QACnB,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;CACF","sourcesContent":["/** The atlases of a map's symbol layers, the glyphs and the icons: created on first use, moved to each new engine. */\n\nimport { Glyphs } from '../layers/glyphs.ts';\nimport { Icons, type ImageOptions, type Pixels, readPixels } from '../layers/icons.ts';\nimport type { Engine } from '../wasm/isard_webgpu.js';\n\n/** The glyphs and icons of a map */\nexport class SymbolAtlases {\n private readonly maxSize: () => number | undefined;\n private readonly glyphsUrl: string | undefined;\n private readonly engine: () => Engine;\n #glyphs: Glyphs | undefined;\n #icons: Icons | undefined;\n\n /** `maxSize`: the largest texture the engine takes (undefined if unknown); `glyphsUrl`: the map's option; `engine`:\n * the map's engine of the moment */\n constructor(maxSize: () => number | undefined, glyphsUrl: string | undefined, engine: () => Engine) {\n this.maxSize = maxSize;\n this.glyphsUrl = glyphsUrl;\n this.engine = engine;\n }\n\n /** The glyphs of the symbol layers, loaded on first use */\n get glyphs(): Glyphs {\n if (!this.#glyphs) {\n // The engine's device: the atlas stays within its texture size limit\n this.#glyphs = new Glyphs(this.glyphsUrl, this.maxSize());\n this.#glyphs.attach(this.engine());\n }\n\n return this.#glyphs;\n }\n\n /** The icons of the symbol layers: the application's images and the vector basemaps' sprites */\n get icons(): Icons {\n if (!this.#icons) {\n this.#icons = new Icons(this.maxSize());\n this.#icons.attach(this.engine());\n }\n\n return this.#icons;\n }\n\n /** An image for the icons, from its pixels or from an image; one without pixels throws */\n addImage(\n name: string,\n image: Pixels | (CanvasImageSource & { width: number; height: number }),\n options: ImageOptions,\n ): void {\n const pixels = 'data' in image ? image : readPixels(image);\n\n if (!pixels) throw new Error(`isard: the image ${name} has no pixels`);\n this.icons.add(name, pixels, options);\n }\n\n hasImage(name: string): boolean {\n return this.#icons?.has(name) ?? false;\n }\n\n removeImage(name: string): void {\n this.#icons?.remove(name);\n }\n\n /** Uploads the atlases made so far to a new engine (after a context loss, or the one left once the map is gone) */\n attach(engine: Engine): void {\n this.#glyphs?.attach(engine);\n this.#icons?.attach(engine);\n }\n}\n"]}
|
package/dist/map/viewshed.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The viewshed's observers given to the engine, in the arrays it reads. */
|
|
2
2
|
import type { ViewshedOptions } from '../types.ts';
|
|
3
|
-
import type { Engine } from '../wasm/
|
|
3
|
+
import type { Engine } from '../wasm/isard_webgpu.js';
|
|
4
4
|
/** Sets the viewshed of the engine, or clears it without observers; true if one is set (a frame to draw) */
|
|
5
5
|
export declare const applyViewshed: (engine: Engine, options: ViewshedOptions | readonly ViewshedOptions[] | undefined) => boolean;
|