diff --git a/init.lua b/init.lua index 0edec00..fcfb958 100644 --- a/init.lua +++ b/init.lua @@ -294,36 +294,46 @@ local function cell_has_material(vertices, cells_material, w, h, x, y) return false end --- Returns the blob-gated 8-bit neighbour bitmask for cell (x, y) given --- the layer's vertex grid + map size. Bit layout (clockwise from N): --- 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW. +-- Returns the blob-gated 8-bit neighbour bitmask for cell (x, y). +-- Bit layout (clockwise from N, LSB-first): N, NE, E, SE, S, SW, W, NW. -- --- 0.5.6: bits derive from the render-cell's own 4 corner map-tiles --- (= the 4 surrounding vertices in dual-grid terms), not from the --- material status of the 8 neighbour cells. A cardinal bit is set iff --- at least one of the 2 vertices on that edge is painted; a diagonal --- bit is set iff the corner vertex in that direction is painted. --- Pre-0.5.6 used cell-neighbour-material, which made two cells with a --- shared unpainted edge see each other as material whenever any other --- corner of either was painted — producing connected blobs across --- visually-empty map-tile gaps. See plan --- 2026-05-29-painting-model-rethink for the discovery. +-- 0.5.7: per-cell-origin branch. Cells whose material origin is +-- cells_material[x, y] use the classical 47-blob 8-neighbour rule on +-- effective material (vertex-derived OR cell-derived). Vertex-only +-- cells continue to use the FIX-A 4-own-corner rule (v0.5.6 dual-grid +-- semantics, 5 reachable atlas slots). +-- +-- Pre-condition: cell_has_material(vertices, cells_material, w, h, x, y) +-- returned true for this cell. local function compute_cell_bitmask_v3(vertices, cells_material, w, h, x, y) - local vw = w + 1 - local vh = h + 1 - local TL = vertex_at(vertices, vw, vh, x, y ) ~= 0 - local TR = vertex_at(vertices, vw, vh, x + 1, y ) ~= 0 - local BL = vertex_at(vertices, vw, vh, x, y + 1) ~= 0 - local BR = vertex_at(vertices, vw, vh, x + 1, y + 1) ~= 0 local b = 0 - if TL or TR then b = b | 0x01 end -- N edge: TL or TR painted - if TR then b = b | 0x02 end -- NE corner: TR painted - if TR or BR then b = b | 0x04 end -- E edge: TR or BR painted - if BR then b = b | 0x08 end -- SE corner: BR painted - if BL or BR then b = b | 0x10 end -- S edge: BL or BR painted - if BL then b = b | 0x20 end -- SW corner: BL painted - if TL or BL then b = b | 0x40 end -- W edge: TL or BL painted - if TL then b = b | 0x80 end -- NW corner: TL painted + if cells_material_at(cells_material, w, h, x, y) ~= 0 then + -- 47-blob branch: 8 neighbour effective-material bits. + if cell_has_material(vertices, cells_material, w, h, x, y - 1) then b = b | 0x01 end + if cell_has_material(vertices, cells_material, w, h, x + 1, y - 1) then b = b | 0x02 end + if cell_has_material(vertices, cells_material, w, h, x + 1, y ) then b = b | 0x04 end + if cell_has_material(vertices, cells_material, w, h, x + 1, y + 1) then b = b | 0x08 end + if cell_has_material(vertices, cells_material, w, h, x, y + 1) then b = b | 0x10 end + if cell_has_material(vertices, cells_material, w, h, x - 1, y + 1) then b = b | 0x20 end + if cell_has_material(vertices, cells_material, w, h, x - 1, y ) then b = b | 0x40 end + if cell_has_material(vertices, cells_material, w, h, x - 1, y - 1) then b = b | 0x80 end + else + -- FIX-A 4-corner-vertex branch (v0.5.6 dual-grid, unchanged). + local vw = w + 1 + local vh = h + 1 + local TL = vertex_at(vertices, vw, vh, x, y ) ~= 0 + local TR = vertex_at(vertices, vw, vh, x + 1, y ) ~= 0 + local BL = vertex_at(vertices, vw, vh, x, y + 1) ~= 0 + local BR = vertex_at(vertices, vw, vh, x + 1, y + 1) ~= 0 + if TL or TR then b = b | 0x01 end -- N + if TR then b = b | 0x02 end -- NE + if TR or BR then b = b | 0x04 end -- E + if BR then b = b | 0x08 end -- SE + if BL or BR then b = b | 0x10 end -- S + if BL then b = b | 0x20 end -- SW + if TL or BL then b = b | 0x40 end -- W + if TL then b = b | 0x80 end -- NW + end return apply_blob_gating(b) end