@codexo/exojs-tilemap 0.15.2 → 0.16.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 (151) hide show
  1. package/README.md +33 -26
  2. package/dist/esm/ChunkSource.d.ts +33 -0
  3. package/dist/esm/ChunkSource.d.ts.map +1 -0
  4. package/dist/esm/ChunkStreamer.d.ts +98 -0
  5. package/dist/esm/ChunkStreamer.d.ts.map +1 -0
  6. package/dist/esm/ChunkStreamer.js +201 -0
  7. package/dist/esm/ChunkStreamer.js.map +1 -0
  8. package/dist/esm/ImageLayer.d.ts +11 -3
  9. package/dist/esm/ImageLayer.d.ts.map +1 -0
  10. package/dist/esm/ImageLayer.js +71 -64
  11. package/dist/esm/ImageLayer.js.map +1 -1
  12. package/dist/esm/ImageLayerNode.d.ts +89 -0
  13. package/dist/esm/ImageLayerNode.d.ts.map +1 -0
  14. package/dist/esm/ImageLayerNode.js +205 -0
  15. package/dist/esm/ImageLayerNode.js.map +1 -0
  16. package/dist/esm/MapObject.d.ts +70 -0
  17. package/dist/esm/MapObject.d.ts.map +1 -0
  18. package/dist/esm/MapObject.js +34 -0
  19. package/dist/esm/MapObject.js.map +1 -0
  20. package/dist/esm/MapObjectSpawner.d.ts +133 -0
  21. package/dist/esm/MapObjectSpawner.d.ts.map +1 -0
  22. package/dist/esm/MapObjectSpawner.js +147 -0
  23. package/dist/esm/MapObjectSpawner.js.map +1 -0
  24. package/dist/esm/MapSpawnSession.d.ts +53 -0
  25. package/dist/esm/MapSpawnSession.d.ts.map +1 -0
  26. package/dist/esm/MapSpawnSession.js +88 -0
  27. package/dist/esm/MapSpawnSession.js.map +1 -0
  28. package/dist/esm/MapWorld.d.ts +134 -0
  29. package/dist/esm/MapWorld.d.ts.map +1 -0
  30. package/dist/esm/MapWorld.js +150 -0
  31. package/dist/esm/MapWorld.js.map +1 -0
  32. package/dist/esm/MapWorldRuntime.d.ts +182 -0
  33. package/dist/esm/MapWorldRuntime.d.ts.map +1 -0
  34. package/dist/esm/MapWorldRuntime.js +261 -0
  35. package/dist/esm/MapWorldRuntime.js.map +1 -0
  36. package/dist/esm/ObjectLayer.d.ts +93 -7
  37. package/dist/esm/ObjectLayer.d.ts.map +1 -0
  38. package/dist/esm/ObjectLayer.js +184 -167
  39. package/dist/esm/ObjectLayer.js.map +1 -1
  40. package/dist/esm/SampledChunkSource.d.ts +43 -0
  41. package/dist/esm/SampledChunkSource.d.ts.map +1 -0
  42. package/dist/esm/SampledChunkSource.js +48 -0
  43. package/dist/esm/SampledChunkSource.js.map +1 -0
  44. package/dist/esm/TileAnimator.d.ts +12 -2
  45. package/dist/esm/TileAnimator.d.ts.map +1 -0
  46. package/dist/esm/TileAnimator.js +154 -165
  47. package/dist/esm/TileAnimator.js.map +1 -1
  48. package/dist/esm/TileChunk.d.ts +30 -5
  49. package/dist/esm/TileChunk.d.ts.map +1 -0
  50. package/dist/esm/TileChunk.js +190 -188
  51. package/dist/esm/TileChunk.js.map +1 -1
  52. package/dist/esm/TileChunkNode.d.ts +18 -3
  53. package/dist/esm/TileChunkNode.d.ts.map +1 -0
  54. package/dist/esm/TileChunkNode.js +104 -85
  55. package/dist/esm/TileChunkNode.js.map +1 -1
  56. package/dist/esm/TileLayer.d.ts +104 -24
  57. package/dist/esm/TileLayer.d.ts.map +1 -0
  58. package/dist/esm/TileLayer.js +511 -469
  59. package/dist/esm/TileLayer.js.map +1 -1
  60. package/dist/esm/TileLayerNode.d.ts +52 -11
  61. package/dist/esm/TileLayerNode.d.ts.map +1 -0
  62. package/dist/esm/TileLayerNode.js +224 -166
  63. package/dist/esm/TileLayerNode.js.map +1 -1
  64. package/dist/esm/TileMap.d.ts +96 -31
  65. package/dist/esm/TileMap.d.ts.map +1 -0
  66. package/dist/esm/TileMap.js +401 -357
  67. package/dist/esm/TileMap.js.map +1 -1
  68. package/dist/esm/TileMapBand.d.ts +42 -29
  69. package/dist/esm/TileMapBand.d.ts.map +1 -0
  70. package/dist/esm/TileMapBand.js +151 -158
  71. package/dist/esm/TileMapBand.js.map +1 -1
  72. package/dist/esm/TileMapNode.d.ts +34 -18
  73. package/dist/esm/TileMapNode.d.ts.map +1 -0
  74. package/dist/esm/TileMapNode.js +122 -109
  75. package/dist/esm/TileMapNode.js.map +1 -1
  76. package/dist/esm/TileMapView.d.ts +108 -47
  77. package/dist/esm/TileMapView.d.ts.map +1 -0
  78. package/dist/esm/TileMapView.js +385 -338
  79. package/dist/esm/TileMapView.js.map +1 -1
  80. package/dist/esm/TileSet.d.ts +15 -6
  81. package/dist/esm/TileSet.d.ts.map +1 -0
  82. package/dist/esm/TileSet.js +161 -181
  83. package/dist/esm/TileSet.js.map +1 -1
  84. package/dist/esm/WangSet.d.ts +5 -4
  85. package/dist/esm/WangSet.d.ts.map +1 -0
  86. package/dist/esm/WangSet.js +70 -78
  87. package/dist/esm/WangSet.js.map +1 -1
  88. package/dist/esm/WorkerSampledChunkSource.d.ts +95 -0
  89. package/dist/esm/WorkerSampledChunkSource.d.ts.map +1 -0
  90. package/dist/esm/WorkerSampledChunkSource.js +117 -0
  91. package/dist/esm/WorkerSampledChunkSource.js.map +1 -0
  92. package/dist/esm/autoTile.d.ts +10 -5
  93. package/dist/esm/autoTile.d.ts.map +1 -0
  94. package/dist/esm/autoTile.js +164 -205
  95. package/dist/esm/autoTile.js.map +1 -1
  96. package/dist/esm/chunkGeometry.d.ts +8 -7
  97. package/dist/esm/chunkGeometry.d.ts.map +1 -0
  98. package/dist/esm/chunkGeometry.js +83 -94
  99. package/dist/esm/chunkGeometry.js.map +1 -1
  100. package/dist/esm/index.d.ts +1 -0
  101. package/dist/esm/index.d.ts.map +1 -0
  102. package/dist/esm/index.js +26 -15
  103. package/dist/esm/nodeBounds.d.ts +20 -0
  104. package/dist/esm/nodeBounds.d.ts.map +1 -0
  105. package/dist/esm/nodeBounds.js +40 -0
  106. package/dist/esm/nodeBounds.js.map +1 -0
  107. package/dist/esm/pixelSnap.d.ts +4 -3
  108. package/dist/esm/pixelSnap.d.ts.map +1 -0
  109. package/dist/esm/pixelSnap.js +18 -16
  110. package/dist/esm/pixelSnap.js.map +1 -1
  111. package/dist/esm/public.d.ts +23 -3
  112. package/dist/esm/public.d.ts.map +1 -0
  113. package/dist/esm/tileCollision.d.ts +190 -0
  114. package/dist/esm/tileCollision.d.ts.map +1 -0
  115. package/dist/esm/tileCollision.js +367 -0
  116. package/dist/esm/tileCollision.js.map +1 -0
  117. package/dist/esm/tileWord.d.ts +12 -0
  118. package/dist/esm/tileWord.d.ts.map +1 -0
  119. package/dist/esm/tileWord.js +16 -0
  120. package/dist/esm/tileWord.js.map +1 -0
  121. package/dist/esm/tilemapExtension.d.ts +4 -3
  122. package/dist/esm/tilemapExtension.d.ts.map +1 -0
  123. package/dist/esm/tilemapExtension.js +47 -47
  124. package/dist/esm/tilemapExtension.js.map +1 -1
  125. package/dist/esm/tilemapSerializers.d.ts +5 -4
  126. package/dist/esm/tilemapSerializers.d.ts.map +1 -0
  127. package/dist/esm/tilemapSerializers.js +48 -41
  128. package/dist/esm/tilemapSerializers.js.map +1 -1
  129. package/dist/esm/types.d.ts +34 -18
  130. package/dist/esm/types.d.ts.map +1 -0
  131. package/dist/esm/types.js +111 -120
  132. package/dist/esm/types.js.map +1 -1
  133. package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts +50 -2
  134. package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts.map +1 -0
  135. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js +366 -332
  136. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js.map +1 -1
  137. package/dist/esm/webgl2/shaders/tile-chunk.frag.js +6 -0
  138. package/dist/esm/webgl2/shaders/tile-chunk.frag.js.map +1 -0
  139. package/dist/esm/webgl2/shaders/tile-chunk.vert.js +6 -0
  140. package/dist/esm/webgl2/shaders/tile-chunk.vert.js.map +1 -0
  141. package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts +70 -4
  142. package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts.map +1 -0
  143. package/dist/esm/webgpu/WebGpuTileChunkRenderer.js +496 -383
  144. package/dist/esm/webgpu/WebGpuTileChunkRenderer.js.map +1 -1
  145. package/dist/esm/webgpu/shaders/tile-chunk.wgsl.js +6 -0
  146. package/dist/esm/webgpu/shaders/tile-chunk.wgsl.js.map +1 -0
  147. package/package.json +8 -15
  148. package/dist/esm/index.js.map +0 -1
  149. package/dist/esm/register.d.ts +0 -1
  150. package/dist/esm/register.js +0 -25
  151. package/dist/esm/register.js.map +0 -1
