diff --git a/crates/bevy_sprite/src/lib.rs b/crates/bevy_sprite/src/lib.rs index a029ee6d6a..e64fb9808d 100644 --- a/crates/bevy_sprite/src/lib.rs +++ b/crates/bevy_sprite/src/lib.rs @@ -120,9 +120,12 @@ pub fn calculate_bounds_2d( images: Res>, atlases: Res>, meshes_without_aabb: Query<(Entity, &Mesh2dHandle), (Without, Without)>, - sprites_without_aabb: Query< + sprites_to_recalculate_aabb: Query< (Entity, &Sprite, &Handle), - (Without, Without), + ( + Or<(Without, Changed)>, + Without, + ), >, atlases_without_aabb: Query< (Entity, &TextureAtlasSprite, &Handle), @@ -136,7 +139,7 @@ pub fn calculate_bounds_2d( } } } - for (entity, sprite, texture_handle) in &sprites_without_aabb { + for (entity, sprite, texture_handle) in &sprites_to_recalculate_aabb { if let Some(size) = sprite .custom_size .or_else(|| images.get(texture_handle).map(|image| image.size_f32())) @@ -163,3 +166,115 @@ pub fn calculate_bounds_2d( } } } + +#[cfg(test)] +mod test { + + use bevy_math::Vec2; + use bevy_utils::default; + + use super::*; + + #[test] + fn calculate_bounds_2d_create_aabb_for_image_sprite_entity() { + // Setup app + let mut app = App::new(); + + // Add resources and get handle to image + let mut image_assets = Assets::::default(); + let image_handle = image_assets.add(Image::default()); + app.insert_resource(image_assets); + let mesh_assets = Assets::::default(); + app.insert_resource(mesh_assets); + let texture_atlas_assets = Assets::::default(); + app.insert_resource(texture_atlas_assets); + + // Add system + app.add_systems(Update, calculate_bounds_2d); + + // Add entites + let entity = app.world.spawn((Sprite::default(), image_handle)).id(); + + // Verify that the entity does not have an AABB + assert!(!app + .world + .get_entity(entity) + .expect("Could not find entity") + .contains::()); + + // Run system + app.update(); + + // Verify the AABB exists + assert!(app + .world + .get_entity(entity) + .expect("Could not find entity") + .contains::()); + } + + #[test] + fn calculate_bounds_2d_update_aabb_when_sprite_custom_size_changes_to_some() { + // Setup app + let mut app = App::new(); + + // Add resources and get handle to image + let mut image_assets = Assets::::default(); + let image_handle = image_assets.add(Image::default()); + app.insert_resource(image_assets); + let mesh_assets = Assets::::default(); + app.insert_resource(mesh_assets); + let texture_atlas_assets = Assets::::default(); + app.insert_resource(texture_atlas_assets); + + // Add system + app.add_systems(Update, calculate_bounds_2d); + + // Add entites + let entity = app + .world + .spawn(( + Sprite { + custom_size: Some(Vec2::ZERO), + ..default() + }, + image_handle, + )) + .id(); + + // Create initial AABB + app.update(); + + // Get the initial AABB + let first_aabb = *app + .world + .get_entity(entity) + .expect("Could not find entity") + .get::() + .expect("Could not find initial AABB"); + + // Change `custom_size` of sprite + let mut binding = app + .world + .get_entity_mut(entity) + .expect("Could not find entity"); + let mut sprite = binding + .get_mut::() + .expect("Could not find sprite component of entity"); + sprite.custom_size = Some(Vec2::ONE); + + // Re-run the `calculate_bounds_2d` system to get the new AABB + app.update(); + + // Get the re-calculated AABB + let second_aabb = *app + .world + .get_entity(entity) + .expect("Could not find entity") + .get::() + .expect("Could not find second AABB"); + + // Check that the AABBs are not equal + assert_ne!(first_aabb, second_aabb); + } +}