The active tilemap layer can be renamed from the painting section, and a Show setting fades or hides the other layers in the scene view while the tilemap is selected (#138)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bfbcbe604c
commit
f53279d065
10 files changed
+248
-13
No files matched your search
+23
-2
@@ -12,6 +12,21 @@ import { placeNode } from './symbols';
|
||||
import type { TextureLibrary } from './TextureLibrary';
|
||||
import { groupByTile, type TileSheet, tileMesh } from './tilemapMesh';
|
||||
|
||||
/** The layer painted on and how the others are shown next to it (#138); null shows every layer. */
|
||||
export interface LayerFocus {
|
||||
layerId: string;
|
||||
mode: 'all' | 'dim' | 'solo';
|
||||
}
|
||||
|
||||
/** How far the others fade in `dim`: still readable as a map, plainly not what the brush reaches. */
|
||||
export const DIMMED_LAYER_ALPHA = 0.3;
|
||||
|
||||
/** How opaque one layer is drawn; 0 means it is not drawn at all. */
|
||||
export function layerAlpha(layerId: string, focus: LayerFocus | null): number {
|
||||
if (!focus || focus.mode === 'all' || layerId === focus.layerId) return 1;
|
||||
return focus.mode === 'dim' ? DIMMED_LAYER_ALPHA : 0;
|
||||
}
|
||||
|
||||
export class TilemapField {
|
||||
readonly container = new Container();
|
||||
private readonly meshes = new Map<string, Mesh>();
|
||||
@@ -28,7 +43,7 @@ export class TilemapField {
|
||||
* `now` is the global clock, so every tilemap showing the same tile is on the same step –
|
||||
* animated water does not run out of phase between two maps.
|
||||
*/
|
||||
sync(item: DrawItem, textures: TextureLibrary, now: number): void {
|
||||
sync(item: DrawItem, textures: TextureLibrary, now: number, focus: LayerFocus | null = null): void {
|
||||
const draw = item.tilemap;
|
||||
this.animated = false;
|
||||
// The whole map sits under one node, so the object's own transform is applied once rather
|
||||
@@ -39,6 +54,8 @@ export class TilemapField {
|
||||
const drawn: Mesh[] = [];
|
||||
const alive = new Set<string>();
|
||||
for (const layer of draw?.layers ?? []) {
|
||||
const alpha = layerAlpha(layer.id, focus);
|
||||
if (alpha === 0) continue;
|
||||
for (const [tileId, tiles] of groupByTile(layer.tiles)) {
|
||||
const source = draw?.tiles.get(tileId);
|
||||
const picture = source && pictureNow(source, now);
|
||||
@@ -48,7 +65,11 @@ export class TilemapField {
|
||||
const key = `${layer.id}|${tileId}`;
|
||||
alive.add(key);
|
||||
const { positions, uvs, indices } = tileMesh(tiles, tile, origin, sheetOf(source, picture, texture));
|
||||
drawn.push(this.meshFor(key, new MeshGeometry({ positions, uvs, indices }), texture));
|
||||
const mesh = this.meshFor(key, new MeshGeometry({ positions, uvs, indices }), texture);
|
||||
// Per mesh rather than per layer: the meshes of one layer never overlap, so fading each
|
||||
// one looks the same as fading the layer as a whole.
|
||||
mesh.alpha = alpha;
|
||||
drawn.push(mesh);
|
||||
}
|
||||
}
|
||||
for (const [key, mesh] of this.meshes) {
|
||||
|
||||
Reference in new issue
Block a user