Added margin

master
Mark 2024-01-05 12:17:00 -08:00
parent eabc1ebd37
commit 9ee22d3618
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
2 changed files with 27 additions and 13 deletions

View File

@ -1,6 +1,6 @@
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use galactica_packer::{SpriteAtlas, SpriteAtlasImage}; use galactica_packer::{SpriteAtlas, SpriteAtlasImage};
use image::{imageops, ImageBuffer, Rgba, RgbaImage}; use image::{imageops, GenericImageView, ImageBuffer, Rgba, RgbaImage};
use std::{ use std::{
fs::File, fs::File,
io::{Read, Write}, io::{Read, Write},
@ -51,6 +51,9 @@ pub struct AtlasSet {
/// The root directory that contains all image files. /// The root directory that contains all image files.
/// Files outside this directory will not be packed. /// Files outside this directory will not be packed.
asset_root: PathBuf, asset_root: PathBuf,
/// Leave an empty border this many pixels wide around each image
image_margin: u32,
} }
impl AtlasSet { impl AtlasSet {
@ -59,6 +62,7 @@ impl AtlasSet {
texture_height: u32, texture_height: u32,
texture_limit: usize, texture_limit: usize,
asset_root: &Path, asset_root: &Path,
image_margin: u32,
) -> Self { ) -> Self {
Self { Self {
asset_root: asset_root.to_path_buf(), asset_root: asset_root.to_path_buf(),
@ -71,11 +75,12 @@ impl AtlasSet {
index: SpriteAtlas::new(), index: SpriteAtlas::new(),
used_area: 0f64, used_area: 0f64,
image_y_start: Vec::new(), image_y_start: Vec::new(),
image_margin,
} }
} }
/// Add a sprite to this atlas set /// Add a sprite to this atlas set
pub fn write_image(&mut self, path: &Path, dim: [u32; 2]) -> Result<usize> { pub fn write_image(&mut self, path: &Path) -> Result<usize> {
let mut f = File::open(&path)?; let mut f = File::open(&path)?;
let mut bytes = Vec::new(); let mut bytes = Vec::new();
f.read_to_end(&mut bytes) f.read_to_end(&mut bytes)
@ -83,6 +88,13 @@ impl AtlasSet {
let img = image::load_from_memory(&bytes) let img = image::load_from_memory(&bytes)
.with_context(|| format!("While loading file `{}`", path.display()))?; .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 x = 0;
let mut y = 0; let mut y = 0;
let mut final_atlas_idx = None; let mut final_atlas_idx = None;
@ -113,8 +125,6 @@ impl AtlasSet {
if dim[0] >= sd[0] || dim[1] >= sd[1] { if dim[0] >= sd[0] || dim[1] >= sd[1] {
y = sy; y = sy;
} }
} else {
self.image_y_start.push((0, [u32::MAX, u32::MAX]));
} }
let mut free = false; let mut free = false;
@ -156,8 +166,12 @@ impl AtlasSet {
}; };
// We found a spot for this image, write it. // 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(
imageops::overlay(&mut self.texture_list[atlas_idx], &img, x.into(), y.into()); &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_regions[atlas_idx].push(([x, y], dim));
self.used_area += dim[0] as f64 * dim[1] as f64; self.used_area += dim[0] as f64 * dim[1] as f64;
@ -182,10 +196,10 @@ impl AtlasSet {
p.to_path_buf(), p.to_path_buf(),
SpriteAtlasImage { SpriteAtlasImage {
atlas: atlas_idx as u32, atlas: atlas_idx as u32,
x: x as f32 / self.texture_width as f32, x: (x + self.image_margin) as f32 / self.texture_width as f32,
y: y as f32 / self.texture_height as f32, y: (y + self.image_margin) as f32 / self.texture_height as f32,
w: dim[0] as f32 / self.texture_width as f32, w: image_dim.0 as f32 / self.texture_width as f32,
h: dim[1] as f32 / self.texture_height as f32, h: image_dim.1 as f32 / self.texture_height as f32,
}, },
); );

View File

@ -64,13 +64,13 @@ fn main() -> Result<()> {
} }
// Create atlas set // 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 total = files.len();
let mut i = 0; let mut i = 0;
let mut peak_efficiency = 0f64; let mut peak_efficiency = 0f64;
for (path, dim) in files { for (path, _) in files {
i += 1; i += 1;
let atlas_idx = atlas_set.write_image(&path, dim)?; let atlas_idx = atlas_set.write_image(&path)?;
println!( println!(
"({i} of {total}, atlas {atlas_idx}, efficiency {:.02}%) Added {}", "({i} of {total}, atlas {atlas_idx}, efficiency {:.02}%) Added {}",
100.0 * atlas_set.get_efficiency(), 100.0 * atlas_set.get_efficiency(),