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 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<usize> {
pub fn write_image(&mut self, path: &Path) -> Result<usize> {
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,
},
);

View File

@ -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(),