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