@@ -6,7 +6,7 @@ use bevy_asset::{AssetEvent, Assets};
66use bevy_ecs:: prelude:: * ;
77use bevy_math:: { Rect , Vec2 } ;
88use bevy_render:: texture:: Image ;
9- use bevy_sprite:: { ImageScaleMode , TextureSlice } ;
9+ use bevy_sprite:: { ImageScaleMode , TextureAtlas , TextureAtlasLayout , TextureSlice } ;
1010use bevy_transform:: prelude:: * ;
1111use bevy_utils:: HashSet ;
1212
@@ -74,25 +74,48 @@ impl ComputedTextureSlices {
7474}
7575
7676/// 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.
7878///
7979/// 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
8090#[ must_use]
8191fn compute_texture_slices (
8292 draw_area : Vec2 ,
8393 scale_mode : & ImageScaleMode ,
8494 image_handle : & UiImage ,
8595 images : & Assets < Image > ,
96+ atlas : Option < & TextureAtlas > ,
97+ atlas_layouts : & Assets < TextureAtlasLayout > ,
8698) -> 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+ }
96119 } ;
97120 let slices = match scale_mode {
98121 ImageScaleMode :: Sliced ( slicer) => slicer. compute_slices ( texture_rect, Some ( draw_area) ) ,
@@ -118,7 +141,14 @@ pub(crate) fn compute_slices_on_asset_event(
118141 mut commands : Commands ,
119142 mut events : EventReader < AssetEvent < Image > > ,
120143 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+ ) > ,
122152) {
123153 // We store the asset ids of added/modified image assets
124154 let added_handles: HashSet < _ > = events
@@ -132,11 +162,18 @@ pub(crate) fn compute_slices_on_asset_event(
132162 return ;
133163 }
134164 // 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 {
136166 if !added_handles. contains ( & image. texture . id ( ) ) {
137167 continue ;
138168 }
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+ ) {
140177 commands. entity ( entity) . insert ( slices) ;
141178 }
142179 }
@@ -147,13 +184,32 @@ pub(crate) fn compute_slices_on_asset_event(
147184pub ( crate ) fn compute_slices_on_image_change (
148185 mut commands : Commands ,
149186 images : Res < Assets < Image > > ,
187+ atlas_layouts : Res < Assets < TextureAtlasLayout > > ,
150188 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+ ) > ,
153202 > ,
154203) {
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+ ) {
157213 commands. entity ( entity) . insert ( slices) ;
158214 }
159215 }
0 commit comments