From e2c2e1bce1e87f425fee970d96cf35f412207309 Mon Sep 17 00:00:00 2001 From: Maxicarlos08 Date: Fri, 26 Jan 2024 10:16:47 +0100 Subject: [PATCH] store sprite data separately for compressed chunks --- common/net/src/msg/compression.rs | 89 +++++++++++++++++-------------- common/src/terrain/block.rs | 2 +- 2 files changed, 50 insertions(+), 41 deletions(-) diff --git a/common/net/src/msg/compression.rs b/common/net/src/msg/compression.rs index 412b6b28f6..e047b943c7 100644 --- a/common/net/src/msg/compression.rs +++ b/common/net/src/msg/compression.rs @@ -1,5 +1,5 @@ use common::{ - terrain::{chonk::Chonk, Block, BlockKind, SpriteKind}, + terrain::{chonk::Chonk, Block, BlockKind}, vol::{BaseVol, ReadVol, RectVolSize, WriteVol}, volumes::vol_grid_2d::VolGrid2d, }; @@ -132,8 +132,7 @@ pub trait VoxelImageEncoding { x: u32, y: u32, kind: BlockKind, - sprite: SpriteKind, - ori: Option, + sprite_data: [u8; 3], ); fn finish(ws: &Self::Workspace) -> Option; } @@ -168,10 +167,9 @@ impl<'a, VIE: VoxelImageEncoding> VoxelImageEncoding for &'a VIE { x: u32, y: u32, kind: BlockKind, - sprite: SpriteKind, - ori: Option, + sprite_data: [u8; 3], ) { - (*self).put_sprite(ws, x, y, kind, sprite, ori) + (*self).put_sprite(ws, x, y, kind, sprite_data) } fn finish(ws: &Self::Workspace) -> Option { VIE::finish(ws) } @@ -189,12 +187,13 @@ impl<'a, VIE: VoxelImageDecoding> VoxelImageDecoding for &'a VIE { pub struct QuadPngEncoding(); impl VoxelImageEncoding for QuadPngEncoding { - type Output = CompressedData<(Vec, [usize; 3])>; + type Output = CompressedData<(Vec, [usize; 3], Vec<[u8; 3]>)>; type Workspace = ( ImageBuffer, Vec>, ImageBuffer, Vec>, ImageBuffer, Vec>, ImageBuffer, Vec>, + Vec<[u8; 3]>, ); fn create(width: u32, height: u32) -> Self::Workspace { @@ -203,6 +202,7 @@ impl VoxelImageEncoding for QuadPngEncoding { ImageBuffer::new(width, height), ImageBuffer::new(width, height), ImageBuffer::new(width / N, height / N), + Vec::new(), ) } @@ -219,12 +219,18 @@ impl VoxelImageEncoding for QuadPngEncoding { x: u32, y: u32, kind: BlockKind, - sprite: SpriteKind, - ori: Option, + sprite_data: [u8; 3], ) { + let index: u16 = + ws.4.len() + .try_into() + .expect("Cannot have more than 2^16 sprites in one chunk"); + let index = index.to_be_bytes(); + ws.4.push(sprite_data); + ws.0.put_pixel(x, y, image::Luma([kind as u8])); - ws.1.put_pixel(x, y, image::Luma([sprite as u8])); - ws.2.put_pixel(x, y, image::Luma([ori.unwrap_or(0)])); + ws.1.put_pixel(x, y, image::Luma([index[0]])); + ws.2.put_pixel(x, y, image::Luma([index[1]])); } fn finish(ws: &Self::Workspace) -> Option { @@ -261,7 +267,7 @@ impl VoxelImageEncoding for QuadPngEncoding { .ok()?; } - Some(CompressedData::compress(&(buf, indices), 4)) + Some(CompressedData::compress(&(buf, indices, ws.4.clone()), 4)) } } @@ -320,7 +326,7 @@ const fn gen_lanczos_lookup( impl VoxelImageDecoding for QuadPngEncoding { fn start(data: &Self::Output) -> Option { use image::codecs::png::PngDecoder; - let (quad, indices) = data.decompress()?; + let (quad, indices, sprite_data) = data.decompress()?; let ranges: [_; 4] = [ 0..indices[0], indices[0]..indices[1], @@ -331,7 +337,7 @@ impl VoxelImageDecoding for QuadPngEncoding { let b = image_from_bytes(PngDecoder::new(&quad[ranges[1].clone()]).ok()?)?; let c = image_from_bytes(PngDecoder::new(&quad[ranges[2].clone()]).ok()?)?; let d = image_from_bytes(PngDecoder::new(&quad[ranges[3].clone()]).ok()?)?; - Some((a, b, c, d)) + Some((a, b, c, d, sprite_data)) } fn get_block(ws: &Self::Workspace, x: u32, y: u32, is_border: bool) -> Block { @@ -444,14 +450,9 @@ impl VoxelImageDecoding for QuadPngEncoding { b: rgb.z as u8, }) } else { - let mut block = Block::new(kind, Rgb { r: 0, g: 0, b: 0 }); - if let Some(spritekind) = SpriteKind::from_u8(ws.1.get_pixel(x, y).0[0]) { - block = block.with_sprite(spritekind); - } - if let Some(oriblock) = block.with_ori(ws.2.get_pixel(x, y).0[0]) { - block = oriblock; - } - block + let index = + u16::from_be_bytes([ws.1.get_pixel(x, y).0[0], ws.2.get_pixel(x, y).0[0]]); + Block::from_raw(kind, ws.4[index as usize]) } } else { Block::empty() @@ -463,12 +464,13 @@ impl VoxelImageDecoding for QuadPngEncoding { pub struct TriPngEncoding(); impl VoxelImageEncoding for TriPngEncoding { - type Output = CompressedData<(Vec, Vec>, [usize; 3])>; + type Output = CompressedData<(Vec, Vec>, [usize; 3], Vec<[u8; 3]>)>; type Workspace = ( ImageBuffer, Vec>, ImageBuffer, Vec>, ImageBuffer, Vec>, HashMap, usize>>, + Vec<[u8; 3]>, ); fn create(width: u32, height: u32) -> Self::Workspace { @@ -477,6 +479,7 @@ impl VoxelImageEncoding for TriPngEncoding VoxelImageEncoding for TriPngEncoding, + sprite_data: [u8; 3], ) { + let index: u16 = + ws.4.len() + .try_into() + .expect("Cannot have more than 2^16 sprites in one chunk"); + let index = index.to_be_bytes(); + ws.4.push(sprite_data); + ws.0.put_pixel(x, y, image::Luma([kind as u8])); - ws.1.put_pixel(x, y, image::Luma([sprite as u8])); - ws.2.put_pixel(x, y, image::Luma([ori.unwrap_or(0)])); + ws.1.put_pixel(x, y, image::Luma([index[0]])); + ws.2.put_pixel(x, y, image::Luma([index[1]])); } fn finish(ws: &Self::Workspace) -> Option { @@ -545,14 +554,17 @@ impl VoxelImageEncoding for TriPngEncoding VoxelImageDecoding for TriPngEncoding { fn start(data: &Self::Output) -> Option { use image::codecs::png::PngDecoder; - let (quad, palette, indices) = data.decompress()?; + let (quad, palette, indices, sprite_data) = data.decompress()?; let ranges: [_; 3] = [ 0..indices[0], indices[0]..indices[1], @@ -573,7 +585,7 @@ impl VoxelImageDecoding for TriPngEncoding Block { @@ -662,14 +674,9 @@ impl VoxelImageDecoding for TriPngEncoding { VIE::put_solid(vie, &mut image, i, j, *block, rgb); }, - (None, Some(sprite)) => { - VIE::put_sprite(vie, &mut image, i, j, *block, sprite, block.get_ori()); + (None, Some(_)) => { + let data = block.to_u32().to_be_bytes(); + + VIE::put_sprite(vie, &mut image, i, j, *block, [data[1], data[2], data[3]]); }, _ => panic!( "attr being used for color vs sprite is mutually exclusive (and that's \ diff --git a/common/src/terrain/block.rs b/common/src/terrain/block.rs index 1160c6877e..99423ebf71 100644 --- a/common/src/terrain/block.rs +++ b/common/src/terrain/block.rs @@ -157,7 +157,7 @@ impl Block { /* Constructors */ #[inline] - pub(super) const fn from_raw(kind: BlockKind, data: [u8; 3]) -> Self { Self { kind, data } } + pub const fn from_raw(kind: BlockKind, data: [u8; 3]) -> Self { Self { kind, data } } // TODO: Rename to `filled`, make caller guarantees stronger #[inline]