Skip to content

Commit

Permalink
Fix TextureAtlasBuilder padding (bevyengine#10031)
Browse files Browse the repository at this point in the history
# Objective

- Fix TextureAtlasBuilder padding issue

TextureAtlasBuilder padding is reserved during add_texture() but can
still be changed afterwards. This means that changing padding after the
textures will be wrongly applied, either distorting the textures or
panicking if new padding is higher than texture+old padding.


## Solution

- Delay applying padding until finish()
  • Loading branch information
s-puig authored and ameknite committed Nov 6, 2023
1 parent d643bff commit 4fdb382
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions crates/bevy_sprite/src/texture_atlas_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ pub enum TextureAtlasBuilderError {
/// A builder which is used to create a texture atlas from many individual
/// sprites.
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<AssetId<Image>>,
/// Collection of textures and their size to be packed into an atlas
textures_to_place: Vec<(AssetId<Image>, Extent3d)>,
/// The initial atlas size in pixels.
initial_size: Vec2,
/// The absolute maximum size of the texture atlas in pixels.
Expand All @@ -45,7 +44,7 @@ pub struct TextureAtlasBuilder {
impl Default for TextureAtlasBuilder {
fn default() -> Self {
Self {
rects_to_place: GroupedRectsToPlace::new(),
textures_to_place: Vec::new(),
initial_size: Vec2::new(256., 256.),
max_size: Vec2::new(2048., 2048.),
format: TextureFormat::Rgba8UnormSrgb,
Expand Down Expand Up @@ -84,15 +83,8 @@ impl TextureAtlasBuilder {

/// Adds a texture to be copied to the texture atlas.
pub fn add_texture(&mut self, image_id: AssetId<Image>, texture: &Image) {
self.rects_to_place.push_rect(
image_id,
None,
RectToInsert::new(
texture.texture_descriptor.size.width + self.padding.x,
texture.texture_descriptor.size.height + self.padding.y,
1,
),
);
self.textures_to_place
.push((image_id, texture.texture_descriptor.size));
}

/// Sets the amount of padding in pixels to add between the textures in the texture atlas.
Expand Down Expand Up @@ -177,6 +169,16 @@ impl TextureAtlasBuilder {
let mut current_height = initial_height;
let mut rect_placements = None;
let mut atlas_texture = Image::default();
let mut rects_to_place = GroupedRectsToPlace::<AssetId<Image>>::new();

// Adds textures to rectangle group packer
for (image_id, size) in &self.textures_to_place {
rects_to_place.push_rect(
*image_id,
None,
RectToInsert::new(size.width + self.padding.x, size.height + self.padding.y, 1),
);
}

while rect_placements.is_none() {
if current_width > max_width || current_height > max_height {
Expand All @@ -188,7 +190,7 @@ impl TextureAtlasBuilder {
let mut target_bins = std::collections::BTreeMap::new();
target_bins.insert(0, TargetBin::new(current_width, current_height, 1));
rect_placements = match pack_rects(
&self.rects_to_place,
&rects_to_place,
&mut target_bins,
&volume_heuristic,
&contains_smallest_box,
Expand Down

0 comments on commit 4fdb382

Please sign in to comment.