@codexo/exojs-tilemap 0.13.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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +187 -0
  3. package/dist/esm/TileChunk.d.ts +136 -0
  4. package/dist/esm/TileChunk.js +192 -0
  5. package/dist/esm/TileChunk.js.map +1 -0
  6. package/dist/esm/TileChunkNode.d.ts +59 -0
  7. package/dist/esm/TileChunkNode.js +89 -0
  8. package/dist/esm/TileChunkNode.js.map +1 -0
  9. package/dist/esm/TileLayer.d.ts +229 -0
  10. package/dist/esm/TileLayer.js +450 -0
  11. package/dist/esm/TileLayer.js.map +1 -0
  12. package/dist/esm/TileLayerNode.d.ts +81 -0
  13. package/dist/esm/TileLayerNode.js +142 -0
  14. package/dist/esm/TileLayerNode.js.map +1 -0
  15. package/dist/esm/TileMap.d.ts +178 -0
  16. package/dist/esm/TileMap.js +262 -0
  17. package/dist/esm/TileMap.js.map +1 -0
  18. package/dist/esm/TileMapBand.d.ts +97 -0
  19. package/dist/esm/TileMapBand.js +161 -0
  20. package/dist/esm/TileMapBand.js.map +1 -0
  21. package/dist/esm/TileMapNode.d.ts +71 -0
  22. package/dist/esm/TileMapNode.js +113 -0
  23. package/dist/esm/TileMapNode.js.map +1 -0
  24. package/dist/esm/TileMapView.d.ts +182 -0
  25. package/dist/esm/TileMapView.js +342 -0
  26. package/dist/esm/TileMapView.js.map +1 -0
  27. package/dist/esm/TileSet.d.ts +99 -0
  28. package/dist/esm/TileSet.js +157 -0
  29. package/dist/esm/TileSet.js.map +1 -0
  30. package/dist/esm/chunkGeometry.d.ts +71 -0
  31. package/dist/esm/chunkGeometry.js +98 -0
  32. package/dist/esm/chunkGeometry.js.map +1 -0
  33. package/dist/esm/index.d.ts +1 -0
  34. package/dist/esm/index.js +10 -0
  35. package/dist/esm/index.js.map +1 -0
  36. package/dist/esm/pixelSnap.d.ts +12 -0
  37. package/dist/esm/pixelSnap.js +19 -0
  38. package/dist/esm/pixelSnap.js.map +1 -0
  39. package/dist/esm/public.d.ts +18 -0
  40. package/dist/esm/register.d.ts +1 -0
  41. package/dist/esm/register.js +20 -0
  42. package/dist/esm/register.js.map +1 -0
  43. package/dist/esm/tilemapExtension.d.ts +18 -0
  44. package/dist/esm/tilemapExtension.js +52 -0
  45. package/dist/esm/tilemapExtension.js.map +1 -0
  46. package/dist/esm/types.d.ts +139 -0
  47. package/dist/esm/types.js +121 -0
  48. package/dist/esm/types.js.map +1 -0
  49. package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts +39 -0
  50. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js +339 -0
  51. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js.map +1 -0
  52. package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts +42 -0
  53. package/dist/esm/webgpu/WebGpuTileChunkRenderer.js +390 -0
  54. package/dist/esm/webgpu/WebGpuTileChunkRenderer.js.map +1 -0
  55. package/package.json +48 -0
