Skip to content

Commit adf6bc5

Browse files
committed
Rect slicing
1 parent e2557c0 commit adf6bc5

File tree

2 files changed

+49
-37
lines changed

2 files changed

+49
-37
lines changed

crates/bevy_sprite/src/render/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,13 @@ pub fn extract_sprites(
365365
};
366366

367367
let slices = match &sprite.draw_mode {
368-
SpriteDrawMode::Sliced(slicer) => {
369-
slicer.compute_slices(image_size, sprite.custom_size.unwrap_or(image_size))
370-
}
368+
SpriteDrawMode::Sliced(slicer) => slicer.compute_slices(
369+
Rect {
370+
min: Vec2::ZERO,
371+
max: image_size,
372+
},
373+
sprite.custom_size,
374+
),
371375
SpriteDrawMode::Tiled {
372376
tile_x,
373377
tile_y,
@@ -592,7 +596,7 @@ pub fn queue_sprites(
592596
};
593597
let mut current_batch_entity = Entity::from_raw(u32::MAX);
594598
let mut current_image_size = Vec2::ZERO;
595-
// Add a phase item for each sprite, and detect when succesive items can be batched.
599+
// Add a phase item for each sprite, and detect when successive items can be batched.
596600
// Spawn an entity with a `SpriteBatch` component for each possible batch.
597601
// Compatible items share the same entity.
598602
// Batches are merged later (in `batch_phase_system()`), so that they can be interrupted

crates/bevy_sprite/src/texture_slice.rs

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,16 @@ pub(crate) struct TextureSlice {
5454

5555
impl TextureSlicer {
5656
/// Computes the 4 corner slices
57-
pub(crate) fn corner_slices(&self, image_size: Vec2, render_size: Vec2) -> [TextureSlice; 4] {
57+
fn corner_slices(&self, base_rect: Rect, render_size: Vec2) -> [TextureSlice; 4] {
58+
let image_size = base_rect.size();
5859
let coef = render_size / image_size;
5960
let min_coef = coef.x.min(coef.y).min(self.max_corner_scale.max(0.001));
6061
[
6162
// Top Left Corner
6263
TextureSlice {
6364
texture_rect: Rect {
64-
min: Vec2::ZERO,
65-
max: Vec2::new(self.border.left, self.border.top),
65+
min: base_rect.min,
66+
max: base_rect.min + Vec2::new(self.border.left, self.border.top),
6667
},
6768
draw_size: Vec2::new(self.border.left, self.border.top) * min_coef,
6869
offset: Vec2::new(
@@ -73,8 +74,8 @@ impl TextureSlicer {
7374
// Top Right Corner
7475
TextureSlice {
7576
texture_rect: Rect {
76-
min: Vec2::new(image_size.x - self.border.right, 0.0),
77-
max: Vec2::new(image_size.x, self.border.top),
77+
min: base_rect.min + Vec2::new(image_size.x - self.border.right, 0.0),
78+
max: base_rect.min + Vec2::new(image_size.x, self.border.top),
7879
},
7980
draw_size: Vec2::new(self.border.right, self.border.top) * min_coef,
8081
offset: Vec2::new(
@@ -85,8 +86,8 @@ impl TextureSlicer {
8586
// Bottom Left
8687
TextureSlice {
8788
texture_rect: Rect {
88-
min: Vec2::new(0.0, image_size.y - self.border.bottom),
89-
max: Vec2::new(self.border.left, image_size.y),
89+
min: base_rect.min + Vec2::new(0.0, image_size.y - self.border.bottom),
90+
max: base_rect.min + Vec2::new(self.border.left, image_size.y),
9091
},
9192
draw_size: Vec2::new(self.border.left, self.border.bottom) * min_coef,
9293
offset: Vec2::new(
@@ -97,11 +98,12 @@ impl TextureSlicer {
9798
// Bottom Right Corner
9899
TextureSlice {
99100
texture_rect: Rect {
100-
min: Vec2::new(
101-
image_size.x - self.border.right,
102-
image_size.y - self.border.bottom,
103-
),
104-
max: Vec2::new(image_size.x, image_size.y),
101+
min: base_rect.min
102+
+ Vec2::new(
103+
image_size.x - self.border.right,
104+
image_size.y - self.border.bottom,
105+
),
106+
max: base_rect.min + Vec2::new(image_size.x, image_size.y),
105107
},
106108
draw_size: Vec2::new(self.border.right, self.border.bottom) * min_coef,
107109
offset: Vec2::new(
@@ -113,17 +115,18 @@ impl TextureSlicer {
113115
}
114116

115117
/// Computes the 2 horizontal side slices (left and right borders)
116-
pub(crate) fn horizontal_side_slices(
118+
fn horizontal_side_slices(
117119
&self,
118120
[tl_corner, tr_corner, bl_corner, br_corner]: &[TextureSlice; 4],
119-
image_size: Vec2,
121+
base_rect: Rect,
120122
render_size: Vec2,
121123
) -> [TextureSlice; 2] {
124+
let image_size = base_rect.size();
122125
// left
123126
let left_side = TextureSlice {
124127
texture_rect: Rect {
125-
min: Vec2::new(0.0, self.border.top),
126-
max: Vec2::new(self.border.left, image_size.y - self.border.bottom),
128+
min: base_rect.min + Vec2::new(0.0, self.border.top),
129+
max: base_rect.min + Vec2::new(self.border.left, image_size.y - self.border.bottom),
127130
},
128131
draw_size: Vec2::new(
129132
bl_corner.draw_size.x,
@@ -135,8 +138,9 @@ impl TextureSlicer {
135138
// right
136139
let right_side = TextureSlice {
137140
texture_rect: Rect {
138-
min: Vec2::new(image_size.x - self.border.right, self.border.bottom),
139-
max: Vec2::new(image_size.x, image_size.y - self.border.top),
141+
min: base_rect.min
142+
+ Vec2::new(image_size.x - self.border.right, self.border.bottom),
143+
max: base_rect.min + Vec2::new(image_size.x, image_size.y - self.border.top),
140144
},
141145
draw_size: Vec2::new(
142146
br_corner.draw_size.x,
@@ -148,17 +152,18 @@ impl TextureSlicer {
148152
}
149153

150154
/// Computes the 2 vertical side slices (top and bottom borders)
151-
pub(crate) fn vertical_side_slices(
155+
fn vertical_side_slices(
152156
&self,
153157
[tl_corner, tr_corner, bl_corner, br_corner]: &[TextureSlice; 4],
154-
image_size: Vec2,
158+
base_rect: Rect,
155159
render_size: Vec2,
156160
) -> [TextureSlice; 2] {
161+
let image_size = base_rect.size();
157162
// Bottom
158163
let bot_side = TextureSlice {
159164
texture_rect: Rect {
160-
min: Vec2::new(self.border.left, image_size.y - self.border.bottom),
161-
max: Vec2::new(image_size.x - self.border.right, image_size.y),
165+
min: base_rect.min + Vec2::new(self.border.left, image_size.y - self.border.bottom),
166+
max: base_rect.min + Vec2::new(image_size.x - self.border.right, image_size.y),
162167
},
163168
draw_size: Vec2::new(
164169
render_size.x - (bl_corner.draw_size.x + br_corner.draw_size.x),
@@ -170,8 +175,8 @@ impl TextureSlicer {
170175
// Top
171176
let top_side = TextureSlice {
172177
texture_rect: Rect {
173-
min: Vec2::new(self.border.left, 0.0),
174-
max: Vec2::new(image_size.x - self.border.right, self.border.top),
178+
min: base_rect.min + Vec2::new(self.border.left, 0.0),
179+
max: base_rect.min + Vec2::new(image_size.x - self.border.right, self.border.top),
175180
},
176181
draw_size: Vec2::new(
177182
render_size.x - (tl_corner.draw_size.x + tr_corner.draw_size.x),
@@ -182,21 +187,24 @@ impl TextureSlicer {
182187
[bot_side, top_side]
183188
}
184189

185-
pub(crate) fn compute_slices(&self, image_size: Vec2, render_size: Vec2) -> Vec<TextureSlice> {
190+
pub(crate) fn compute_slices(
191+
&self,
192+
rect: Rect,
193+
render_size: Option<Vec2>,
194+
) -> Vec<TextureSlice> {
195+
let render_size = render_size.unwrap_or_else(|| rect.size());
186196
let mut slices = Vec::with_capacity(9);
187197
// Corners
188-
let corners = self.corner_slices(image_size, render_size);
198+
let corners = self.corner_slices(rect, render_size);
189199
// Sides
190-
let vertical_sides = self.vertical_side_slices(&corners, image_size, render_size);
191-
let horizontal_sides = self.horizontal_side_slices(&corners, image_size, render_size);
200+
let vertical_sides = self.vertical_side_slices(&corners, rect, render_size);
201+
let horizontal_sides = self.horizontal_side_slices(&corners, rect, render_size);
192202
// Center
193203
let center = TextureSlice {
194204
texture_rect: Rect {
195-
min: Vec2::new(self.border.left, self.border.bottom),
196-
max: Vec2::new(
197-
image_size.x - self.border.right,
198-
image_size.y - self.border.top,
199-
),
205+
min: rect.min + Vec2::new(self.border.left, self.border.bottom),
206+
max: rect.min
207+
+ Vec2::new(rect.max.x - self.border.right, rect.max.y - self.border.top),
200208
},
201209
draw_size: Vec2::new(
202210
render_size.x - (corners[2].draw_size.x + corners[3].draw_size.x),

0 commit comments

Comments
 (0)