From 700a36299a5229b9585c7304068dbcd12dc0c472 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 1 Dec 2020 16:27:14 +0700 Subject: [PATCH 1/6] Change`TextureAtlasBuilder` into expected Builder conventions --- .../bevy_sprite/src/texture_atlas_builder.rs | 77 +++++++++++++------ examples/2d/texture_atlas.rs | 2 +- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/crates/bevy_sprite/src/texture_atlas_builder.rs b/crates/bevy_sprite/src/texture_atlas_builder.rs index 906761ef027a8..ea8a2f3208c04 100644 --- a/crates/bevy_sprite/src/texture_atlas_builder.rs +++ b/crates/bevy_sprite/src/texture_atlas_builder.rs @@ -9,45 +9,65 @@ use rectangle_pack::{ }; use thiserror::Error; +#[derive(Debug, Error)] +pub enum TextureAtlasBuilderError { + #[error("could not pack textures into an atlas within the given bounds")] + NotEnoughSpace, +} + #[derive(Debug)] +/// A builder which is used to create a texture atlas from many individual +/// sprites. pub struct TextureAtlasBuilder { - pub textures: Vec>, - pub rects_to_place: GroupedRectsToPlace>, - pub initial_size: Vec2, - pub max_size: Vec2, + /// The grouped rects which must be placed with a key value pair of a + /// texture handle to an index. + rects_to_place: GroupedRectsToPlace>, + /// The sprite size in pixels. + initial_size: Vec2, + /// The absolute maximum size of a sprite sheet in pixels. + max_size: Vec2, } impl Default for TextureAtlasBuilder { fn default() -> Self { - Self::new(Vec2::new(256., 256.), Vec2::new(2048., 2048.)) + Self { + rects_to_place: GroupedRectsToPlace::new(), + initial_size: Vec2::new(256., 256.), + max_size: Vec2::new(2048., 2048.), + } } } -#[derive(Debug, Error)] -pub enum RectanglePackError { - #[error("could not pack textures into an atlas within the given bounds")] - NotEnoughSpace, -} +pub type TextureAtlasBuilderResult = Result; impl TextureAtlasBuilder { - pub fn new(initial_size: Vec2, max_size: Vec2) -> Self { - Self { - textures: Default::default(), - rects_to_place: GroupedRectsToPlace::new(), - initial_size, - max_size, - } + /// Constructs a new texture atlas builder. + pub fn new() -> Self { + Self::default() + } + + /// Sets the initial size of the atlas in pixels. + pub fn initial_size(mut self, size: Vec2) -> Self { + self.initial_size = size; + self + } + + /// Sets the max size of the atlas in pixels. + pub fn max_size(mut self, size: Vec2) -> Self { + self.max_size = size; + self } - pub fn add_texture(&mut self, texture_handle: Handle, texture: &Texture) { + /// Adds a texture to be copied to the texture atlas. + pub fn add_texture(&mut self, texture_handle: Handle, width: u32, height: u32) { self.rects_to_place.push_rect( texture_handle, None, - RectToInsert::new(texture.size.width, texture.size.height, 1), + RectToInsert::new(width, height, 1), ) } - fn place_texture( + fn copy_texture( &mut self, atlas_texture: &mut Texture, texture: &Texture, @@ -70,10 +90,21 @@ impl TextureAtlasBuilder { } } + /// Consumes the builder and returns a result with a new texture atlas. + /// + /// Internally it copies all rectangles from the textures and copies them + /// into a new texture which the texture atlas will use. It is not useful to + /// hold a strong handle to the texture afterwards else it will exist twice + /// in memory. + /// + /// # Errors + /// + /// If there is not enough space in the atlas texture, an error will + /// be returned. It is then recommended to make a larger sprite sheet. pub fn finish( mut self, textures: &mut Assets, - ) -> Result { + ) -> Result { let initial_width = self.initial_size.x as u32; let initial_height = self.initial_size.y as u32; let max_width = self.max_size.x as u32; @@ -120,7 +151,7 @@ impl TextureAtlasBuilder { } } - let rect_placements = rect_placements.ok_or(RectanglePackError::NotEnoughSpace)?; + let rect_placements = rect_placements.ok_or(TextureAtlasBuilderError::NotEnoughSpace)?; let mut texture_rects = Vec::with_capacity(rect_placements.packed_locations().len()); let mut texture_handles = HashMap::default(); @@ -134,7 +165,7 @@ impl TextureAtlasBuilder { ); texture_handles.insert(texture_handle.clone_weak(), texture_rects.len()); texture_rects.push(Rect { min, max }); - self.place_texture(&mut atlas_texture, texture, packed_location); + self.copy_texture(&mut atlas_texture, texture, packed_location); } Ok(TextureAtlas { size: atlas_texture.size.as_vec3().truncate(), diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index 4879641926e5d..3161d9919e8e1 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -38,7 +38,7 @@ fn load_atlas( { for handle in rpg_sprite_handles.handles.iter() { let texture = textures.get(handle).unwrap(); - texture_atlas_builder.add_texture(handle.clone_weak().typed::(), &texture); + texture_atlas_builder.add_texture(handle.clone_weak().typed::(), texture.size.width, texture.size.height); } let texture_atlas = texture_atlas_builder.finish(&mut textures).unwrap(); From df57c7e8fb75f1bb11dfc63d05d6012abae2af89 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 1 Dec 2020 16:30:48 +0700 Subject: [PATCH 2/6] Revert needless API breaking change. --- crates/bevy_sprite/src/texture_atlas_builder.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_sprite/src/texture_atlas_builder.rs b/crates/bevy_sprite/src/texture_atlas_builder.rs index ea8a2f3208c04..f83bcf4ae71a6 100644 --- a/crates/bevy_sprite/src/texture_atlas_builder.rs +++ b/crates/bevy_sprite/src/texture_atlas_builder.rs @@ -59,11 +59,11 @@ impl TextureAtlasBuilder { } /// Adds a texture to be copied to the texture atlas. - pub fn add_texture(&mut self, texture_handle: Handle, width: u32, height: u32) { + pub fn add_texture(&mut self, texture_handle: Handle, texture: &Texture) { self.rects_to_place.push_rect( texture_handle, None, - RectToInsert::new(width, height, 1), + RectToInsert::new(texture.size.width, texture.size.height, 1), ) } From d1a5688d99571d6f8fc688f5f342076d31d5311b Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 1 Dec 2020 16:46:30 +0700 Subject: [PATCH 3/6] Cargo fmt --- examples/2d/texture_atlas.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index 3161d9919e8e1..6e355723b832a 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -38,7 +38,11 @@ fn load_atlas( { for handle in rpg_sprite_handles.handles.iter() { let texture = textures.get(handle).unwrap(); - texture_atlas_builder.add_texture(handle.clone_weak().typed::(), texture.size.width, texture.size.height); + texture_atlas_builder.add_texture( + handle.clone_weak().typed::(), + texture.size.width, + texture.size.height, + ); } let texture_atlas = texture_atlas_builder.finish(&mut textures).unwrap(); From 94959b117a2db5ad284972a534d99a16de7e5c48 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Tue, 1 Dec 2020 16:56:06 +0700 Subject: [PATCH 4/6] Revert use --- examples/2d/texture_atlas.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index 6e355723b832a..fbe6db078d062 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -38,11 +38,7 @@ fn load_atlas( { for handle in rpg_sprite_handles.handles.iter() { let texture = textures.get(handle).unwrap(); - texture_atlas_builder.add_texture( - handle.clone_weak().typed::(), - texture.size.width, - texture.size.height, - ); + texture_atlas_builder.add_texture(handle.clone_weak().typed::(), texture); } let texture_atlas = texture_atlas_builder.finish(&mut textures).unwrap(); From ca73ae183c453448b0c2b685c19f8db8418fc588 Mon Sep 17 00:00:00 2001 From: "Joshua J. Bouw" Date: Thu, 3 Dec 2020 00:02:51 +0700 Subject: [PATCH 5/6] Remove `new` --- crates/bevy_sprite/src/texture_atlas_builder.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crates/bevy_sprite/src/texture_atlas_builder.rs b/crates/bevy_sprite/src/texture_atlas_builder.rs index f83bcf4ae71a6..9245e1244f3b9 100644 --- a/crates/bevy_sprite/src/texture_atlas_builder.rs +++ b/crates/bevy_sprite/src/texture_atlas_builder.rs @@ -41,11 +41,6 @@ impl Default for TextureAtlasBuilder { pub type TextureAtlasBuilderResult = Result; impl TextureAtlasBuilder { - /// Constructs a new texture atlas builder. - pub fn new() -> Self { - Self::default() - } - /// Sets the initial size of the atlas in pixels. pub fn initial_size(mut self, size: Vec2) -> Self { self.initial_size = size; From 7afccb2abb6e900dae2ff059a0e45358b6fb5630 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Wed, 2 Dec 2020 11:37:30 -0800 Subject: [PATCH 6/6] Update texture_atlas_builder.rs --- crates/bevy_sprite/src/texture_atlas_builder.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_sprite/src/texture_atlas_builder.rs b/crates/bevy_sprite/src/texture_atlas_builder.rs index 9245e1244f3b9..2be6d0058e04d 100644 --- a/crates/bevy_sprite/src/texture_atlas_builder.rs +++ b/crates/bevy_sprite/src/texture_atlas_builder.rs @@ -22,9 +22,9 @@ pub struct TextureAtlasBuilder { /// The grouped rects which must be placed with a key value pair of a /// texture handle to an index. rects_to_place: GroupedRectsToPlace>, - /// The sprite size in pixels. + /// The initial atlas size in pixels. initial_size: Vec2, - /// The absolute maximum size of a sprite sheet in pixels. + /// The absolute maximum size of the texture atlas in pixels. max_size: Vec2, }