world/layer: collect block light data with top layer

This commit is contained in:
Matthias Schiffer 2023-03-04 17:38:52 +01:00
parent 4fd316f3fc
commit 116e7e5fb6
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C

View file

@ -83,6 +83,7 @@ impl OptionBlockInfoExt for Option<BlockInfo> {
} }
pub type BlockInfoArray = LayerBlockArray<Option<BlockInfo>>; pub type BlockInfoArray = LayerBlockArray<Option<BlockInfo>>;
pub type BlockLightArray = LayerBlockArray<u8>;
/// Fills in a [BlockInfoArray] with the information of the chunk's top /// Fills in a [BlockInfoArray] with the information of the chunk's top
/// block layer /// block layer
@ -91,7 +92,7 @@ pub type BlockInfoArray = LayerBlockArray<Option<BlockInfo>>;
/// determined as the block that should be visible on the rendered /// determined as the block that should be visible on the rendered
/// map. For water blocks, the height of the first non-water block /// map. For water blocks, the height of the first non-water block
/// is additionally filled in as the water depth. /// is additionally filled in as the water depth.
pub fn top_layer(chunk: &Chunk) -> Result<Option<Box<BlockInfoArray>>> { pub fn top_layer(chunk: &Chunk) -> Result<Option<(Box<BlockInfoArray>, Box<BlockLightArray>)>> {
use BLOCKS_PER_CHUNK as N; use BLOCKS_PER_CHUNK as N;
if chunk.is_empty() { if chunk.is_empty() {
@ -99,33 +100,42 @@ pub fn top_layer(chunk: &Chunk) -> Result<Option<Box<BlockInfoArray>>> {
} }
let mut done = 0; let mut done = 0;
let mut ret = Box::<BlockInfoArray>::default(); let mut blocks = Box::<BlockInfoArray>::default();
let mut light = Box::<BlockLightArray>::default();
for SectionIterItem { for SectionIterItem {
y: section_y, y: section_y,
section, section,
block_light: _, block_light,
} in chunk.sections().rev() } in chunk.sections().rev()
{ {
for y in BlockY::iter().rev() { for y in BlockY::iter().rev() {
for xz in BlockInfoArray::keys() { for xz in BlockInfoArray::keys() {
let entry = &mut ret[xz]; let entry = &mut blocks[xz];
if entry.done() { if entry.done() {
continue; continue;
} }
let coords = SectionBlockCoords { xz, y }; let coords = SectionBlockCoords { xz, y };
'check_block: {
let Some(block_type) = section.block_at(coords)? else { let Some(block_type) = section.block_at(coords)? else {
continue; break 'check_block;
}; };
let height = BlockHeight::new(section_y, y)?; let height = BlockHeight::new(section_y, y)?;
if !entry.fill(height, block_type) { if !entry.fill(height, block_type) {
continue; break 'check_block;
} }
assert!(entry.done()); assert!(entry.done());
done += 1; done += 1;
};
if entry.is_none() {
light[xz] = block_light.block_light_at(coords);
}
if done == N * N { if done == N * N {
break; break;
} }
@ -133,5 +143,5 @@ pub fn top_layer(chunk: &Chunk) -> Result<Option<Box<BlockInfoArray>>> {
} }
} }
Ok(Some(ret)) Ok(Some((blocks, light)))
} }