fix a couple bugs which could cause chunks to get eaten away across reloads

mainly related to me not knowing how to decode WebP properly (I blame the API design of the webp crate)
turns out it can return RGB images instead of RGBA and so you have to convert it to RGBA first

there were also a couple math bugs with chunk drawing/saving related to some of my refactors of that math
This commit is contained in:
liquidex 2024-08-24 17:18:44 +02:00
parent c55f5e054c
commit fb0e15c00c
3 changed files with 26 additions and 7 deletions

View file

@ -21,7 +21,7 @@ use tokio::{
select,
sync::{mpsc, oneshot},
};
use tracing::{error, instrument};
use tracing::{error, info, instrument};
use crate::{
haku::{Haku, Limits},
@ -450,7 +450,7 @@ fn chunks_to_modify(wall: &Wall, points: &[Vec2]) -> HashSet<ChunkPosition> {
let top_left_chunk = wall.settings().chunk_at(Vec2::new(left, top));
let bottom_right_chunk = wall
.settings()
.chunk_at(Vec2::new(left + paint_area, top + paint_area));
.chunk_at_ceil(Vec2::new(left + paint_area, top + paint_area));
for chunk_y in top_left_chunk.y..bottom_right_chunk.y {
for chunk_x in top_left_chunk.x..bottom_right_chunk.x {
chunks.insert(ChunkPosition::new(chunk_x, chunk_y));
@ -472,8 +472,8 @@ fn draw_to_chunks(wall: &Wall, haku: &Haku, value: Value, center: Vec2) -> eyre:
let left_chunk = settings.chunk_at_1d(left);
let top_chunk = settings.chunk_at_1d(top);
let right_chunk = settings.chunk_at_1d(left + paint_area);
let bottom_chunk = settings.chunk_at_1d(top + paint_area);
let right_chunk = settings.chunk_at_1d_ceil(left + paint_area);
let bottom_chunk = settings.chunk_at_1d_ceil(top + paint_area);
for chunk_y in top_chunk..bottom_chunk {
for chunk_x in left_chunk..right_chunk {
let x = f32::floor(-chunk_x as f32 * chunk_size + center.x);

View file

@ -128,9 +128,20 @@ impl Settings {
f32::floor(x / self.chunk_size as f32) as i32
}
pub fn chunk_at_1d_ceil(&self, x: f32) -> i32 {
f32::ceil(x / self.chunk_size as f32) as i32
}
pub fn chunk_at(&self, position: Vec2) -> ChunkPosition {
ChunkPosition::new(self.chunk_at_1d(position.x), self.chunk_at_1d(position.y))
}
pub fn chunk_at_ceil(&self, position: Vec2) -> ChunkPosition {
ChunkPosition::new(
self.chunk_at_1d_ceil(position.x),
self.chunk_at_1d_ceil(position.y),
)
}
}
pub struct Wall {

View file

@ -160,7 +160,14 @@ impl ChunkImageLoop {
webp::Decoder::new(data)
.decode()
.and_then(|image| {
info!(?position, "decoded");
info!(
?position,
width = image.width(),
height = image.height(),
data_len = image.len(),
"decoded"
);
let image = image.to_image().into_rgba8();
let size = IntSize::from_wh(image.width(), image.height())?;
Pixmap::from_vec(image.to_vec(), size)
})
@ -173,15 +180,16 @@ impl ChunkImageLoop {
// I don't know yet if locking all the chunks is a good idea at this point.
// I can imagine contended chunks having some trouble loading.
let chunk_arcs: Vec<_> = chunks
let chunk_arcs: Vec<_> = decoded
.iter()
.map(|ChunkDataPair { position, .. }| self.wall.get_or_create_chunk(*position))
.map(|(position, _)| self.wall.get_or_create_chunk(*position))
.collect();
let mut chunk_refs = Vec::with_capacity(chunk_arcs.len());
for arc in &chunk_arcs {
chunk_refs.push(arc.lock().await);
}
info!(num = ?chunk_refs.len(), "replacing chunks' pixmaps");
for ((_, pixmap), mut chunk) in decoded.into_iter().zip(chunk_refs) {
chunk.pixmap = pixmap;
}