@navaramap/three 0.0.0 → 0.0.1

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.
Files changed (33) hide show
  1. package/dist/assets/fontWorker-CCWL5pbx.js +2 -0
  2. package/dist/assets/fontWorker-CCWL5pbx.js.map +1 -0
  3. package/dist/assets/index-BdtHOOT9.js +12 -0
  4. package/dist/assets/index-BdtHOOT9.js.map +1 -0
  5. package/dist/assets/{navara_wasm_font_worker_bg-665OLxjy.wasm → navara_wasm_font_worker_bg-Bnck8OGf.wasm} +0 -0
  6. package/dist/assets/{navara_wasm_worker_bg-BXhKC5bE.wasm → navara_wasm_worker_bg-DG9ORAmj.wasm} +0 -0
  7. package/dist/index.d.ts +142 -51
  8. package/dist/index.js +4772 -4510
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.umd.cjs +226 -218
  11. package/dist/index.umd.cjs.map +1 -1
  12. package/package.json +13 -13
  13. package/src/event/context.ts +5 -0
  14. package/src/index.ts +10 -2
  15. package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/mutates.ts +6 -1
  16. package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/shader.ts +9 -2
  17. package/src/mesh/tile/drapeResolver.ts +76 -0
  18. package/src/mesh/{tile.test.ts → tile/index.test.ts} +16 -6
  19. package/src/mesh/{tile.ts → tile/index.ts} +124 -392
  20. package/src/mesh/tile/rasterDrapeResolver.ts +423 -0
  21. package/src/mesh/tile/vectorDrapeResolver.ts +404 -0
  22. package/src/tileTexture/TileTextureCache.test.ts +2 -0
  23. package/src/tileTexture/TileTextureCache.ts +1 -0
  24. package/src/tileTexture/TileTextureCompositor.test.ts +105 -0
  25. package/src/tileTexture/TileTextureCompositor.ts +241 -31
  26. package/src/tileTexture/__snapshots__/CompositeShader.snapshot.test.ts.snap +36 -16
  27. package/src/tileTexture/types.ts +7 -0
  28. package/src/utils/demNoDataColor.test.ts +47 -0
  29. package/src/utils/demNoDataColor.ts +48 -0
  30. package/dist/assets/fontWorker-CEJEfRpb.js +0 -2
  31. package/dist/assets/fontWorker-CEJEfRpb.js.map +0 -1
  32. package/dist/assets/index-BUB-ijMO.js +0 -12
  33. package/dist/assets/index-BUB-ijMO.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1791,6 +1791,12 @@ declare class Core {
1791
1791
  getMartini(martini_id: ReconstructableEntity): TransferableMartini | undefined;
1792
1792
  getMemoryStats(): MemoryStats_2 | undefined;
1793
1793
  getParentTile(handle: bigint): TransferableTile | undefined;
1794
+ /**
1795
+ * The WebMercator raster tiles to bake into per-layer drape render targets for a
1796
+ * terrain tile (baked layers only; empty on WebMercator terrain, which drapes 1:1
1797
+ * through the per-slot material path).
1798
+ */
1799
+ getRasterTileStates(handle: bigint): RasterTileState[];
1794
1800
  getTile(handle: bigint): TransferableTile | undefined;
1795
1801
  getTileElevationDecoder(handle: bigint): ElevationDecoder | undefined;
1796
1802
  getTransferablePolygonBatchedFeature(batched_feature_id: bigint): ReturnedTransferablePolygonBatchedFeature | undefined;
@@ -1813,6 +1819,12 @@ declare class Core {
1813
1819
  newBufferU8(byte_length: number, f: Function): number | undefined;
1814
1820
  newBufferU8Cloned(data: Uint8Array): number | undefined;
1815
1821
  newExternalBuffer(byte_length: number): number | undefined;
1822
+ /**
1823
+ * Monotonic revision that changes only when the raster drape resolution could have
1824
+ * changed. The web renderer reads it once per frame and skips the per-terrain-tile
1825
+ * `getRasterTileStates` calls while it is unchanged.
1826
+ */
1827
+ rasterRevision(): number;
1816
1828
  readAllBatchedProperties(renderable_feature_bits: bigint, callback: Function): void;
1817
1829
  readEvents(): Events | undefined;
1818
1830
  readFilteredBatchedProperties(renderable_feature_bits: bigint, keys: any[], callback: Function): void;
@@ -2376,7 +2388,7 @@ export declare type Descriptions = {
2376
2388
  * Why a tile's composite atlas needs to be re-rendered.
2377
2389
  * Aggregated per-handle so a single composite pass services multiple updates.
2378
2390
  */
2379
- declare type DirtyReason = "material" | "texture-binding" | "vector-revision" | "hillshade";
2391
+ declare type DirtyReason = "material" | "texture-binding" | "vector-revision" | "raster-revision" | "hillshade";
2380
2392
 
2381
2393
  export declare class DrapedMesh<TGeometry extends BufferGeometry = BufferGeometry<NormalBufferAttributes>, TMaterial extends Material | Material[] = Material | Material[], TEventMap extends Object3DEventMap = Object3DEventMap> extends Mesh_2<TGeometry, TMaterial, TEventMap> {
2382
2394
  drapedEnable: boolean;
@@ -2705,6 +2717,12 @@ declare class ElevationDecoder {
2705
2717
  declare type ElevationHeatmapCompositeLayer = CompositeLayerBase & {
2706
2718
  kind: "elevationHeatmap";
2707
2719
  opacity: number;
2720
+ /**
2721
+ * Same Mercator latitude reprojection band as {@link RasterCompositeLayer}:
2722
+ * the heatmap decode samples the reprojected per-slot UV, so a DEM draped on
2723
+ * Geographic terrain (baked or direct) remaps identically to color imagery.
2724
+ */
2725
+ reproject?: [number, number];
2708
2726
  };
2709
2727
 
2710
2728
  /**
@@ -3467,7 +3485,7 @@ export declare function getWGS84SemiMinorAxis(): number;
3467
3485
  * Provides an interface for accessing and modifying globe properties
3468
3486
  * that are shared across different material types (VectorTile, RasterTile, RasterTerrain).
3469
3487
  */
3470
- export declare class Globe implements Omit<RemoveFreeRecursively<Globe_2>, "elevationColormap" | "color"> {
3488
+ export declare class Globe implements Omit<RemoveFreeRecursively<Globe_2>, "elevationColormap" | "color" | "isGeographicTiling"> {
3471
3489
  private handler;
3472
3490
  private _elevationColormap?;
3473
3491
  constructor(handler: GlobeHandler, options?: GlobeOptions);
@@ -3515,6 +3533,14 @@ declare class Globe_2 {
3515
3533
  * Whether to hide underground geometry. Disabling this value might cause unexpected behavior when using effect.
3516
3534
  */
3517
3535
  hideUnderground: boolean;
3536
+ /**
3537
+ * Whether the globe tiles with the Geographic scheme (quantized-mesh
3538
+ * terrain) rather than the default WebMercator. Engine-set output — the
3539
+ * web renderer selects its raster drape pipeline (baked vs direct) from
3540
+ * it at tile-mesh creation; ignored on input (the scheme is dictated by
3541
+ * the terrain source, not configurable).
3542
+ */
3543
+ isGeographicTiling: boolean;
3518
3544
  /**
3519
3545
  * Screen-space error threshold for level of detail (LOD) calculations. Initialization only.
3520
3546
  */
@@ -3567,7 +3593,7 @@ declare type GlobeHandler = {
3567
3593
  setElevationColormap: (value: ColorMap) => void;
3568
3594
  };
3569
3595
 
3570
- declare type GlobeOptions = Partial<Omit<Globe_2, "constructor" | "free" | "elevationColormap" | "color">> & {
3596
+ declare type GlobeOptions = Partial<Omit<Globe_2, "constructor" | "free" | "elevationColormap" | "color" | "isGeographicTiling">> & {
3571
3597
  elevationColormap?: ColorMap;
3572
3598
  color?: Color_2;
3573
3599
  };
@@ -6949,6 +6975,30 @@ export declare function radianToDegree(radian: number): number;
6949
6975
 
6950
6976
  export declare const RAIN_ASSETS_URL: string;
6951
6977
 
6978
+ /** One baked raster layer: its overlapping WM tile textures, mosaicked into one
6979
+ * render target. Heatmap layers carry encoded DEM, copied raw (nearest, no
6980
+ * color conversion) so the composite decode stays valid. */
6981
+ declare type RasterBakeSlot = {
6982
+ isElevationHeatmap: boolean;
6983
+ /**
6984
+ * The decoder's no-data (boundary) color for heatmap slots: painted across
6985
+ * the render target before the sources so uncovered regions decode as
6986
+ * "no elevation" — the no-data story lives entirely in the encoded-elevation
6987
+ * domain, keeping the alpha channel free for future RGBA encodings. Absent
6988
+ * for color slots and for decoders with no byte-representable boundary.
6989
+ */
6990
+ noDataColor?: [number, number, number];
6991
+ sources: RasterBakeSource[];
6992
+ };
6993
+
6994
+ /** One WebMercator raster tile texture to bake into a layer's render target,
6995
+ * framed by the Rust-resolved mercator affine (terrain `[0,1]` UV → source UV). */
6996
+ declare type RasterBakeSource = {
6997
+ texture: Texture;
6998
+ uvOffset: [number, number];
6999
+ uvScale: [number, number];
7000
+ };
7001
+
6952
7002
  /** A sampled color layer — a raster tile or a texturized vector scene. */
6953
7003
  declare type RasterCompositeLayer = CompositeLayerBase & {
6954
7004
  kind: "raster";
@@ -7123,6 +7173,27 @@ declare class RasterTileSourceDescription {
7123
7173
  set url(value: string | null | undefined);
7124
7174
  }
7125
7175
 
7176
+ /**
7177
+ * One WebMercator raster tile to bake into a layer's drape render target (one per
7178
+ * overlapping WM tile per baked layer). `layer_ordinal` pairs the entry with the k-th
7179
+ * baked composite slot; `fragment_ind`/`fragment_gen` identify the loaded texture
7180
+ * fragment (the web derives its `loadedTexs` key, `${ind}_${gen}`, from them);
7181
+ * `uv_offset`/`uv_scale` place this tile into the terrain tile's `[0, 1]` UV for the
7182
+ * bake camera; `reproject_terrain_lat` is `[south, north]` (radians) on Geographic
7183
+ * terrain (Mercator reprojection) or empty on WebMercator terrain.
7184
+ */
7185
+ declare class RasterTileState {
7186
+ private constructor();
7187
+ free(): void;
7188
+ [Symbol.dispose](): void;
7189
+ fragment_gen: number;
7190
+ fragment_ind: number;
7191
+ layer_ordinal: number;
7192
+ reproject_terrain_lat: Float32Array;
7193
+ uv_offset: Float32Array;
7194
+ uv_scale: Float32Array;
7195
+ }
7196
+
7126
7197
  export declare type Ray = Required<NormalizeWASMClass<Ray_2>>;
7127
7198
 
7128
7199
  declare class Ray_2 {
@@ -8544,6 +8615,7 @@ declare class ThreeView<D extends Descriptions = EmptyDescriptions> extends Even
8544
8615
  private _buf;
8545
8616
  private _texFragment;
8546
8617
  private _vectorRevision;
8618
+ private _rasterRevision;
8547
8619
  private _tileHandler;
8548
8620
  private _globeHandler;
8549
8621
  private _workerTaskHandler;
@@ -9055,6 +9127,10 @@ declare type TileHandler = {
9055
9127
  getTileElevationDecoder: (handle: bigint) => ElevationDecoder | undefined;
9056
9128
  getVectorTileStates: (handle: bigint) => VectorTileState[] | undefined;
9057
9129
  vectorRevision: () => number;
9130
+ /** The WM raster tiles to bake into per-layer drape render targets for a
9131
+ * terrain tile (Geographic terrain only; empty on WebMercator terrain). */
9132
+ getRasterTileStates: (handle: bigint) => RasterTileState[] | undefined;
9133
+ rasterRevision: () => number;
9058
9134
  /** Reports a terrain tile's drape render-target GPU footprint (bytes) so the
9059
9135
  * memory ledger tracks clamp-to-ground vector bakes that scale with terrain
9060
9136
  * subdivision past the vector `maxZoom`. Pass 0 to release on dispose. */
@@ -9087,62 +9163,26 @@ export declare class TileMesh extends Mesh_2<BufferGeometry, TileMaterial, Custo
9087
9163
  maxTextures: number;
9088
9164
  texturizedSceneIndexFrom: number;
9089
9165
  numTexturizedVector: number;
9090
- private vectorSlots;
9091
- private prevVectorSignature;
9092
- private _lastVectorRevision;
9166
+ private readonly vectorDrape;
9167
+ private readonly rasterDrape;
9093
9168
  private shadowMesh?;
9094
- private texturizedSceneByTileCoordinates;
9095
9169
  private compositor;
9096
- texturizedSceneRenderTargets: WebGLRenderTarget[];
9097
9170
  private readonly drapeRtSize;
9098
9171
  private readonly atlasBytes;
9099
9172
  private reportedDrapeGpuBytes;
9100
- private warnedExceededTextures;
9101
9173
  readonly ctx: EventContext;
9102
9174
  constructor(ctx: EventContext, mesh: MeshAdded);
9103
9175
  /**
9104
- * Pull the Rust-resolved texturized-vector slots for this terrain tile into
9105
- * {@link vectorSlots}: one bake slot per clamp-to-ground layer, keyed by the
9106
- * rendered WM vector tile that backs it (ancestor fallback already resolved in
9107
- * Rust). Only layers with an actual draped scene take a slot — Rust also returns
9108
- * non-draped layers (rendered in the MRT scene), which must not consume the budget.
9109
- * Capped to the GPU slot budget; warns once when more draped layers are requested.
9110
- */
9111
- private refreshVectorSlots;
9112
- /**
9113
- * Size the drape render-target pool to the live slot count (already capped to
9114
- * `numTexturizedVector` by {@link refreshVectorSlots}): allocate the ones a
9115
- * newly-draped layer needs, dispose the ones a vanished layer freed. Then
9116
- * report the pool's GPU footprint to the memory ledger so it tracks drape
9117
- * memory that scales with terrain subdivision past the vector maxZoom — a cost
9118
- * per-vector-tile accounting cannot see. Reports only when the count changes.
9176
+ * Report the tile's drape GPU footprint (composite atlas + vector and baked-raster
9177
+ * drape render targets) to the memory ledger when it changed. The atlas is acquired
9178
+ * in the constructor and held for the tile's lifetime regardless of draping, so it
9179
+ * is always part of the report — otherwise a tile whose last draped layer vanished
9180
+ * would report 0 and wipe the atlas cost Rust seeds at mesh-attach time. The render
9181
+ * targets on top of it scale with terrain subdivision past the layers' maxZoom — a
9182
+ * cost per-source-tile accounting cannot see.
9119
9183
  */
9120
- private syncDrapeRenderTargets;
9121
- /**
9122
- * Identity of the current slot set + the backing scenes' content. A change means
9123
- * the offscreen scenes must be re-baked and the per-slot material state re-bound.
9124
- */
9125
- private vectorSignature;
9184
+ private reportDrapeGpuBytesIfChanged;
9126
9185
  private _onBeforeRender;
9127
- /**
9128
- * Drive each vector slot's main-shader state per frame: texture, per-slot UV
9129
- * transform, visibility and the draped mesh's material attributes. One slot per
9130
- * layer, sourced from the WM vector tile the Rust resolve picked. The resolve
9131
- * walks up to the nearest rendered tile (readiness derived from ECS activation
9132
- * / the Rust resolve, not a JS-side scene_ready flag), so the slot's scene is
9133
- * always bakeable (its own render target was framed by the bake) and the UV is
9134
- * identity — the ancestor LOD fallback lives entirely in Rust. Replaces the old
9135
- * scene-observer `updateTexturizedSceneTextureVisibility`.
9136
- */
9137
- private bindVectorSlots;
9138
- /**
9139
- * First available draped mesh backing any of a layer's sources. A clamp-to-ground
9140
- * layer's material attributes (water/specular/emissive/…) are uniform across its
9141
- * tiles, so any source's mesh is a faithful representative for the slot.
9142
- */
9143
- private representativeVectorMesh;
9144
- /** Copy a draped mesh's material attributes into the main shader's slot `lastIdx`. */
9145
- private copyVectorMeshAttrs;
9146
9186
  /**
9147
9187
  * Feature flags for the **main** TileMesh shader (atlas-sampling side): drives
9148
9188
  * its program cache key and which normal/specular branches compile. Sourced
@@ -9352,12 +9392,16 @@ declare class TileTextureCompositor {
9352
9392
  * per-tile GPU byte cost it reports to the memory ledger. */
9353
9393
  readonly size: number;
9354
9394
  private readonly texturizedScenes;
9355
- private readonly vectorCamera;
9395
+ private readonly bakeCamera;
9356
9396
  private readonly quadScene;
9357
9397
  private readonly quadCamera;
9358
9398
  private readonly quadMesh;
9359
9399
  private readonly materialCache;
9360
- private readonly touchedVectorTargets;
9400
+ private readonly touchedTargets;
9401
+ private readonly rasterBakeScene;
9402
+ private readonly rasterBakeMaterial;
9403
+ private demNoDataTexture;
9404
+ private demNoDataTextureKey;
9361
9405
  constructor(opts: TileTextureCompositorOptions);
9362
9406
  acquire(handle: TileHandle): CompositeOutputs;
9363
9407
  release(handle: TileHandle): void;
@@ -9390,6 +9434,53 @@ declare class TileTextureCompositor {
9390
9434
  uvScale: [number, number];
9391
9435
  }[];
9392
9436
  }[], renderTargets: WebGLRenderTarget[]): void;
9437
+ /**
9438
+ * Bake each raster layer's overlapping WM tile textures into ONE render
9439
+ * target (slot `i` → `renderTargets[i]`), mirroring {@link renderVectorScenes}:
9440
+ * every source is a textured quad framed by the Rust-supplied mercator affine
9441
+ * `uvOffset`/`uvScale`, so the render target ends up spanning the terrain
9442
+ * tile's (Mercator-projected) extent and the composite treats the whole layer
9443
+ * as one slot with the terrain-band reprojection — instead of one composite
9444
+ * slot per overlapping tile, which overflowed the GPU slot budget on
9445
+ * Geographic terrain once 3+ layers were draped.
9446
+ *
9447
+ * Sources are drawn coarse-first (ascending `uvScale`): an ancestor fallback
9448
+ * covers the whole terrain rect, so painting it first lets the finer tiles
9449
+ * overwrite it instead of being buried under coarse texels. The bake is a
9450
+ * value-preserving copy (`toneMapped: false`; per-kind color spaces below), so
9451
+ * heatmap DEM texels survive it bit-faithfully:
9452
+ * - color imagery: source + target declared sRGB — decode at fetch, encode at
9453
+ * write, decode again at the composite fetch: the same linear values the
9454
+ * direct (non-baked) path produced.
9455
+ * - elevation heatmap: everything `NoColorSpace` + nearest — raw texels, no
9456
+ * interpolation, so the composite's decode-then-interpolate keeps working.
9457
+ */
9458
+ renderRasterTiles(slots: (RasterBakeSlot | undefined)[], renderTargets: (WebGLRenderTarget | undefined)[]): void;
9459
+ /**
9460
+ * Shared bake loop over per-layer drape render targets (slot `i` →
9461
+ * `renderTargets[i]`): saves/restores the renderer state, clears each live
9462
+ * target once and lets `drawSlot` accumulate that slot's sources into it —
9463
+ * autoClear stays off so the sources mosaic instead of overwriting one
9464
+ * another.
9465
+ */
9466
+ private bakeSlotTargets;
9467
+ /**
9468
+ * Frame the shared bake camera on the terrain tile's sub-rect of a source
9469
+ * from the mercator affine: meshUv ∈ [0,1] → sourceUv = uvOffset +
9470
+ * meshUv·uvScale, source NDC = 2·sourceUv − 1. A source finer than the
9471
+ * terrain tile yields a camera wider than [-1, 1], so it draws into only
9472
+ * its sub-rect and leaves the rest of the render target transparent.
9473
+ */
9474
+ private frameBakeCamera;
9475
+ /** Draw one textured quad into the current render target through the bake
9476
+ * camera window — the value-preserving copy described on
9477
+ * {@link renderRasterTiles}. */
9478
+ private drawRasterBakeQuad;
9479
+ /** The cached 1×1 no-data texture, (re)created when the color changes. */
9480
+ private demNoDataUnderlay;
9481
+ /** Value-preserving sampler settings for a bake source texture (see
9482
+ * {@link renderRasterTiles}); idempotent so re-bakes don't re-upload. */
9483
+ private configureRasterBakeSource;
9393
9484
  /**
9394
9485
  * Run the composite MRT pass for a handle if (and only if) its atlas is
9395
9486
  * dirty. Consumes the dirty flags on success so the next frame skips work