Added margin
parent
eabc1ebd37
commit
9ee22d3618
|
@ -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,
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Reference in New Issue