// TODO - this should be passed as a input parameter
// It still needs to scan the new buffer, since it hasn't been added to the column
final boolean[][][] dirty = new boolean[sizeX + 2][sizeY + 2][sizeZ + 2];
final int[][][] newLight = new int[sizeX + 2][sizeY + 2][sizeZ + 2];
final IntVector3FIFO fifo = new IntVector3FIFO((sizeX + 2) * (sizeY + 2) * (sizeZ + 2));
bulkEmittingInitialize(buffer, newLight, height);
// Mark the edges as dirty so they don't get added to the FIFO
for (int x = 0; x <= sizeX + 1; x++) {
for (int y = 0; y <= sizeY + 1; y++) {
dirty[x][y][0] = true;
dirty[x][y][sizeZ + 1] = true;
}
}
for (int x = 0; x <= sizeX + 1; x++) {
for (int z = 0; z <= sizeZ + 1; z++) {
dirty[x][0][z] = true;
dirty[x][sizeY + 1][z] = true;
}
}
for (int y = 0; y <= sizeY + 1; y++) {
for (int z = 0; z <= sizeZ + 1; z++) {
dirty[0][y][z] = true;
dirty[sizeX + 1][y][z] = true;
}
}
for (int x = 1; x <= sizeX; x++) {
for (int y = 1; y <= sizeY; y++) {
for (int z = 1; z <= sizeZ; z++) {
if (newLight[x][y][z] > 0) {
fifo.write(x, y, z);
dirty[x][y][z] = true;
}
}
}
}
IntVector3 v;
while ((v = fifo.read()) != null) {
int x = v.getX();
int y = v.getY();
int z = v.getZ();
BlockMaterial m = buffer.get(x + baseX - 1, y + baseY - 1, z + baseZ - 1);
ByteBitSet occulusion = m.getOcclusion(m.getData());
int center = newLight[x][y][z];
for (BlockFace face : allFaces) {
if (occulusion.get(face)) {
continue;
}
IntVector3 off = face.getIntOffset();
int nx = x + off.getX();
int ny = y + off.getY();
int nz = z + off.getZ();
if (nx <= 0 || nx > sizeX || ny <= 0 || ny > sizeY || nz <= 0 || nz > sizeZ) {
continue;
}
BlockMaterial other = buffer.get(nx + baseX - 1, ny + baseY - 1, nz + baseZ - 1);
int opacity = other.getOpacity() + 1;
int newLevel = center - opacity;
if (newLevel > newLight[nx][ny][nz] && !other.getOcclusion(other.getData()).get(face.getOpposite())) {
newLight[nx][ny][nz] = newLevel;
if (!dirty[nx][ny][nz]) {
dirty[nx][ny][nz] = true;
fifo.write(nx, ny, nz);
}
}
}
dirty[x][y][z] = false;
}