From 9ee22d361839a89bc7c638024a3473ff2eec4c4e Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 5 Jan 2024 12:17:00 -0800 Subject: [PATCH] Added margin --- crates/packer/src/atlasset.rs | 34 ++++++++++++++++++++++++---------- crates/packer/src/main.rs | 6 +++--- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/crates/packer/src/atlasset.rs b/crates/packer/src/atlasset.rs index 80ee0e5..3223376 100644 --- a/crates/packer/src/atlasset.rs +++ b/crates/packer/src/atlasset.rs @@ -1,6 +1,6 @@ use anyhow::{bail, Context, Result}; use galactica_packer::{SpriteAtlas, SpriteAtlasImage}; -use image::{imageops, ImageBuffer, Rgba, RgbaImage}; +use image::{imageops, GenericImageView, ImageBuffer, Rgba, RgbaImage}; use std::{ fs::File, io::{Read, Write}, @@ -51,6 +51,9 @@ pub struct AtlasSet { /// The root directory that contains all image files. /// Files outside this directory will not be packed. asset_root: PathBuf, + + /// Leave an empty border this many pixels wide around each image + image_margin: u32, } impl AtlasSet { @@ -59,6 +62,7 @@ impl AtlasSet { texture_height: u32, texture_limit: usize, asset_root: &Path, + image_margin: u32, ) -> Self { Self { asset_root: asset_root.to_path_buf(), @@ -71,11 +75,12 @@ impl AtlasSet { index: SpriteAtlas::new(), used_area: 0f64, image_y_start: Vec::new(), + image_margin, } } /// Add a sprite to this atlas set - pub fn write_image(&mut self, path: &Path, dim: [u32; 2]) -> Result { + pub fn write_image(&mut self, path: &Path) -> Result { let mut f = File::open(&path)?; let mut bytes = Vec::new(); f.read_to_end(&mut bytes) @@ -83,6 +88,13 @@ impl AtlasSet { let img = image::load_from_memory(&bytes) .with_context(|| format!("While loading file `{}`", path.display()))?; + let image_dim = img.dimensions(); + + let dim = [ + image_dim.0 + 2 * self.image_margin, + image_dim.1 + 2 * self.image_margin, + ]; + let mut x = 0; let mut y = 0; let mut final_atlas_idx = None; @@ -113,8 +125,6 @@ impl AtlasSet { if dim[0] >= sd[0] || dim[1] >= sd[1] { y = sy; } - } else { - self.image_y_start.push((0, [u32::MAX, u32::MAX])); } let mut free = false; @@ -156,8 +166,12 @@ impl AtlasSet { }; // We found a spot for this image, write it. - //let img = RgbaImage::from_pixel(dim[0], dim[1], Rgba([0, 0, 0, 255])); - imageops::overlay(&mut self.texture_list[atlas_idx], &img, x.into(), y.into()); + imageops::overlay( + &mut self.texture_list[atlas_idx], + &img, + (x + self.image_margin).into(), + (y + self.image_margin).into(), + ); self.used_regions[atlas_idx].push(([x, y], dim)); self.used_area += dim[0] as f64 * dim[1] as f64; @@ -182,10 +196,10 @@ impl AtlasSet { p.to_path_buf(), SpriteAtlasImage { atlas: atlas_idx as u32, - x: x as f32 / self.texture_width as f32, - y: y as f32 / self.texture_height as f32, - w: dim[0] as f32 / self.texture_width as f32, - h: dim[1] as f32 / self.texture_height as f32, + x: (x + self.image_margin) as f32 / self.texture_width as f32, + y: (y + self.image_margin) as f32 / self.texture_height as f32, + w: image_dim.0 as f32 / self.texture_width as f32, + h: image_dim.1 as f32 / self.texture_height as f32, }, ); diff --git a/crates/packer/src/main.rs b/crates/packer/src/main.rs index 37d7bb4..b0a888d 100644 --- a/crates/packer/src/main.rs +++ b/crates/packer/src/main.rs @@ -64,13 +64,13 @@ fn main() -> Result<()> { } // Create atlas set - let mut atlas_set = AtlasSet::new(8192, 8192, 16, &asset_root); + let mut atlas_set = AtlasSet::new(8192, 8192, 16, &asset_root, 2); let total = files.len(); let mut i = 0; let mut peak_efficiency = 0f64; - for (path, dim) in files { + for (path, _) in files { i += 1; - let atlas_idx = atlas_set.write_image(&path, dim)?; + let atlas_idx = atlas_set.write_image(&path)?; println!( "({i} of {total}, atlas {atlas_idx}, efficiency {:.02}%) Added {}", 100.0 * atlas_set.get_efficiency(),