# Objective Fixes #17098 It seems that it's not totally obvious how to fix this, but that reverting might be part of the solution anyway. Let's get the repo back into a working state. ## Solution Revert the [recent optimization](https://github.com/bevyengine/bevy/pull/17078) that broke "many-to-one main->render world entities" for 2d. ## Testing `cargo run --example text2d` `cargo run --example sprite_slice`
This commit is contained in:
		
							parent
							
								
									39f38a191e
								
							
						
					
					
						commit
						859c2d77f9
					
				| @ -19,6 +19,7 @@ use bevy_ecs::{ | |||||||
| }; | }; | ||||||
| use bevy_image::{BevyDefault, Image, ImageSampler, TextureFormatPixelInfo}; | use bevy_image::{BevyDefault, Image, ImageSampler, TextureFormatPixelInfo}; | ||||||
| use bevy_math::{Affine3A, FloatOrd, Quat, Rect, Vec2, Vec4}; | use bevy_math::{Affine3A, FloatOrd, Quat, Rect, Vec2, Vec4}; | ||||||
|  | use bevy_render::sync_world::MainEntity; | ||||||
| use bevy_render::view::RenderVisibleEntities; | use bevy_render::view::RenderVisibleEntities; | ||||||
| use bevy_render::{ | use bevy_render::{ | ||||||
|     render_asset::RenderAssets, |     render_asset::RenderAssets, | ||||||
| @ -31,7 +32,7 @@ use bevy_render::{ | |||||||
|         *, |         *, | ||||||
|     }, |     }, | ||||||
|     renderer::{RenderDevice, RenderQueue}, |     renderer::{RenderDevice, RenderQueue}, | ||||||
|     sync_world::{MainEntityHashMap, RenderEntity, TemporaryRenderEntity}, |     sync_world::{RenderEntity, TemporaryRenderEntity}, | ||||||
|     texture::{DefaultImageSampler, FallbackImage, GpuImage}, |     texture::{DefaultImageSampler, FallbackImage, GpuImage}, | ||||||
|     view::{ |     view::{ | ||||||
|         ExtractedView, Msaa, ViewTarget, ViewUniform, ViewUniformOffset, ViewUniforms, |         ExtractedView, Msaa, ViewTarget, ViewUniform, ViewUniformOffset, ViewUniforms, | ||||||
| @ -340,12 +341,11 @@ pub struct ExtractedSprite { | |||||||
|     /// For cases where additional [`ExtractedSprites`] are created during extraction, this stores the
 |     /// For cases where additional [`ExtractedSprites`] are created during extraction, this stores the
 | ||||||
|     /// entity that caused that creation for use in determining visibility.
 |     /// entity that caused that creation for use in determining visibility.
 | ||||||
|     pub original_entity: Option<Entity>, |     pub original_entity: Option<Entity>, | ||||||
|     pub render_entity: Entity, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Resource, Default)] | #[derive(Resource, Default)] | ||||||
| pub struct ExtractedSprites { | pub struct ExtractedSprites { | ||||||
|     pub sprites: MainEntityHashMap<ExtractedSprite>, |     pub sprites: HashMap<(Entity, MainEntity), ExtractedSprite>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Resource, Default)] | #[derive(Resource, Default)] | ||||||
| @ -390,13 +390,16 @@ pub fn extract_sprites( | |||||||
|         if let Some(slices) = slices { |         if let Some(slices) = slices { | ||||||
|             extracted_sprites.sprites.extend( |             extracted_sprites.sprites.extend( | ||||||
|                 slices |                 slices | ||||||
|                     .extract_sprites( |                     .extract_sprites(transform, original_entity, sprite) | ||||||
|                         transform, |                     .map(|e| { | ||||||
|                         original_entity, |                         ( | ||||||
|  |                             ( | ||||||
|                                 commands.spawn(TemporaryRenderEntity).id(), |                                 commands.spawn(TemporaryRenderEntity).id(), | ||||||
|                         sprite, |                                 original_entity.into(), | ||||||
|  |                             ), | ||||||
|  |                             e, | ||||||
|                         ) |                         ) | ||||||
|                     .map(|e| (original_entity.into(), e)), |                     }), | ||||||
|             ); |             ); | ||||||
|         } else { |         } else { | ||||||
|             let atlas_rect = sprite |             let atlas_rect = sprite | ||||||
| @ -417,7 +420,7 @@ pub fn extract_sprites( | |||||||
| 
 | 
 | ||||||
|             // PERF: we don't check in this function that the `Image` asset is ready, since it should be in most cases and hashing the handle is expensive
 |             // PERF: we don't check in this function that the `Image` asset is ready, since it should be in most cases and hashing the handle is expensive
 | ||||||
|             extracted_sprites.sprites.insert( |             extracted_sprites.sprites.insert( | ||||||
|                 original_entity.into(), |                 (entity, original_entity.into()), | ||||||
|                 ExtractedSprite { |                 ExtractedSprite { | ||||||
|                     color: sprite.color.into(), |                     color: sprite.color.into(), | ||||||
|                     transform: *transform, |                     transform: *transform, | ||||||
| @ -429,7 +432,6 @@ pub fn extract_sprites( | |||||||
|                     image_handle_id: sprite.image.id(), |                     image_handle_id: sprite.image.id(), | ||||||
|                     anchor: sprite.anchor.as_vec(), |                     anchor: sprite.anchor.as_vec(), | ||||||
|                     original_entity: Some(original_entity), |                     original_entity: Some(original_entity), | ||||||
|                     render_entity: entity, |  | ||||||
|                 }, |                 }, | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
| @ -556,11 +558,8 @@ pub fn queue_sprites( | |||||||
|             .items |             .items | ||||||
|             .reserve(extracted_sprites.sprites.len()); |             .reserve(extracted_sprites.sprites.len()); | ||||||
| 
 | 
 | ||||||
|         for (main_entity, extracted_sprite) in extracted_sprites.sprites.iter() { |         for ((entity, main_entity), extracted_sprite) in extracted_sprites.sprites.iter() { | ||||||
|             let index = extracted_sprite |             let index = extracted_sprite.original_entity.unwrap_or(*entity).index(); | ||||||
|                 .original_entity |  | ||||||
|                 .unwrap_or(extracted_sprite.render_entity) |  | ||||||
|                 .index(); |  | ||||||
| 
 | 
 | ||||||
|             if !view_entities.contains(index as usize) { |             if !view_entities.contains(index as usize) { | ||||||
|                 continue; |                 continue; | ||||||
| @ -573,7 +572,7 @@ pub fn queue_sprites( | |||||||
|             transparent_phase.add(Transparent2d { |             transparent_phase.add(Transparent2d { | ||||||
|                 draw_function: draw_sprite_function, |                 draw_function: draw_sprite_function, | ||||||
|                 pipeline, |                 pipeline, | ||||||
|                 entity: (extracted_sprite.render_entity, *main_entity), |                 entity: (*entity, *main_entity), | ||||||
|                 sort_key, |                 sort_key, | ||||||
|                 // batch_range and dynamic_offset will be calculated in prepare_sprites
 |                 // batch_range and dynamic_offset will be calculated in prepare_sprites
 | ||||||
|                 batch_range: 0..0, |                 batch_range: 0..0, | ||||||
| @ -663,7 +662,7 @@ pub fn prepare_sprite_image_bind_groups( | |||||||
|         // Compatible items share the same entity.
 |         // Compatible items share the same entity.
 | ||||||
|         for item_index in 0..transparent_phase.items.len() { |         for item_index in 0..transparent_phase.items.len() { | ||||||
|             let item = &transparent_phase.items[item_index]; |             let item = &transparent_phase.items[item_index]; | ||||||
|             let Some(extracted_sprite) = extracted_sprites.sprites.get(&item.entity.1) else { |             let Some(extracted_sprite) = extracted_sprites.sprites.get(&item.entity) else { | ||||||
|                 // If there is a phase item that is not a sprite, then we must start a new
 |                 // If there is a phase item that is not a sprite, then we must start a new
 | ||||||
|                 // batch to draw the other phase item(s) and to respect draw order. This can be
 |                 // batch to draw the other phase item(s) and to respect draw order. This can be
 | ||||||
|                 // done by invalidating the batch_image_handle
 |                 // done by invalidating the batch_image_handle
 | ||||||
|  | |||||||
| @ -28,7 +28,6 @@ impl ComputedTextureSlices { | |||||||
|         &'a self, |         &'a self, | ||||||
|         transform: &'a GlobalTransform, |         transform: &'a GlobalTransform, | ||||||
|         original_entity: Entity, |         original_entity: Entity, | ||||||
|         render_entity: Entity, |  | ||||||
|         sprite: &'a Sprite, |         sprite: &'a Sprite, | ||||||
|     ) -> impl ExactSizeIterator<Item = ExtractedSprite> + 'a { |     ) -> impl ExactSizeIterator<Item = ExtractedSprite> + 'a { | ||||||
|         let mut flip = Vec2::ONE; |         let mut flip = Vec2::ONE; | ||||||
| @ -54,7 +53,6 @@ impl ComputedTextureSlices { | |||||||
|                 flip_y, |                 flip_y, | ||||||
|                 image_handle_id: sprite.image.id(), |                 image_handle_id: sprite.image.id(), | ||||||
|                 anchor: Self::redepend_anchor_from_sprite_to_slice(sprite, slice), |                 anchor: Self::redepend_anchor_from_sprite_to_slice(sprite, slice), | ||||||
|                 render_entity, |  | ||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -206,7 +206,10 @@ pub fn extract_text2d_sprite( | |||||||
|             let atlas = texture_atlases.get(&atlas_info.texture_atlas).unwrap(); |             let atlas = texture_atlases.get(&atlas_info.texture_atlas).unwrap(); | ||||||
| 
 | 
 | ||||||
|             extracted_sprites.sprites.insert( |             extracted_sprites.sprites.insert( | ||||||
|  |                 ( | ||||||
|  |                     commands.spawn(TemporaryRenderEntity).id(), | ||||||
|                     original_entity.into(), |                     original_entity.into(), | ||||||
|  |                 ), | ||||||
|                 ExtractedSprite { |                 ExtractedSprite { | ||||||
|                     transform: transform * GlobalTransform::from_translation(position.extend(0.)), |                     transform: transform * GlobalTransform::from_translation(position.extend(0.)), | ||||||
|                     color, |                     color, | ||||||
| @ -217,7 +220,6 @@ pub fn extract_text2d_sprite( | |||||||
|                     flip_y: false, |                     flip_y: false, | ||||||
|                     anchor: Anchor::Center.as_vec(), |                     anchor: Anchor::Center.as_vec(), | ||||||
|                     original_entity: Some(original_entity), |                     original_entity: Some(original_entity), | ||||||
|                     render_entity: commands.spawn(TemporaryRenderEntity).id(), |  | ||||||
|                 }, |                 }, | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ use bevy::{ | |||||||
|         render_asset::RenderAssetUsages, |         render_asset::RenderAssetUsages, | ||||||
|         render_resource::{Extent3d, TextureDimension, TextureFormat}, |         render_resource::{Extent3d, TextureDimension, TextureFormat}, | ||||||
|     }, |     }, | ||||||
|     sprite::{AlphaMode2d, SpritePlugin}, |     sprite::AlphaMode2d, | ||||||
|     utils::Duration, |     utils::Duration, | ||||||
|     window::{PresentMode, WindowResolution}, |     window::{PresentMode, WindowResolution}, | ||||||
|     winit::{UpdateMode, WinitSettings}, |     winit::{UpdateMode, WinitSettings}, | ||||||
| @ -132,8 +132,7 @@ fn main() { | |||||||
| 
 | 
 | ||||||
|     App::new() |     App::new() | ||||||
|         .add_plugins(( |         .add_plugins(( | ||||||
|             DefaultPlugins |             DefaultPlugins.set(WindowPlugin { | ||||||
|                 .set(WindowPlugin { |  | ||||||
|                 primary_window: Some(Window { |                 primary_window: Some(Window { | ||||||
|                     title: "BevyMark".into(), |                     title: "BevyMark".into(), | ||||||
|                     resolution: WindowResolution::new(1920.0, 1080.0) |                     resolution: WindowResolution::new(1920.0, 1080.0) | ||||||
| @ -142,10 +141,6 @@ fn main() { | |||||||
|                     ..default() |                     ..default() | ||||||
|                 }), |                 }), | ||||||
|                 ..default() |                 ..default() | ||||||
|                 }) |  | ||||||
|                 .set(SpritePlugin { |  | ||||||
|                     #[cfg(feature = "bevy_sprite_picking_backend")] |  | ||||||
|                     add_picking: false, |  | ||||||
|             }), |             }), | ||||||
|             FrameTimeDiagnosticsPlugin, |             FrameTimeDiagnosticsPlugin, | ||||||
|             LogDiagnosticsPlugin::default(), |             LogDiagnosticsPlugin::default(), | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Rob Parrett
						Rob Parrett