@@ -1,99 +1,88 @@
1
- import { unpackTile } from './types.js';
1
+ import { unpackTile } from "./types.js";
2
2
 
3
+ //#region src/chunkGeometry.ts
3
4
  /** Pack a {@link TileTransform} into a 3-bit orientation code. @internal */
4
- function orientCode(transform) {
5
- return (transform.flipX ? 1 : 0) | (transform.flipY ? 2 : 0) | (transform.diagonal ? 4 : 0);
6
- }
5
+ const orientCode = (transform) => (transform.flipX ? 1 : 0) | (transform.flipY ? 2 : 0) | (transform.diagonal ? 4 : 0);
6
+ let tileGeometryRebuildCount = 0;
7
7
  /**
8
- * Build per-tileset page geometry for a single chunk.
9
- *
10
- * Iterates the chunk's packed cells in deterministic row-major order, skipping
11
- * empties, out-of-range tilesets, and out-of-range local tile ids (all treated
12
- * as empty this is the renderer's half of the G-GID contract). Each surviving
13
- * cell is resolved to its source UV rect (from `tileset.getTileRect` + the
14
- * tileset `TextureRegion`) and a chunk-local destination rect (bottom-left
15
- * aligned per Tiled orthogonal semantics, so tilesets whose tiles are taller
16
- * than the map grid extend upward).
17
- *
18
- * Allocation happens here only the result is cached on the owning
19
- * {@link import('./TileChunkNode').TileChunkNode} keyed by `chunk.revision`, so
20
- * unchanged chunks never rebuild and the per-frame path stays allocation-free.
21
- *
22
- * @param chunk The readonly chunk view to build from.
23
- * @param tilesets The layer's tileset array (packed `tilesetIndex` selects one).
24
- * @param tileWidth Map/layer tile cell width in pixels.
25
- * @param tileHeight Map/layer tile cell height in pixels.
26
- * @internal
27
- */
28
- function buildChunkPages(chunk, tilesets, tileWidth, tileHeight) {
29
- if (chunk.empty) {
30
- return [];
31
- }
32
- const buckets = new Map();
33
- const width = chunk.width;
34
- const height = chunk.height;
35
- for (let ly = 0; ly < height; ly++) {
36
- for (let lx = 0; lx < width; lx++) {
37
- const packed = chunk.getRawAt(lx, ly);
38
- if (packed === 0) {
39
- continue;
40
- }
41
- const decoded = unpackTile(packed);
42
- if (decoded === null) {
43
- continue;
44
- }
45
- const tileset = tilesets[decoded.tilesetIndex];
46
- // Out-of-range tileset or local id → treat as empty (G-GID). getTileRect
47
- // throws on an out-of-range id, so the bounds check must precede it.
48
- if (tileset === undefined || decoded.localTileId >= tileset.tileCount) {
49
- continue;
50
- }
51
- const region = tileset.texture;
52
- const texture = region.texture;
53
- const textureWidth = texture.width;
54
- const textureHeight = texture.height;
55
- if (textureWidth <= 0 || textureHeight <= 0) {
56
- continue;
57
- }
58
- const rect = tileset.getTileRect(decoded.localTileId);
59
- // Absolute source pixel rect = tileset-region offset + in-atlas tile rect.
60
- const sx = region.x + rect.x;
61
- const sy = region.y + rect.y;
62
- // Exact tile UVs, no half-texel inset. This assumes NEAREST filtering on
63
- // the tileset atlas (the typical pixel-art case). Under LINEAR/mipmap
64
- // filtering an atlas WITHOUT extrusion padding can bleed neighbouring
65
- // tiles at the edges; author tilesets with extruded margins for linear
66
- // sampling. (Extrusion-aware tilemap UV insetting — already done on the
67
- // NineSlice/RepeatingSprite geometry paths — is a v0.14 follow-up.)
68
- const u0 = sx / textureWidth;
69
- const v0 = sy / textureHeight;
70
- const u1 = (sx + rect.width) / textureWidth;
71
- const v1 = (sy + rect.height) / textureHeight;
72
- // Bottom-left aligned destination (Tiled orthogonal). Uniform tiles
73
- // (rect.height === tileHeight) collapse to a plain cell rect. The
74
- // tileset's visual draw offset (Tiled `tileoffset`) shifts every tile.
75
- const x0 = lx * tileWidth + tileset.offsetX;
76
- const y0 = ly * tileHeight + tileHeight - rect.height + tileset.offsetY;
77
- const x1 = x0 + rect.width;
78
- const y1 = y0 + rect.height;
79
- let bucket = buckets.get(tileset);
80
- if (bucket === undefined) {
81
- bucket = [];
82
- buckets.set(tileset, bucket);
83
- }
84
- bucket.push({ x0, y0, x1, y1, u0, v0, u1, v1, orient: orientCode(decoded.transform) });
85
- }
86
- }
87
- // Emit pages in tileset-array order for deterministic, reproducible builds.
88
- const pages = [];
89
- for (const tileset of tilesets) {
90
- const quads = buckets.get(tileset);
91
- if (quads !== undefined && quads.length > 0) {
92
- pages.push({ tileset, texture: tileset.texture.texture, quads });
93
- }
94
- }
95
- return pages;
96
- }
8
+ * Build per-tileset page geometry for a single chunk.
9
+ *
10
+ * Iterates the chunk's packed cells in deterministic row-major order, skipping
11
+ * empties, out-of-range tilesets, and out-of-range local tile ids (all treated
12
+ * as empty - this is the renderer's half of the G-GID contract). Each surviving
13
+ * cell is resolved to its source UV rect (from `tileset.getTileRect` + the
14
+ * tileset `TextureRegion`) and a chunk-local destination rect (bottom-left
15
+ * aligned per Tiled orthogonal semantics, so tilesets whose tiles are taller
16
+ * than the map grid extend upward).
17
+ *
18
+ * Allocation happens here only - the result is cached on the owning
19
+ * {@link import('./TileChunkNode').TileChunkNode} keyed by `chunk.revision`, so
20
+ * unchanged chunks never rebuild and the per-frame path stays allocation-free.
21
+ *
22
+ * @param chunk The readonly chunk view to build from.
23
+ * @param tilesets The layer's tileset array (packed `tilesetIndex` selects one).
24
+ * @param tileWidth Map/layer tile cell width in pixels.
25
+ * @param tileHeight Map/layer tile cell height in pixels.
26
+ * @internal
27
+ */
28
+ const buildChunkPages = (chunk, tilesets, tileWidth, tileHeight) => {
29
+ tileGeometryRebuildCount++;
30
+ if (chunk.empty) return [];
31
+ const buckets = /* @__PURE__ */ new Map();
32
+ const width = chunk.width;
33
+ const height = chunk.height;
34
+ for (let ly = 0; ly < height; ly++) for (let lx = 0; lx < width; lx++) {
35
+ const packed = chunk.getRawAt(lx, ly);
36
+ if (packed === 0) continue;
37
+ const decoded = unpackTile(packed);
38
+ if (decoded === null) continue;
39
+ const tileset = tilesets[decoded.tilesetIndex];
40
+ if (tileset === void 0 || decoded.localTileId >= tileset.tileCount) continue;
41
+ const region = tileset.texture;
42
+ const texture = region.texture;
43
+ const textureWidth = texture.width;
44
+ const textureHeight = texture.height;
45
+ if (textureWidth <= 0 || textureHeight <= 0) continue;
46
+ const rect = tileset.getTileRect(decoded.localTileId);
47
+ const sx = region.x + rect.x;
48
+ const sy = region.y + rect.y;
49
+ const u0 = sx / textureWidth;
50
+ const v0 = sy / textureHeight;
51
+ const u1 = (sx + rect.width) / textureWidth;
52
+ const v1 = (sy + rect.height) / textureHeight;
53
+ const x0 = lx * tileWidth + tileset.offsetX;
54
+ const y0 = ly * tileHeight + tileHeight - rect.height + tileset.offsetY;
55
+ const x1 = x0 + rect.width;
56
+ const y1 = y0 + rect.height;
57
+ let bucket = buckets.get(tileset);
58
+ if (bucket === void 0) {
59
+ bucket = [];
60
+ buckets.set(tileset, bucket);
61
+ }
62
+ bucket.push({
63
+ x0,
64
+ y0,
65
+ x1,
66
+ y1,
67
+ u0,
68
+ v0,
69
+ u1,
70
+ v1,
71
+ orient: orientCode(decoded.transform)
72
+ });
73
+ }
74
+ const pages = [];
75
+ for (const tileset of tilesets) {
76
+ const quads = buckets.get(tileset);
77
+ if (quads !== void 0 && quads.length > 0) pages.push({
78
+ tileset,
79
+ texture: tileset.texture.texture,
80
+ quads
81
+ });
82
+ }
83
+ return pages;
84
+ };
97
85
 
86
+ //#endregion
98
87
  export { buildChunkPages, orientCode };
99
- //# sourceMappingURL=chunkGeometry.js.map
88
+ //# sourceMappingURL=chunkGeometry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chunkGeometry.js","sources":["../../../src/chunkGeometry.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chunkGeometry.js","names":[],"sources":["../../src/chunkGeometry.ts"],"sourcesContent":["import type { Texture } from '@codexo/exojs';\n\nimport type { ReadonlyTileChunk } from './TileChunk';\nimport type { TileSet } from './TileSet';\nimport type { TileTransform } from './types';\nimport { unpackTile } from './types';\n\n/**\n * One textured tile quad in chunk-local pixel space.\n *\n * `u0/v0/u1/v1` are the raw (min/max) source UV bounds of the tile within its\n * tileset texture - flip/orientation is **not** baked here; it travels in\n * {@link TileQuad.orient} and is applied by the per-backend renderer (flipX/Y\n * via UV-corner swap, diagonal via an axis swap in the shader). Keeping the\n * geometry orientation-neutral lets both backends share one CPU builder.\n * @internal\n */\nexport interface TileQuad {\n /** Local destination rect, left/top (chunk-local pixels). */\n readonly x0: number;\n readonly y0: number;\n /** Local destination rect, right/bottom (chunk-local pixels). */\n readonly x1: number;\n readonly y1: number;\n /** Normalised source UV bounds (always min ≤ max). */\n readonly u0: number;\n readonly v0: number;\n readonly u1: number;\n readonly v1: number;\n /** Orientation code: bit0 = flipX, bit1 = flipY, bit2 = diagonal. */\n readonly orient: number;\n}\n\n/**\n * Geometry for one tileset \"page\" within a chunk: every tile in the chunk that\n * draws from a single tileset texture, grouped so the renderer can batch by\n * `(shader, texture)`.\n * @internal\n */\nexport interface ChunkPage {\n /** The tileset all quads in this page draw from. */\n readonly tileset: TileSet;\n /** The underlying GPU texture (the tileset's atlas), bound once per page. */\n readonly texture: Texture;\n /** The tile quads for this page, in deterministic row-major order. */\n readonly quads: readonly TileQuad[];\n}\n\n/** Pack a {@link TileTransform} into a 3-bit orientation code. @internal */\nexport const orientCode = (transform: TileTransform): number => (transform.flipX ? 1 : 0) | (transform.flipY ? 2 : 0) | (transform.diagonal ? 4 : 0);\n\n// Test/perf-only instrumentation: counts CPU chunk-geometry rebuilds. A rebuild\n// happens once per {@link buildChunkPages} call - i.e. when a chunk node sees a\n// changed `chunk.revision`. Lets benchmarks/regression tests assert that a camera\n// pan rebuilds nothing and a single tile mutation rebuilds exactly one chunk.\n// Near-zero cost (one integer increment on the already-expensive rebuild path).\nlet tileGeometryRebuildCount = 0;\n\n/** Read the cumulative chunk-geometry rebuild count. @internal */\nexport const getTileGeometryRebuildCount = (): number => tileGeometryRebuildCount;\n\n/** Reset the chunk-geometry rebuild counter (call before a measured frame). @internal */\nexport const resetTileGeometryRebuildCount = (): void => {\n tileGeometryRebuildCount = 0;\n};\n\n/**\n * Build per-tileset page geometry for a single chunk.\n *\n * Iterates the chunk's packed cells in deterministic row-major order, skipping\n * empties, out-of-range tilesets, and out-of-range local tile ids (all treated\n * as empty - this is the renderer's half of the G-GID contract). Each surviving\n * cell is resolved to its source UV rect (from `tileset.getTileRect` + the\n * tileset `TextureRegion`) and a chunk-local destination rect (bottom-left\n * aligned per Tiled orthogonal semantics, so tilesets whose tiles are taller\n * than the map grid extend upward).\n *\n * Allocation happens here only - the result is cached on the owning\n * {@link import('./TileChunkNode').TileChunkNode} keyed by `chunk.revision`, so\n * unchanged chunks never rebuild and the per-frame path stays allocation-free.\n *\n * @param chunk The readonly chunk view to build from.\n * @param tilesets The layer's tileset array (packed `tilesetIndex` selects one).\n * @param tileWidth Map/layer tile cell width in pixels.\n * @param tileHeight Map/layer tile cell height in pixels.\n * @internal\n */\nexport const buildChunkPages = (chunk: ReadonlyTileChunk, tilesets: readonly TileSet[], tileWidth: number, tileHeight: number): ChunkPage[] => {\n tileGeometryRebuildCount++;\n\n if (chunk.empty) {\n return [];\n }\n\n const buckets = new Map<TileSet, TileQuad[]>();\n const width = chunk.width;\n const height = chunk.height;\n\n for (let ly = 0; ly < height; ly++) {\n for (let lx = 0; lx < width; lx++) {\n const packed = chunk.getRawAt(lx, ly);\n\n if (packed === 0) {\n continue;\n }\n\n const decoded = unpackTile(packed);\n\n if (decoded === null) {\n continue;\n }\n\n const tileset = tilesets[decoded.tilesetIndex];\n\n // Out-of-range tileset or local id → treat as empty (G-GID). getTileRect\n // throws on an out-of-range id, so the bounds check must precede it.\n if (tileset === undefined || decoded.localTileId >= tileset.tileCount) {\n continue;\n }\n\n const region = tileset.texture;\n const texture = region.texture;\n const textureWidth = texture.width;\n const textureHeight = texture.height;\n\n if (textureWidth <= 0 || textureHeight <= 0) {\n continue;\n }\n\n const rect = tileset.getTileRect(decoded.localTileId);\n\n // Absolute source pixel rect = tileset-region offset + in-atlas tile rect.\n const sx = region.x + rect.x;\n const sy = region.y + rect.y;\n // Exact tile UVs, no half-texel inset. This assumes NEAREST filtering on\n // the tileset atlas (the typical pixel-art case). Under LINEAR/mipmap\n // filtering an atlas WITHOUT extrusion padding can bleed neighbouring\n // tiles at the edges; author tilesets with extruded margins for linear\n // sampling. (Extrusion-aware tilemap UV insetting - already done on the\n // NineSlice/RepeatingSprite geometry paths - is a v0.14 follow-up.)\n const u0 = sx / textureWidth;\n const v0 = sy / textureHeight;\n const u1 = (sx + rect.width) / textureWidth;\n const v1 = (sy + rect.height) / textureHeight;\n\n // Bottom-left aligned destination (Tiled orthogonal). Uniform tiles\n // (rect.height === tileHeight) collapse to a plain cell rect. The\n // tileset's visual draw offset (Tiled `tileoffset`) shifts every tile.\n const x0 = lx * tileWidth + tileset.offsetX;\n const y0 = ly * tileHeight + tileHeight - rect.height + tileset.offsetY;\n const x1 = x0 + rect.width;\n const y1 = y0 + rect.height;\n\n let bucket = buckets.get(tileset);\n\n if (bucket === undefined) {\n bucket = [];\n buckets.set(tileset, bucket);\n }\n\n bucket.push({ x0, y0, x1, y1, u0, v0, u1, v1, orient: orientCode(decoded.transform) });\n }\n }\n\n // Emit pages in tileset-array order for deterministic, reproducible builds.\n const pages: ChunkPage[] = [];\n\n for (const tileset of tilesets) {\n const quads = buckets.get(tileset);\n\n if (quads !== undefined && quads.length > 0) {\n pages.push({ tileset, texture: tileset.texture.texture, quads });\n }\n }\n\n return pages;\n};\n"],"mappings":";;;;AAiDA,MAAa,cAAc,eAAsC,UAAU,QAAQ,IAAI,MAAM,UAAU,QAAQ,IAAI,MAAM,UAAU,WAAW,IAAI;AAOlJ,IAAI,2BAA2B;;;;;;;;;;;;;;;;;;;;;;AA+B/B,MAAa,mBAAmB,OAA0B,UAA8B,WAAmB,eAAoC;CAC7I;CAEA,IAAI,MAAM,OACR,OAAO,CAAC;CAGV,MAAM,0BAAU,IAAI,IAAyB;CAC7C,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,MAAM;CAErB,KAAK,IAAI,KAAK,GAAG,KAAK,QAAQ,MAC5B,KAAK,IAAI,KAAK,GAAG,KAAK,OAAO,MAAM;EACjC,MAAM,SAAS,MAAM,SAAS,IAAI,EAAE;EAEpC,IAAI,WAAW,GACb;EAGF,MAAM,UAAU,WAAW,MAAM;EAEjC,IAAI,YAAY,MACd;EAGF,MAAM,UAAU,SAAS,QAAQ;EAIjC,IAAI,YAAY,UAAa,QAAQ,eAAe,QAAQ,WAC1D;EAGF,MAAM,SAAS,QAAQ;EACvB,MAAM,UAAU,OAAO;EACvB,MAAM,eAAe,QAAQ;EAC7B,MAAM,gBAAgB,QAAQ;EAE9B,IAAI,gBAAgB,KAAK,iBAAiB,GACxC;EAGF,MAAM,OAAO,QAAQ,YAAY,QAAQ,WAAW;EAGpD,MAAM,KAAK,OAAO,IAAI,KAAK;EAC3B,MAAM,KAAK,OAAO,IAAI,KAAK;EAO3B,MAAM,KAAK,KAAK;EAChB,MAAM,KAAK,KAAK;EAChB,MAAM,MAAM,KAAK,KAAK,SAAS;EAC/B,MAAM,MAAM,KAAK,KAAK,UAAU;EAKhC,MAAM,KAAK,KAAK,YAAY,QAAQ;EACpC,MAAM,KAAK,KAAK,aAAa,aAAa,KAAK,SAAS,QAAQ;EAChE,MAAM,KAAK,KAAK,KAAK;EACrB,MAAM,KAAK,KAAK,KAAK;EAErB,IAAI,SAAS,QAAQ,IAAI,OAAO;EAEhC,IAAI,WAAW,QAAW;GACxB,SAAS,CAAC;GACV,QAAQ,IAAI,SAAS,MAAM;EAC7B;EAEA,OAAO,KAAK;GAAE;GAAI;GAAI;GAAI;GAAI;GAAI;GAAI;GAAI;GAAI,QAAQ,WAAW,QAAQ,SAAS;EAAE,CAAC;CACvF;CAIF,MAAM,QAAqB,CAAC;CAE5B,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,QAAQ,QAAQ,IAAI,OAAO;EAEjC,IAAI,UAAU,UAAa,MAAM,SAAS,GACxC,MAAM,KAAK;GAAE;GAAS,SAAS,QAAQ,QAAQ;GAAS;EAAM,CAAC;CAEnE;CAEA,OAAO;AACT"}
@@ -1 +1,2 @@
1
1
  export * from './public';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,UAAU,CAAC"}
package/dist/esm/index.js CHANGED
@@ -1,15 +1,26 @@
1
- export { tilemapExtension } from './tilemapExtension.js';
2
- export { ImageLayer } from './ImageLayer.js';
3
- export { ObjectKind, ObjectLayer } from './ObjectLayer.js';
4
- export { TileLayer } from './TileLayer.js';
5
- export { TileMap } from './TileMap.js';
6
- export { TileSet } from './TileSet.js';
7
- export { TileLayerNode } from './TileLayerNode.js';
8
- export { TileMapNode } from './TileMapNode.js';
9
- export { TileMapBand } from './TileMapBand.js';
10
- export { TileMapView } from './TileMapView.js';
11
- export { TILE_TRANSFORM_IDENTITY, TilePropertyKind, tileToChunkCoord, tileToLocalInChunk } from './types.js';
12
- export { TileAnimator } from './TileAnimator.js';
13
- export { autoTile, refreshCell } from './autoTile.js';
14
- export { WangSet } from './WangSet.js';
15
- //# sourceMappingURL=index.js.map
1
+ import { TILE_TRANSFORM_IDENTITY, TilePropertyKind, packTile, tileToChunkCoord, tileToLocalInChunk, unpackTile } from "./types.js";
2
+ import { ImageLayer } from "./ImageLayer.js";
3
+ import { ImageLayerNode } from "./ImageLayerNode.js";
4
+ import { TileLayerNode } from "./TileLayerNode.js";
5
+ import { TileMapNode } from "./TileMapNode.js";
6
+ import { TileLayer } from "./TileLayer.js";
7
+ import { TileMapBand } from "./TileMapBand.js";
8
+ import { TileMapView } from "./TileMapView.js";
9
+ import { TileSet } from "./TileSet.js";
10
+ import { TileMap } from "./TileMap.js";
11
+ import { tilemapExtension } from "./tilemapExtension.js";
12
+ import { ObjectKind, ObjectLayer } from "./ObjectLayer.js";
13
+ import { MapLevelSide, MapWorld } from "./MapWorld.js";
14
+ import { MapLevelRuntime, MapWorldRuntime } from "./MapWorldRuntime.js";
15
+ import { mapObjectDescriptor, mapObjectDescriptors } from "./MapObject.js";
16
+ import { MapSpawnSession } from "./MapSpawnSession.js";
17
+ import { MapObjectSpawner, MapSpawnError } from "./MapObjectSpawner.js";
18
+ import { TileAnimator } from "./TileAnimator.js";
19
+ import { buildTileCollisionGeometry } from "./tileCollision.js";
20
+ import { ChunkStreamer } from "./ChunkStreamer.js";
21
+ import { createSampledChunkSource } from "./SampledChunkSource.js";
22
+ import { createWorkerSampledChunkSource } from "./WorkerSampledChunkSource.js";
23
+ import { autoTile, refreshCell } from "./autoTile.js";
24
+ import { WangSet } from "./WangSet.js";
25
+
26
+ export { ChunkStreamer, ImageLayer, ImageLayerNode, MapLevelRuntime, MapLevelSide, MapObjectSpawner, MapSpawnError, MapSpawnSession, MapWorld, MapWorldRuntime, ObjectKind, ObjectLayer, TILE_TRANSFORM_IDENTITY, TileAnimator, TileLayer, TileLayerNode, TileMap, TileMapBand, TileMapNode, TileMapView, TilePropertyKind, TileSet, WangSet, autoTile, buildTileCollisionGeometry, createSampledChunkSource, createWorkerSampledChunkSource, mapObjectDescriptor, mapObjectDescriptors, packTile, refreshCell, tileToChunkCoord, tileToLocalInChunk, tilemapExtension, unpackTile };
@@ -0,0 +1,20 @@
1
+ import type { SceneNode } from '@codexo/exojs';
2
+ import { Rectangle } from '@codexo/exojs';
3
+ /**
4
+ * Grow `out` to the union of `children`'s local bounds, each transformed by
5
+ * the child's own (translation-only, in practice) local transform - i.e. the
6
+ * children's combined extent expressed in the *parent's* local coordinate
7
+ * space, not the parent's own position/scale/rotation.
8
+ *
9
+ * Used as the unbounded-layer/-map fallback for `getLocalBounds()`: `Container`
10
+ * does not aggregate children into its own local bounds automatically (only
11
+ * `getBounds()` - global - does that), so nodes that want a children-derived
12
+ * local rect must compute it explicitly. Mirrors `Container.updateBounds()`'s
13
+ * own aggregation semantics, including skipping invisible children. Callers
14
+ * are expected to only invoke this when `children.length > 0`; `out` is left
15
+ * untouched otherwise (also guarded internally in case a future call site
16
+ * forgets to check).
17
+ * @internal
18
+ */
19
+ export declare const aggregateChildLocalBounds: (children: readonly SceneNode[], out: Rectangle) => void;
20
+ //# sourceMappingURL=nodeBounds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodeBounds.d.ts","sourceRoot":"","sources":["../../src/nodeBounds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,yBAAyB,GAAI,UAAU,SAAS,SAAS,EAAE,EAAE,KAAK,SAAS,KAAG,IA6B1F,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { Rectangle } from "@codexo/exojs";
2
+
3
+ //#region src/nodeBounds.ts
4
+ /**
5
+ * Grow `out` to the union of `children`'s local bounds, each transformed by
6
+ * the child's own (translation-only, in practice) local transform - i.e. the
7
+ * children's combined extent expressed in the *parent's* local coordinate
8
+ * space, not the parent's own position/scale/rotation.
9
+ *
10
+ * Used as the unbounded-layer/-map fallback for `getLocalBounds()`: `Container`
11
+ * does not aggregate children into its own local bounds automatically (only
12
+ * `getBounds()` - global - does that), so nodes that want a children-derived
13
+ * local rect must compute it explicitly. Mirrors `Container.updateBounds()`'s
14
+ * own aggregation semantics, including skipping invisible children. Callers
15
+ * are expected to only invoke this when `children.length > 0`; `out` is left
16
+ * untouched otherwise (also guarded internally in case a future call site
17
+ * forgets to check).
18
+ * @internal
19
+ */
20
+ const aggregateChildLocalBounds = (children, out) => {
21
+ if (children.length === 0) return;
22
+ let minX = Infinity;
23
+ let minY = Infinity;
24
+ let maxX = -Infinity;
25
+ let maxY = -Infinity;
26
+ for (const child of children) {
27
+ if (!child.visible) continue;
28
+ const rect = child.getLocalBounds().transform(child.getTransform(), Rectangle.temp);
29
+ minX = Math.min(minX, rect.left);
30
+ minY = Math.min(minY, rect.top);
31
+ maxX = Math.max(maxX, rect.right);
32
+ maxY = Math.max(maxY, rect.bottom);
33
+ }
34
+ if (minX === Infinity) return;
35
+ out.set(minX, minY, maxX - minX, maxY - minY);
36
+ };
37
+
38
+ //#endregion
39
+ export { aggregateChildLocalBounds };
40
+ //# sourceMappingURL=nodeBounds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodeBounds.js","names":[],"sources":["../../src/nodeBounds.ts"],"sourcesContent":["import type { SceneNode } from '@codexo/exojs';\nimport { Rectangle } from '@codexo/exojs';\n\n/**\n * Grow `out` to the union of `children`'s local bounds, each transformed by\n * the child's own (translation-only, in practice) local transform - i.e. the\n * children's combined extent expressed in the *parent's* local coordinate\n * space, not the parent's own position/scale/rotation.\n *\n * Used as the unbounded-layer/-map fallback for `getLocalBounds()`: `Container`\n * does not aggregate children into its own local bounds automatically (only\n * `getBounds()` - global - does that), so nodes that want a children-derived\n * local rect must compute it explicitly. Mirrors `Container.updateBounds()`'s\n * own aggregation semantics, including skipping invisible children. Callers\n * are expected to only invoke this when `children.length > 0`; `out` is left\n * untouched otherwise (also guarded internally in case a future call site\n * forgets to check).\n * @internal\n */\nexport const aggregateChildLocalBounds = (children: readonly SceneNode[], out: Rectangle): void => {\n if (children.length === 0) {\n return;\n }\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const child of children) {\n if (!child.visible) {\n continue;\n }\n\n const rect = child.getLocalBounds().transform(child.getTransform(), Rectangle.temp);\n\n minX = Math.min(minX, rect.left);\n minY = Math.min(minY, rect.top);\n maxX = Math.max(maxX, rect.right);\n maxY = Math.max(maxY, rect.bottom);\n }\n\n if (minX === Infinity) {\n // Every child was invisible; nothing to aggregate.\n return;\n }\n\n out.set(minX, minY, maxX - minX, maxY - minY);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmBA,MAAa,6BAA6B,UAAgC,QAAyB;CACjG,IAAI,SAAS,WAAW,GACtB;CAGF,IAAI,OAAO;CACX,IAAI,OAAO;CACX,IAAI,OAAO;CACX,IAAI,OAAO;CAEX,KAAK,MAAM,SAAS,UAAU;EAC5B,IAAI,CAAC,MAAM,SACT;EAGF,MAAM,OAAO,MAAM,eAAe,CAAC,CAAC,UAAU,MAAM,aAAa,GAAG,UAAU,IAAI;EAElF,OAAO,KAAK,IAAI,MAAM,KAAK,IAAI;EAC/B,OAAO,KAAK,IAAI,MAAM,KAAK,GAAG;EAC9B,OAAO,KAAK,IAAI,MAAM,KAAK,KAAK;EAChC,OAAO,KAAK,IAAI,MAAM,KAAK,MAAM;CACnC;CAEA,IAAI,SAAS,UAEX;CAGF,IAAI,IAAI,MAAM,MAAM,OAAO,MAAM,OAAO,IAAI;AAC9C"}
@@ -1,12 +1,13 @@
1
- import type { PixelSnapMode } from '@codexo/exojs/renderer-sdk';
1
+ import { PixelSnapMode } from '@codexo/exojs/renderer-sdk';
2
2
  /**
3
3
  * Throw a deterministic error when `mode` is not a valid {@link PixelSnapMode}.
4
4
  *
5
5
  * Mirrors the core `Drawable` setter's guard so the tilemap node passthroughs
6
6
  * (`TileMapView` / `TileMapNode` / `TileLayerNode`) reject JavaScript-invalid
7
- * values atomically even for an empty layer that has no chunk drawable to
7
+ * values atomically - even for an empty layer that has no chunk drawable to
8
8
  * delegate the validation to. Kept local because the core guard is not part of
9
9
  * the public API surface.
10
10
  * @internal
11
11
  */
12
- export declare function assertPixelSnapMode(mode: PixelSnapMode): void;
12
+ export declare const assertPixelSnapMode: (mode: PixelSnapMode) => void;
13
+ //# sourceMappingURL=pixelSnap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixelSnap.d.ts","sourceRoot":"","sources":["../../src/pixelSnap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,aAAa,KAAG,IASzD,CAAC"}
@@ -1,19 +1,21 @@
1
- const validPixelSnapModes = new Set(['none', 'position', 'geometry']);
1
+ import { PixelSnapMode } from "@codexo/exojs/renderer-sdk";
2
+
3
+ //#region src/pixelSnap.ts
2
4
  /**
3
- * Throw a deterministic error when `mode` is not a valid {@link PixelSnapMode}.
4
- *
5
- * Mirrors the core `Drawable` setter's guard so the tilemap node passthroughs
6
- * (`TileMapView` / `TileMapNode` / `TileLayerNode`) reject JavaScript-invalid
7
- * values atomically even for an empty layer that has no chunk drawable to
8
- * delegate the validation to. Kept local because the core guard is not part of
9
- * the public API surface.
10
- * @internal
11
- */
12
- function assertPixelSnapMode(mode) {
13
- if (typeof mode !== 'string' || !validPixelSnapModes.has(mode)) {
14
- throw new Error(`pixelSnapMode must be 'none', 'position', or 'geometry' (got ${String(mode)}).`);
15
- }
16
- }
5
+ * Throw a deterministic error when `mode` is not a valid {@link PixelSnapMode}.
6
+ *
7
+ * Mirrors the core `Drawable` setter's guard so the tilemap node passthroughs
8
+ * (`TileMapView` / `TileMapNode` / `TileLayerNode`) reject JavaScript-invalid
9
+ * values atomically - even for an empty layer that has no chunk drawable to
10
+ * delegate the validation to. Kept local because the core guard is not part of
11
+ * the public API surface.
12
+ * @internal
13
+ */
14
+ const assertPixelSnapMode = (mode) => {
15
+ const value = mode;
16
+ if (value !== PixelSnapMode.None && value !== PixelSnapMode.Position && value !== PixelSnapMode.Geometry) throw new Error(`pixelSnapMode must be a PixelSnapMode enum value (got ${String(mode)}).`);
17
+ };
17
18
 
19
+ //#endregion
18
20
  export { assertPixelSnapMode };
19
- //# sourceMappingURL=pixelSnap.js.map
21
+ //# sourceMappingURL=pixelSnap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pixelSnap.js","sources":["../../../src/pixelSnap.ts"],"sourcesContent":[null],"names":[],"mappings":"AAEA,MAAM,mBAAmB,GAAwB,IAAI,GAAG,CAAS,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAElG;;;;;;;;;AASG;AACG,SAAU,mBAAmB,CAAC,IAAmB,EAAA;AACrD,IAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QAC9D,MAAM,IAAI,KAAK,CAAC,CAAA,6DAAA,EAAgE,MAAM,CAAC,IAAI,CAAC,CAAA,EAAA,CAAI,CAAC;IACnG;AACF;;;;"}
1
+ {"version":3,"file":"pixelSnap.js","names":[],"sources":["../../src/pixelSnap.ts"],"sourcesContent":["import { PixelSnapMode } from '@codexo/exojs/renderer-sdk';\n\n/**\n * Throw a deterministic error when `mode` is not a valid {@link PixelSnapMode}.\n *\n * Mirrors the core `Drawable` setter's guard so the tilemap node passthroughs\n * (`TileMapView` / `TileMapNode` / `TileLayerNode`) reject JavaScript-invalid\n * values atomically - even for an empty layer that has no chunk drawable to\n * delegate the validation to. Kept local because the core guard is not part of\n * the public API surface.\n * @internal\n */\nexport const assertPixelSnapMode = (mode: PixelSnapMode): void => {\n // Widen first: the parameter type would otherwise narrow the third\n // comparison to a statically-false branch, but JavaScript callers can pass\n // anything.\n const value: unknown = mode;\n\n if (value !== PixelSnapMode.None && value !== PixelSnapMode.Position && value !== PixelSnapMode.Geometry) {\n throw new Error(`pixelSnapMode must be a PixelSnapMode enum value (got ${String(mode)}).`);\n }\n};\n"],"mappings":";;;;;;;;;;;;;AAYA,MAAa,uBAAuB,SAA8B;CAIhE,MAAM,QAAiB;CAEvB,IAAI,UAAU,cAAc,QAAQ,UAAU,cAAc,YAAY,UAAU,cAAc,UAC9F,MAAM,IAAI,MAAM,yDAAyD,OAAO,IAAI,EAAE,GAAG;AAE7F"}
@@ -1,27 +1,47 @@
1
1
  export { tilemapExtension } from './tilemapExtension';
2
2
  export type { Extension } from '@codexo/exojs/extensions';
3
+ export type { ChunkPayload, ChunkSource } from './ChunkSource';
3
4
  export type { ImageLayerOptions } from './ImageLayer';
4
5
  export { ImageLayer } from './ImageLayer';
5
6
  export type { EllipseObject, ObjectLayerOptions, ObjectPoint, ObjectQuery, ObjectSchema, PointObject, PolygonObject, PolylineObject, RectangleObject, TextObject, TextStyle, TileMapObject, TileMapObjectKind, TileObject, TypedObject, } from './ObjectLayer';
6
7
  export { ObjectKind, ObjectLayer } from './ObjectLayer';
8
+ export type { MapBounds, MapLevel, MapLevelNeighbour, MapWorldOptions } from './MapWorld';
9
+ export { MapLevelSide, MapWorld } from './MapWorld';
10
+ export type { MapLevelCancelOptions, MapLevelLoadContext, MapLevelLoadOptions, MapLevelProvider, MapWorldRuntimeOptions } from './MapWorldRuntime';
11
+ export { MapLevelRuntime, MapWorldRuntime } from './MapWorldRuntime';
12
+ export type { MapObjectDescriptor } from './MapObject';
13
+ export { mapObjectDescriptor, mapObjectDescriptors } from './MapObject';
14
+ export type { MapObjectFactories, MapObjectFactory, MapObjectSpawnerOptions, MapSpawnErrorReason, MapSpawnOptions, UnknownMapObjectPolicy, } from './MapObjectSpawner';
15
+ export { MapObjectSpawner, MapSpawnError } from './MapObjectSpawner';
16
+ export { MapSpawnSession } from './MapSpawnSession';
7
17
  export type { ReadonlyTileChunk } from './TileChunk';
8
- export type { TileLayerOptions } from './TileLayer';
18
+ export type { ChunkRange, TileLayerOptions } from './TileLayer';
9
19
  export { TileLayer } from './TileLayer';
10
20
  export type { TileMapOptions } from './TileMap';
11
21
  export { TileMap } from './TileMap';
12
22
  export type { TileSetOptions } from './TileSet';
13
23
  export { TileSet } from './TileSet';
24
+ export { ImageLayerNode } from './ImageLayerNode';
14
25
  export type { TileLayerNodeOptions } from './TileLayerNode';
15
26
  export { TileLayerNode } from './TileLayerNode';
16
27
  export type { TileMapNodeOptions } from './TileMapNode';
17
28
  export { TileMapNode } from './TileMapNode';
18
29
  export { TileMapBand } from './TileMapBand';
19
- export type { TileLayerSelector, TileMapBandDefinition, TileMapViewOptions, } from './TileMapView';
30
+ export type { TileLayerSelector, TileMapBandDefinition, TileMapViewOptions } from './TileMapView';
20
31
  export { TileMapView } from './TileMapView';
21
32
  export type { ChunkCoord, PackedTile, ResolvedTile, TileAnimationFrame, TileDefinition, TileProperties, TilePropertyObjectRef, TilePropertyPoint, TilePropertyTileRef, TilePropertyValue, TileTransform, } from './types';
22
- export { TILE_TRANSFORM_IDENTITY, TilePropertyKind, tileToChunkCoord, tileToLocalInChunk, } from './types';
33
+ export { packTile, TILE_TRANSFORM_IDENTITY, TilePropertyKind, tileToChunkCoord, tileToLocalInChunk, unpackTile } from './types';
23
34
  export { TileAnimator } from './TileAnimator';
35
+ export type { TileCellSource, TileCollisionGeometry, TileCollisionOptions, TileCollisionRect, TileCollisionShape, TileCollisionShapeKind, TileRegion, } from './tileCollision';
36
+ export { buildTileCollisionGeometry } from './tileCollision';
37
+ export type { ChunkStreamerOptions } from './ChunkStreamer';
38
+ export { ChunkStreamer } from './ChunkStreamer';
39
+ export type { SampledChunkSourceOptions } from './SampledChunkSource';
40
+ export { createSampledChunkSource } from './SampledChunkSource';
41
+ export type { WorkerSampledChunkSourceOptions } from './WorkerSampledChunkSource';
42
+ export { createWorkerSampledChunkSource } from './WorkerSampledChunkSource';
24
43
  export type { AutoTileOptions } from './autoTile';
25
44
  export { autoTile, refreshCell } from './autoTile';
26
45
  export type { WangSetOptions } from './WangSet';
27
46
  export { WangSet } from './WangSet';
47
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/public.ts"],"names":[],"mappings":"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"}