@@ -0,0 +1,450 @@
1
+ import { TileChunk } from './TileChunk.js';
2
+ import { validateNonNegativeInteger, validatePositiveInteger, validateInteger, tileToChunkCoord, tileToLocalInChunk, packTile, unpackTile } from './types.js';
3
+
4
+ const DEFAULT_CHUNK_SIZE = 32;
5
+ /**
6
+ * A generic, format-independent tile layer with chunk-first storage.
7
+ *
8
+ * Tile data is stored in fixed-size {@link TileChunk}s indexed by signed
9
+ * chunk coordinates. For finite maps, only chunks that intersect the layer
10
+ * bounds exist.
11
+ *
12
+ * **Mutation must go through the layer's public APIs only.**
13
+ * `setTileAt` / `clearTileAt` validate coordinates, tileset references,
14
+ * and increment revision counters only when the stored value actually
15
+ * changes. Direct chunk mutation is not supported — the layer owns chunk
16
+ * storage and exposes only a {@link ReadonlyTileChunk} view.
17
+ *
18
+ * The layer is NOT a SceneNode — that integration lives in the future
19
+ * renderer slice.
20
+ *
21
+ * @advanced
22
+ */
23
+ class TileLayer {
24
+ /** Stable unique ID within the map. */
25
+ id;
26
+ /** Display name (may not be unique). */
27
+ name;
28
+ /** Width in tiles. */
29
+ width;
30
+ /** Height in tiles. */
31
+ height;
32
+ /** Chunk width (tiles). */
33
+ chunkWidth;
34
+ /** Chunk height (tiles). */
35
+ chunkHeight;
36
+ /** Tile width in pixels. */
37
+ tileWidth;
38
+ /** Tile height in pixels. */
39
+ tileHeight;
40
+ /** Pixel width. */
41
+ get pixelWidth() { return this.width * this.tileWidth; }
42
+ /** Pixel height. */
43
+ get pixelHeight() { return this.height * this.tileHeight; }
44
+ /** Visibility flag (mutable). */
45
+ visible;
46
+ /** Opacity 0..1 (mutable). */
47
+ opacity;
48
+ /** Horizontal pixel offset (mutable). */
49
+ offsetX;
50
+ /** Vertical pixel offset (mutable). */
51
+ offsetY;
52
+ /** Immutable layer properties. */
53
+ properties;
54
+ /** The tilesets available to this layer (shared array reference). */
55
+ tilesets;
56
+ /** Chunk storage: chunkKey → mutable TileChunk (internal). */
57
+ _chunks = new Map();
58
+ /**
59
+ * Monotonic layer revision counter.
60
+ * Increments on every cell mutation that actually changes a stored value.
61
+ * Does NOT increment on no-op writes or failed mutations.
62
+ */
63
+ _revision = 0;
64
+ /** Whether the layer has been destroyed. */
65
+ _destroyed = false;
66
+ /**
67
+ * @throws When dimensions, chunk size, or other options are invalid.
68
+ */
69
+ constructor(options) {
70
+ validateNonNegativeInteger(options.id, 'layer.id');
71
+ if (!options.name || typeof options.name !== 'string') {
72
+ throw new Error('TileLayer name must be a non-empty string.');
73
+ }
74
+ validatePositiveInteger(options.width, 'layer.width');
75
+ validatePositiveInteger(options.height, 'layer.height');
76
+ validatePositiveInteger(options.tileWidth, 'layer.tileWidth');
77
+ validatePositiveInteger(options.tileHeight, 'layer.tileHeight');
78
+ const chunkWidth = options.chunkWidth ?? DEFAULT_CHUNK_SIZE;
79
+ const chunkHeight = options.chunkHeight ?? DEFAULT_CHUNK_SIZE;
80
+ validatePositiveInteger(chunkWidth, 'chunkWidth');
81
+ validatePositiveInteger(chunkHeight, 'chunkHeight');
82
+ if (!Array.isArray(options.tilesets)) {
83
+ throw new Error('TileLayer tilesets must be an array.');
84
+ }
85
+ const opacity = options.opacity ?? 1;
86
+ if (typeof opacity !== 'number' || opacity < 0 || opacity > 1) {
87
+ throw new Error(`TileLayer opacity must be 0..1 (got ${opacity}).`);
88
+ }
89
+ const offsetX = options.offsetX ?? 0;
90
+ const offsetY = options.offsetY ?? 0;
91
+ if (!Number.isFinite(offsetX) || !Number.isFinite(offsetY)) {
92
+ throw new Error('TileLayer offset must be finite numbers.');
93
+ }
94
+ this.id = options.id;
95
+ this.name = options.name;
96
+ this.width = options.width;
97
+ this.height = options.height;
98
+ this.chunkWidth = chunkWidth;
99
+ this.chunkHeight = chunkHeight;
100
+ this.tileWidth = options.tileWidth;
101
+ this.tileHeight = options.tileHeight;
102
+ this.tilesets = options.tilesets;
103
+ this.visible = options.visible ?? true;
104
+ this.opacity = opacity;
105
+ this.offsetX = offsetX;
106
+ this.offsetY = offsetY;
107
+ this.properties = options.properties
108
+ ? Object.freeze({ ...options.properties })
109
+ : Object.freeze({});
110
+ }
111
+ // ── Bounds helpers ────────────────────────────────────────────────────
112
+ /**
113
+ * Check whether a tile coordinate lies within the layer bounds.
114
+ * @advanced
115
+ */
116
+ inBounds(tx, ty) {
117
+ return tx >= 0 && tx < this.width && ty >= 0 && ty < this.height;
118
+ }
119
+ /** Compute the range of chunk coordinates that intersect this layer. */
120
+ chunkRange() {
121
+ return {
122
+ minCx: 0,
123
+ minCy: 0,
124
+ maxCx: Math.floor((this.width - 1) / this.chunkWidth),
125
+ maxCy: Math.floor((this.height - 1) / this.chunkHeight),
126
+ };
127
+ }
128
+ // ── Chunk keying ──────────────────────────────────────────────────────
129
+ _chunkKey(cx, cy) {
130
+ return `${cx},${cy}`;
131
+ }
132
+ /**
133
+ * Get a readonly view of a chunk by signed chunk coordinates,
134
+ * or undefined if it does not exist (never been touched).
135
+ * @advanced
136
+ */
137
+ getChunk(cx, cy) {
138
+ return this._chunks.get(this._chunkKey(cx, cy));
139
+ }
140
+ /**
141
+ * Get or create a chunk at the given coordinates.
142
+ * For finite layers, creation is only allowed within the valid chunk range.
143
+ *
144
+ * @internal Package-private: used by {@link setTileAt}, {@link fillRect},
145
+ * and future adapter ingest. External users should not allocate
146
+ * chunks — use {@link setTileAt} to populate tiles.
147
+ */
148
+ _ensureChunk(cx, cy) {
149
+ this._checkDestroyed();
150
+ const key = this._chunkKey(cx, cy);
151
+ let chunk = this._chunks.get(key);
152
+ if (!chunk) {
153
+ const range = this.chunkRange();
154
+ if (cx < range.minCx || cx > range.maxCx || cy < range.minCy || cy > range.maxCy) {
155
+ throw new Error(`Chunk (${cx}, ${cy}) outside layer chunk range ` +
156
+ `[${range.minCx}..${range.maxCx}, ${range.minCy}..${range.maxCy}].`);
157
+ }
158
+ // Compute the actual tile dimensions for this chunk (edge chunks may be smaller).
159
+ const startTx = cx * this.chunkWidth;
160
+ const startTy = cy * this.chunkHeight;
161
+ const cw = Math.min(this.chunkWidth, this.width - startTx);
162
+ const ch = Math.min(this.chunkHeight, this.height - startTy);
163
+ chunk = new TileChunk(cx, cy, cw, ch);
164
+ this._chunks.set(key, chunk);
165
+ }
166
+ return chunk;
167
+ }
168
+ /**
169
+ * Iterate over all loaded chunks in deterministic (cy, cx) ascending order.
170
+ * Returns readonly chunk views — callers cannot mutate storage.
171
+ * @advanced
172
+ */
173
+ loadedChunks() {
174
+ const entries = [...this._chunks.values()];
175
+ entries.sort((a, b) => a.cy - b.cy || a.cx - b.cx);
176
+ return entries[Symbol.iterator]();
177
+ }
178
+ // ── Tile queries ──────────────────────────────────────────────────────
179
+ /**
180
+ * Get the raw packed tile word at (tx, ty). Returns 0 for empty or out-of-bounds.
181
+ * @advanced
182
+ */
183
+ getRawTileAt(tx, ty) {
184
+ validateInteger(tx, 'tx');
185
+ validateInteger(ty, 'ty');
186
+ if (!this.inBounds(tx, ty))
187
+ return 0;
188
+ const { cx, cy } = tileToChunkCoord(tx, ty, this.chunkWidth, this.chunkHeight);
189
+ const chunk = this._chunks.get(this._chunkKey(cx, cy));
190
+ if (!chunk)
191
+ return 0;
192
+ const { lx, ly } = tileToLocalInChunk(tx, ty, this.chunkWidth, this.chunkHeight);
193
+ return chunk.getRawAt(lx, ly);
194
+ }
195
+ /**
196
+ * Query a resolved tile at (tx, ty). Returns null for empty or out-of-bounds.
197
+ * @advanced
198
+ */
199
+ getTileAt(tx, ty) {
200
+ const packed = this.getRawTileAt(tx, ty);
201
+ if (packed === 0)
202
+ return null;
203
+ const decoded = unpackTile(packed);
204
+ if (!decoded)
205
+ return null;
206
+ if (decoded.tilesetIndex >= this.tilesets.length)
207
+ return null;
208
+ const tileset = this.tilesets[decoded.tilesetIndex];
209
+ if (decoded.localTileId >= tileset.tileCount)
210
+ return null;
211
+ return {
212
+ tileset,
213
+ localTileId: decoded.localTileId,
214
+ transform: decoded.transform,
215
+ };
216
+ }
217
+ // ── Mutation ──────────────────────────────────────────────────────────
218
+ /**
219
+ * Validate a tile reference against the layer's tilesets.
220
+ * Returns the packed form or throws.
221
+ */
222
+ _validateTileRef(tile) {
223
+ if (!tile?.tileset) {
224
+ throw new Error('setTileAt requires a valid ResolvedTile.');
225
+ }
226
+ const tilesetIndex = this.tilesets.indexOf(tile.tileset);
227
+ if (tilesetIndex === -1) {
228
+ throw new Error(`Tileset "${tile.tileset.name}" is not available to layer "${this.name}".`);
229
+ }
230
+ if (tile.localTileId < 0 || tile.localTileId >= tile.tileset.tileCount) {
231
+ throw new Error(`localTileId ${tile.localTileId} out of range for tileset "${tile.tileset.name}" ` +
232
+ `(max ${tile.tileset.tileCount - 1}).`);
233
+ }
234
+ return packTile(tilesetIndex, tile.localTileId, tile.transform);
235
+ }
236
+ /**
237
+ * Set a tile at the given tile coordinates.
238
+ * No-op if the effective value is unchanged.
239
+ * @throws If coordinates are out of bounds or the tile reference is invalid.
240
+ * @advanced
241
+ */
242
+ setTileAt(tx, ty, tile) {
243
+ this._checkDestroyed();
244
+ validateInteger(tx, 'tx');
245
+ validateInteger(ty, 'ty');
246
+ if (!this.inBounds(tx, ty)) {
247
+ throw new Error(`setTileAt (${tx}, ${ty}) out of bounds [0..${this.width - 1}, 0..${this.height - 1}].`);
248
+ }
249
+ const packed = this._validateTileRef(tile);
250
+ const { cx, cy } = tileToChunkCoord(tx, ty, this.chunkWidth, this.chunkHeight);
251
+ const chunk = this._ensureChunk(cx, cy);
252
+ const { lx, ly } = tileToLocalInChunk(tx, ty, this.chunkWidth, this.chunkHeight);
253
+ if (chunk._setRawAt(lx, ly, packed)) {
254
+ this._revision++;
255
+ }
256
+ }
257
+ /**
258
+ * Clear (erase) the tile at the given coordinates.
259
+ * No-op if the cell is already empty.
260
+ * @throws If coordinates are out of bounds.
261
+ * @advanced
262
+ */
263
+ clearTileAt(tx, ty) {
264
+ this._checkDestroyed();
265
+ validateInteger(tx, 'tx');
266
+ validateInteger(ty, 'ty');
267
+ if (!this.inBounds(tx, ty)) {
268
+ throw new Error(`clearTileAt (${tx}, ${ty}) out of bounds [0..${this.width - 1}, 0..${this.height - 1}].`);
269
+ }
270
+ const { cx, cy } = tileToChunkCoord(tx, ty, this.chunkWidth, this.chunkHeight);
271
+ const chunk = this._chunks.get(this._chunkKey(cx, cy));
272
+ if (!chunk)
273
+ return; // no chunk = already empty
274
+ const { lx, ly } = tileToLocalInChunk(tx, ty, this.chunkWidth, this.chunkHeight);
275
+ if (chunk._setRawAt(lx, ly, 0)) {
276
+ this._revision++;
277
+ }
278
+ }
279
+ // ── Bulk fill ─────────────────────────────────────────────────────────
280
+ /**
281
+ * Fill a rectangular region with a tile.
282
+ * @advanced
283
+ */
284
+ fillRect(x, y, w, h, tile) {
285
+ this._checkDestroyed();
286
+ const packed = this._validateTileRef(tile);
287
+ let changed = false;
288
+ for (let ty = y; ty < y + h; ty++) {
289
+ for (let tx = x; tx < x + w; tx++) {
290
+ if (!this.inBounds(tx, ty))
291
+ continue;
292
+ const { cx, cy } = tileToChunkCoord(tx, ty, this.chunkWidth, this.chunkHeight);
293
+ const chunk = this._ensureChunk(cx, cy);
294
+ const { lx, ly } = tileToLocalInChunk(tx, ty, this.chunkWidth, this.chunkHeight);
295
+ if (chunk._setRawAt(lx, ly, packed)) {
296
+ changed = true;
297
+ }
298
+ }
299
+ }
300
+ if (changed)
301
+ this._revision++;
302
+ }
303
+ /**
304
+ * Clear a rectangular region.
305
+ * @advanced
306
+ */
307
+ clearRect(x, y, w, h) {
308
+ this._checkDestroyed();
309
+ let changed = false;
310
+ for (let ty = y; ty < y + h; ty++) {
311
+ for (let tx = x; tx < x + w; tx++) {
312
+ if (!this.inBounds(tx, ty))
313
+ continue;
314
+ const { cx, cy } = tileToChunkCoord(tx, ty, this.chunkWidth, this.chunkHeight);
315
+ const chunk = this._chunks.get(this._chunkKey(cx, cy));
316
+ if (!chunk)
317
+ continue;
318
+ const { lx, ly } = tileToLocalInChunk(tx, ty, this.chunkWidth, this.chunkHeight);
319
+ if (chunk._setRawAt(lx, ly, 0)) {
320
+ changed = true;
321
+ }
322
+ }
323
+ }
324
+ if (changed)
325
+ this._revision++;
326
+ }
327
+ // ── Iteration ─────────────────────────────────────────────────────────
328
+ /**
329
+ * Iterate non-empty tiles within a rectangular region in row-major order.
330
+ * Yields (tx, ty, resolvedTile) tuples. Skips empty cells.
331
+ * @advanced
332
+ */
333
+ *tilesInRect(x, y, w, h) {
334
+ const startCx = Math.floor(x / this.chunkWidth);
335
+ const endCx = Math.floor((x + w - 1) / this.chunkWidth);
336
+ const startCy = Math.floor(y / this.chunkHeight);
337
+ const endCy = Math.floor((y + h - 1) / this.chunkHeight);
338
+ for (let cy = startCy; cy <= endCy; cy++) {
339
+ for (let cx = startCx; cx <= endCx; cx++) {
340
+ const chunk = this._chunks.get(this._chunkKey(cx, cy));
341
+ if (!chunk || chunk.empty)
342
+ continue;
343
+ const chunkStartTx = cx * this.chunkWidth;
344
+ const chunkStartTy = cy * this.chunkHeight;
345
+ const minLx = Math.max(0, x - chunkStartTx);
346
+ const maxLx = Math.min(chunk.width - 1, (x + w - 1) - chunkStartTx);
347
+ const minLy = Math.max(0, y - chunkStartTy);
348
+ const maxLy = Math.min(chunk.height - 1, (y + h - 1) - chunkStartTy);
349
+ for (let ly = minLy; ly <= maxLy; ly++) {
350
+ for (let lx = minLx; lx <= maxLx; lx++) {
351
+ const packed = chunk.getRawAt(lx, ly);
352
+ if (packed === 0)
353
+ continue;
354
+ const decoded = unpackTile(packed);
355
+ if (!decoded)
356
+ continue;
357
+ if (decoded.tilesetIndex >= this.tilesets.length)
358
+ continue;
359
+ const tileset = this.tilesets[decoded.tilesetIndex];
360
+ if (decoded.localTileId >= tileset.tileCount)
361
+ continue;
362
+ yield {
363
+ tx: chunkStartTx + lx,
364
+ ty: chunkStartTy + ly,
365
+ tile: {
366
+ tileset,
367
+ localTileId: decoded.localTileId,
368
+ transform: decoded.transform,
369
+ },
370
+ };
371
+ }
372
+ }
373
+ }
374
+ }
375
+ }
376
+ // ── Coordinate conversion ─────────────────────────────────────────────
377
+ /**
378
+ * Convert a tile coordinate to the pixel position of its top-left corner
379
+ * in the layer's local space.
380
+ * @advanced
381
+ */
382
+ tileToPixel(tx, ty) {
383
+ return {
384
+ x: tx * this.tileWidth + this.offsetX,
385
+ y: ty * this.tileHeight + this.offsetY,
386
+ };
387
+ }
388
+ /**
389
+ * Convert a local pixel position to the tile coordinate that contains it.
390
+ * Uses `floor`, so a point exactly on a tile boundary maps to the tile.
391
+ * May return coordinates outside layer bounds.
392
+ * @advanced
393
+ */
394
+ pixelToTile(px, py) {
395
+ return {
396
+ tx: Math.floor((px - this.offsetX) / this.tileWidth),
397
+ ty: Math.floor((py - this.offsetY) / this.tileHeight),
398
+ };
399
+ }
400
+ // ── Revision / lifecycle ──────────────────────────────────────────────
401
+ /**
402
+ * Monotonic layer revision counter.
403
+ * Increments on every cell mutation that changes a stored value.
404
+ * No-op writes and failed mutations do NOT increment.
405
+ * @advanced
406
+ */
407
+ get revision() {
408
+ return this._revision;
409
+ }
410
+ /** Whether the layer has been destroyed. */
411
+ get destroyed() {
412
+ return this._destroyed;
413
+ }
414
+ _checkDestroyed() {
415
+ if (this._destroyed) {
416
+ throw new Error(`TileLayer "${this.name}" has been destroyed.`);
417
+ }
418
+ }
419
+ /**
420
+ * Destroy this layer: clear chunk storage and mark destroyed.
421
+ * Does NOT destroy tileset textures or external resources.
422
+ * Idempotent.
423
+ */
424
+ destroy() {
425
+ if (this._destroyed)
426
+ return;
427
+ this._destroyed = true;
428
+ this._chunks.clear();
429
+ }
430
+ /**
431
+ * Total number of non-empty tiles across all chunks.
432
+ * Walk is cheap for dense layers; sparse layers benefit from empty-chunk fast path.
433
+ * @advanced
434
+ */
435
+ countNonEmptyTiles() {
436
+ let count = 0;
437
+ for (const chunk of this._chunks.values()) {
438
+ for (let ly = 0; ly < chunk.height; ly++) {
439
+ for (let lx = 0; lx < chunk.width; lx++) {
440
+ if (chunk.getRawAt(lx, ly) !== 0)
441
+ count++;
442
+ }
443
+ }
444
+ }
445
+ return count;
446
+ }
447
+ }
448
+
449
+ export { TileLayer };
450
+ //# sourceMappingURL=TileLayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TileLayer.js","sources":["../../../src/TileLayer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { Rectangle } from '@codexo/exojs';
2
+ import { Container } from '@codexo/exojs';
3
+ import type { PixelSnapMode, RenderPlanBuilder } from '@codexo/exojs/rendering';
4
+ import { TileChunkNode } from './TileChunkNode';
5
+ import type { TileLayer } from './TileLayer';
6
+ /**
7
+ * Options for a {@link TileLayerNode}. All optional; reserved for forward
8
+ * compatibility.
9
+ * @advanced
10
+ */
11
+ export interface TileLayerNodeOptions {
12
+ /**
13
+ * Whether the layer's chunk nodes participate in per-chunk view culling.
14
+ * Defaults to `true`. Disable only for tiny, always-on-screen layers where
15
+ * the per-chunk bounds test is pure overhead.
16
+ */
17
+ readonly cullable?: boolean;
18
+ }
19
+ /**
20
+ * A scene node that renders one generic {@link TileLayer} as a
21
+ * {@link Container} of per-chunk {@link TileChunkNode} drawables.
22
+ *
23
+ * Each non-empty loaded chunk becomes one child positioned at its pixel
24
+ * origin, so the engine's existing per-node culling drops individual chunks and
25
+ * the render-plan optimiser batches them by tileset texture. The layer's pixel
26
+ * `offset` is applied to this node's transform; `visible` and `opacity` are
27
+ * read live from the runtime layer on every frame (no rebuild required).
28
+ *
29
+ * The node references — but never owns — the {@link TileLayer}: destroying it
30
+ * frees its chunk nodes and their cached geometry but leaves the layer, map,
31
+ * and Loader-owned textures intact.
32
+ *
33
+ * Structural changes to the layer (tiles written into previously-empty chunks)
34
+ * are reflected only after {@link TileLayerNode.refresh}; in-place edits to
35
+ * existing chunks are picked up automatically via chunk revisions.
36
+ *
37
+ * @advanced
38
+ */
39
+ export declare class TileLayerNode extends Container {
40
+ private readonly _layer;
41
+ private readonly _cullChunks;
42
+ private readonly _chunkNodes;
43
+ private _syncedOpacity;
44
+ private _pixelSnapMode;
45
+ constructor(layer: TileLayer, options?: TileLayerNodeOptions);
46
+ /** The runtime layer this node renders. */
47
+ get layer(): TileLayer;
48
+ /**
49
+ * Render-only pixel-snap mode applied to every chunk node in this layer (and
50
+ * to chunks rebuilt later by {@link refresh}). Each chunk's rendered origin is
51
+ * snapped to the active render target's device-pixel grid; because chunk
52
+ * origins are integer multiples of the integer tile pitch from the same layer
53
+ * origin, the whole grid stays exact and adjacent chunks cannot drift apart.
54
+ *
55
+ * Purely visual: tile data, the layer offset, chunk content revisions, and
56
+ * culling bounds are never changed. `'geometry'` and `'position'` both resolve
57
+ * to coherent origin snapping for tile chunks (chunk quads are already on the
58
+ * integer pixel grid by construction). Setting the current value is a no-op;
59
+ * an invalid value throws and leaves the prior mode unchanged.
60
+ *
61
+ * @default 'none'
62
+ * @stable
63
+ */
64
+ get pixelSnapMode(): PixelSnapMode;
65
+ set pixelSnapMode(mode: PixelSnapMode);
66
+ /**
67
+ * Rebuild the chunk-node children from the layer's current loaded chunks.
68
+ * Call after structural mutation that creates or empties chunks. In-place
69
+ * tile edits to existing chunks do not need a refresh.
70
+ */
71
+ refresh(): this;
72
+ /** The chunk render nodes owned by this layer node, in build order. @internal */
73
+ get chunkNodes(): readonly TileChunkNode[];
74
+ getLocalBounds(): Rectangle;
75
+ /** @internal */
76
+ protected _collectContent(builder: RenderPlanBuilder): void;
77
+ destroy(): void;
78
+ private _buildChunkNodes;
79
+ /** Propagate the layer's live opacity onto the chunk tints if it changed. */
80
+ private _syncOpacity;
81
+ }