diff --git a/crates/packer/src/atlasset.rs b/crates/packer/src/atlasset.rs index 16d048b..d1989b0 100644 --- a/crates/packer/src/atlasset.rs +++ b/crates/packer/src/atlasset.rs @@ -4,6 +4,7 @@ use image::{imageops, GenericImageView, ImageBuffer, Rgba, RgbaImage}; use std::{ fs::File, io::{Read, Write}, + num::NonZeroU32, path::{Path, PathBuf}, }; @@ -205,19 +206,19 @@ impl AtlasSet { ) })?; - self.index - .path_map - .insert(p.to_path_buf(), self.index.index.len() as u32); - - self.index.index.push(SpriteAtlasImage { - true_size: image_dim, - idx: self.index.index.len() as u32, - atlas: atlas_idx as u32, - 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, - }); + self.index.push( + p, + SpriteAtlasImage { + true_size: image_dim, + // Add one to account for hidden texture + idx: NonZeroU32::new(self.index.len() as u32 + 1).unwrap(), + atlas: atlas_idx as u32, + 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, + }, + ); return Ok(atlas_idx); } diff --git a/crates/packer/src/lib.rs b/crates/packer/src/lib.rs index 204ad7b..7a6673f 100644 --- a/crates/packer/src/lib.rs +++ b/crates/packer/src/lib.rs @@ -2,7 +2,11 @@ //! This crate creates texture atlases from an asset tree. -use std::{collections::HashMap, path::PathBuf}; +use std::{ + collections::HashMap, + num::NonZeroU32, + path::{Path, PathBuf}, +}; use serde::{Deserialize, Serialize}; @@ -13,8 +17,9 @@ pub struct SpriteAtlasImage { /// This is an index in SpriteAtlas.atlas_list pub atlas: u32, - /// A globally unique, consecutively numbered index for this sprite - pub idx: u32, + /// A globally unique, consecutively numbered index for this sprite. + /// This is nonzero because index zero is reserved for the "hidden" texture. + pub idx: NonZeroU32, /// The size of this image, in pixels pub true_size: (u32, u32), @@ -41,10 +46,10 @@ pub struct SpriteAtlasImage { #[derive(Debug, Serialize, Deserialize, Clone)] pub struct SpriteAtlas { /// The images in this atlas - pub index: Vec, + pub(crate) index: Vec, /// Map paths to image indices - pub path_map: HashMap, + path_map: HashMap, /// The file names of the atlas textures we've generated pub atlas_list: Vec, @@ -59,4 +64,30 @@ impl SpriteAtlas { atlas_list: Vec::new(), } } + + /// Get a SpriteAtlasImage by index + pub fn get_by_idx(&self, idx: NonZeroU32) -> &SpriteAtlasImage { + &self.index[idx.get() as usize - 1] + } + + /// Get an image index from its path + /// returns None if this path isn't in this index + pub fn get_idx_by_path(&self, path: &Path) -> Option { + self.path_map.get(path).map(|x| *x) + } + + /// Get the number of images in this atlas + pub fn len(&self) -> u32 { + self.index.len() as u32 + } + + /// Add an image with the given path to this index + pub fn push(&mut self, p: &Path, i: SpriteAtlasImage) { + self.path_map.insert( + p.to_path_buf(), + NonZeroU32::new(self.index.len() as u32 + 1).unwrap(), + ); + + self.index.push(i); + } }