/** Compare only visible mesh neighborhoods; unchanged retained sections keep their buffers. */ export function changedLightSections(previous, next, sections) { if (!previous) return [...sections]; const index = (field, x, y, z) => { x -= field.min[0]; y -= field.min[1]; z -= field.min[2]; if (x < 0 || y < 0 || z < 0 || x >= field.size[0] || y >= field.size[1] || z >= field.size[2]) return -1; return x + field.size[0] * (y + field.size[1] * z); }; const changed = []; for (const id of sections) { const base = id.split(",").map(v => Number(v) * 16); let dirty = false; outer: for (let z = base[2] - 1; z <= base[2] + 16; z++) for (let y = base[1] - 1; y <= base[1] + 16; y++) for (let x = base[0] - 1; x <= base[0] + 16; x++) { const a = index(previous, x, y, z), b = index(next, x, y, z); if (a < 0 && b < 0) continue; if (a < 0 || b < 0 || previous.skyLevels[a] !== next.skyLevels[b] || previous.data[a * 4] !== next.data[b * 4] || previous.data[a * 4 + 1] !== next.data[b * 4 + 1] || previous.data[a * 4 + 2] !== next.data[b * 4 + 2]) { dirty = true; break outer; } } if (dirty) changed.push(id); } return changed; }