From 56c9d4489bf02c18d478220083535fe8b6946d8f Mon Sep 17 00:00:00 2001 From: JJJimbo1 <88861660+JJJimbo1@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:03:23 -0500 Subject: [PATCH] fix asymmetrical 9-slicing (#14148) # Objective Fixes #14147. ## Solution Modify the slicing checks and algorithm to fully allow asymmetrical textures to work. Some opinionated code cleanup. ## Testing Tested using the ui_texture_slice example and a custom asymmetrical texture. Before: ![asymmetrical_texture_slice_before](https://github.com/bevyengine/bevy/assets/88861660/00dafce1-904a-41ac-b5d9-faaf087b0681) After: ![asymmetrical_texture_slice_after](https://github.com/bevyengine/bevy/assets/88861660/f3d742f3-6157-4d35-b383-aee4b8f6e7d0) --------- Co-authored-by: Alice Cecile --- .../bevy_sprite/src/texture_slice/slicer.rs | 81 +++++++++---------- 1 file changed, 36 insertions(+), 45 deletions(-) diff --git a/crates/bevy_sprite/src/texture_slice/slicer.rs b/crates/bevy_sprite/src/texture_slice/slicer.rs index 2b69f6fc1f38d..b290272edd70d 100644 --- a/crates/bevy_sprite/src/texture_slice/slicer.rs +++ b/crates/bevy_sprite/src/texture_slice/slicer.rs @@ -126,11 +126,11 @@ impl TextureSlicer { ), }, draw_size: vec2( - bl_corner.draw_size.x, - render_size.y - (bl_corner.draw_size.y + tl_corner.draw_size.y), + tl_corner.draw_size.x, + render_size.y - (tl_corner.draw_size.y + bl_corner.draw_size.y), ), offset: vec2( - -render_size.x + bl_corner.draw_size.x, + tl_corner.draw_size.x - render_size.x, bl_corner.draw_size.y - tl_corner.draw_size.y, ) / 2.0, }, @@ -141,21 +141,21 @@ impl TextureSlicer { base_rect.max.x - self.border.right, base_rect.min.y + self.border.top, ), - max: vec2(base_rect.max.x, base_rect.max.y - self.border.bottom), + max: base_rect.max - vec2(0.0, self.border.bottom), }, draw_size: vec2( - br_corner.draw_size.x, - render_size.y - (br_corner.draw_size.y + tr_corner.draw_size.y), + tr_corner.draw_size.x, + render_size.y - (tr_corner.draw_size.y + br_corner.draw_size.y), ), offset: vec2( - render_size.x - br_corner.draw_size.x, + render_size.x - tr_corner.draw_size.x, br_corner.draw_size.y - tr_corner.draw_size.y, ) / 2.0, }, ] } - /// Computes the 2 vertical side slices (bottom and top borders) + /// Computes the 2 vertical side slices (top and bottom borders) #[must_use] fn vertical_side_slices( &self, @@ -164,24 +164,6 @@ impl TextureSlicer { render_size: Vec2, ) -> [TextureSlice; 2] { [ - // Bottom - TextureSlice { - texture_rect: Rect { - min: vec2( - base_rect.min.x + self.border.left, - base_rect.max.y - self.border.bottom, - ), - max: vec2(base_rect.max.x - self.border.right, base_rect.max.y), - }, - draw_size: vec2( - render_size.x - (bl_corner.draw_size.x + br_corner.draw_size.x), - bl_corner.draw_size.y, - ), - offset: vec2( - (bl_corner.draw_size.x - br_corner.draw_size.x) / 2.0, - bl_corner.offset.y, - ), - }, // Top TextureSlice { texture_rect: Rect { @@ -196,9 +178,27 @@ impl TextureSlicer { tl_corner.draw_size.y, ), offset: vec2( - (tl_corner.draw_size.x - tr_corner.draw_size.x) / 2.0, - tl_corner.offset.y, + tl_corner.draw_size.x - tr_corner.draw_size.x, + render_size.y - tl_corner.draw_size.y, + ) / 2.0, + }, + // Bottom + TextureSlice { + texture_rect: Rect { + min: vec2( + base_rect.min.x + self.border.left, + base_rect.max.y - self.border.bottom, + ), + max: base_rect.max - vec2(self.border.right, 0.0), + }, + draw_size: vec2( + render_size.x - (bl_corner.draw_size.x + br_corner.draw_size.x), + bl_corner.draw_size.y, ), + offset: vec2( + bl_corner.draw_size.x - br_corner.draw_size.x, + bl_corner.draw_size.y - render_size.y, + ) / 2.0, }, ] } @@ -216,11 +216,8 @@ impl TextureSlicer { #[must_use] pub fn compute_slices(&self, rect: Rect, render_size: Option) -> Vec { let render_size = render_size.unwrap_or_else(|| rect.size()); - let rect_size = rect.size() / 2.0; - if self.border.left >= rect_size.x - || self.border.right >= rect_size.x - || self.border.top >= rect_size.y - || self.border.bottom >= rect_size.y + if self.border.left + self.border.right >= rect.size().x + || self.border.top + self.border.bottom >= rect.size().y { bevy_utils::tracing::error!( "TextureSlicer::border has out of bounds values. No slicing will be applied" @@ -234,7 +231,7 @@ impl TextureSlicer { let mut slices = Vec::with_capacity(9); // Corners are in this order: [TL, TR, BL, BR] let corners = self.corner_slices(rect, render_size); - // Vertical Sides: [B, T] + // Vertical Sides: [T, B] let vertical_sides = self.vertical_side_slices(&corners, rect, render_size); // Horizontal Sides: [L, R] let horizontal_sides = self.horizontal_side_slices(&corners, rect, render_size); @@ -242,19 +239,13 @@ impl TextureSlicer { let center = TextureSlice { texture_rect: Rect { min: rect.min + vec2(self.border.left, self.border.top), - max: vec2( - rect.max.x - self.border.right, - rect.max.y - self.border.bottom, - ), + max: rect.max - vec2(self.border.right, self.border.bottom), }, draw_size: vec2( - render_size.x - (corners[2].draw_size.x + corners[3].draw_size.x), - render_size.y - (corners[2].draw_size.y + corners[0].draw_size.y), - ), - offset: Vec2::new( - (corners[0].draw_size.x - corners[3].draw_size.x) / 2.0, - (corners[2].draw_size.y - corners[0].draw_size.y) / 2.0, + render_size.x - (corners[0].draw_size.x + corners[1].draw_size.x), + render_size.y - (corners[0].draw_size.y + corners[2].draw_size.y), ), + offset: vec2(vertical_sides[0].offset.x, horizontal_sides[0].offset.y), }; slices.extend(corners); @@ -399,7 +390,7 @@ mod test { } ); assert_eq!( - vertical_sides[1], /* top */ + vertical_sides[0], /* top */ TextureSlice { texture_rect: Rect { min: Vec2::new(5.0, 0.0),