@@ -6,7 +6,7 @@ use bevy_asset::{AssetEvent, Assets};
6
6
use bevy_ecs:: prelude:: * ;
7
7
use bevy_math:: { Rect , Vec2 } ;
8
8
use bevy_render:: texture:: Image ;
9
- use bevy_sprite:: { ImageScaleMode , TextureSlice } ;
9
+ use bevy_sprite:: { ImageScaleMode , TextureAtlas , TextureAtlasLayout , TextureSlice } ;
10
10
use bevy_transform:: prelude:: * ;
11
11
use bevy_utils:: HashSet ;
12
12
@@ -74,25 +74,48 @@ impl ComputedTextureSlices {
74
74
}
75
75
76
76
/// Generates sprite slices for a `sprite` given a `scale_mode`. The slices
77
- /// will be computed according to the `image_handle` dimensions or the sprite rect .
77
+ /// will be computed according to the `image_handle` dimensions.
78
78
///
79
79
/// Returns `None` if the image asset is not loaded
80
+ ///
81
+ /// # Arguments
82
+ ///
83
+ /// * `draw_area` - The size of the drawing area the slices will have to fit into
84
+ /// * `scale_mode` - The image scaling component
85
+ /// * `image_handle` - The texture to slice or tile
86
+ /// * `images` - The image assets, use to retrieve the image dimensions
87
+ /// * `atlas` - Optional texture atlas, if set the slicing will happen on the matching sub section
88
+ /// of the texture
89
+ /// * `atlas_layouts` - The atlas layout assets, used to retrieve the texture atlas section rect
80
90
#[ must_use]
81
91
fn compute_texture_slices (
82
92
draw_area : Vec2 ,
83
93
scale_mode : & ImageScaleMode ,
84
94
image_handle : & UiImage ,
85
95
images : & Assets < Image > ,
96
+ atlas : Option < & TextureAtlas > ,
97
+ atlas_layouts : & Assets < TextureAtlasLayout > ,
86
98
) -> Option < ComputedTextureSlices > {
87
- let image_size = images. get ( & image_handle. texture ) . map ( |i| {
88
- Vec2 :: new (
89
- i. texture_descriptor . size . width as f32 ,
90
- i. texture_descriptor . size . height as f32 ,
91
- )
92
- } ) ?;
93
- let texture_rect = Rect {
94
- min : Vec2 :: ZERO ,
95
- max : image_size,
99
+ let ( image_size, texture_rect) = match atlas {
100
+ Some ( a) => {
101
+ let layout = atlas_layouts. get ( & a. layout ) ?;
102
+ (
103
+ layout. size . as_vec2 ( ) ,
104
+ layout. textures . get ( a. index ) ?. as_rect ( ) ,
105
+ )
106
+ }
107
+ None => {
108
+ let image = images. get ( & image_handle. texture ) ?;
109
+ let size = Vec2 :: new (
110
+ image. texture_descriptor . size . width as f32 ,
111
+ image. texture_descriptor . size . height as f32 ,
112
+ ) ;
113
+ let rect = Rect {
114
+ min : Vec2 :: ZERO ,
115
+ max : size,
116
+ } ;
117
+ ( size, rect)
118
+ }
96
119
} ;
97
120
let slices = match scale_mode {
98
121
ImageScaleMode :: Sliced ( slicer) => slicer. compute_slices ( texture_rect, Some ( draw_area) ) ,
@@ -118,7 +141,14 @@ pub(crate) fn compute_slices_on_asset_event(
118
141
mut commands : Commands ,
119
142
mut events : EventReader < AssetEvent < Image > > ,
120
143
images : Res < Assets < Image > > ,
121
- ui_nodes : Query < ( Entity , & ImageScaleMode , & Node , & UiImage ) > ,
144
+ atlas_layouts : Res < Assets < TextureAtlasLayout > > ,
145
+ ui_nodes : Query < (
146
+ Entity ,
147
+ & ImageScaleMode ,
148
+ & Node ,
149
+ & UiImage ,
150
+ Option < & TextureAtlas > ,
151
+ ) > ,
122
152
) {
123
153
// We store the asset ids of added/modified image assets
124
154
let added_handles: HashSet < _ > = events
@@ -132,11 +162,18 @@ pub(crate) fn compute_slices_on_asset_event(
132
162
return ;
133
163
}
134
164
// We recompute the sprite slices for sprite entities with a matching asset handle id
135
- for ( entity, scale_mode, ui_node, image) in & ui_nodes {
165
+ for ( entity, scale_mode, ui_node, image, atlas ) in & ui_nodes {
136
166
if !added_handles. contains ( & image. texture . id ( ) ) {
137
167
continue ;
138
168
}
139
- if let Some ( slices) = compute_texture_slices ( ui_node. size ( ) , scale_mode, image, & images) {
169
+ if let Some ( slices) = compute_texture_slices (
170
+ ui_node. size ( ) ,
171
+ scale_mode,
172
+ image,
173
+ & images,
174
+ atlas,
175
+ & atlas_layouts,
176
+ ) {
140
177
commands. entity ( entity) . insert ( slices) ;
141
178
}
142
179
}
@@ -147,13 +184,32 @@ pub(crate) fn compute_slices_on_asset_event(
147
184
pub ( crate ) fn compute_slices_on_image_change (
148
185
mut commands : Commands ,
149
186
images : Res < Assets < Image > > ,
187
+ atlas_layouts : Res < Assets < TextureAtlasLayout > > ,
150
188
changed_nodes : Query <
151
- ( Entity , & ImageScaleMode , & Node , & UiImage ) ,
152
- Or < ( Changed < ImageScaleMode > , Changed < UiImage > , Changed < Node > ) > ,
189
+ (
190
+ Entity ,
191
+ & ImageScaleMode ,
192
+ & Node ,
193
+ & UiImage ,
194
+ Option < & TextureAtlas > ,
195
+ ) ,
196
+ Or < (
197
+ Changed < ImageScaleMode > ,
198
+ Changed < UiImage > ,
199
+ Changed < Node > ,
200
+ Changed < TextureAtlas > ,
201
+ ) > ,
153
202
> ,
154
203
) {
155
- for ( entity, scale_mode, ui_node, image) in & changed_nodes {
156
- if let Some ( slices) = compute_texture_slices ( ui_node. size ( ) , scale_mode, image, & images) {
204
+ for ( entity, scale_mode, ui_node, image, atlas) in & changed_nodes {
205
+ if let Some ( slices) = compute_texture_slices (
206
+ ui_node. size ( ) ,
207
+ scale_mode,
208
+ image,
209
+ & images,
210
+ atlas,
211
+ & atlas_layouts,
212
+ ) {
157
213
commands. entity ( entity) . insert ( slices) ;
158
214
}
159
215
}
0 commit comments