From 0f1eebed38ee884d607213a04f06f9f8bff5e3ad Mon Sep 17 00:00:00 2001 From: James Lucas Date: Thu, 3 Jul 2025 18:43:32 +0100 Subject: [PATCH] Fixing sprite pixel space point computation for sprites with zero custom_size (#19907) # Objective Current implementation of `Sprite::compute_pixel_space_point` always returns the sprite centre as an `Ok` point when the `custom_size` is set to `Vec2::ZERO`. This leads to unexpected behaviour. For example, it causes these sprites to block all interactions with other sprites in the picking backend (under default settings). This small PR: - Fixes sprite pixel space point computation for sprites with zero custom_size - Resolves issue #19880. ## Solution We handle the zero custom_size case explicitly and return `Err(point_relative_to_sprite_center)` instead of `Ok(point_relative_to_texture)`. ## Testing Implemented a new test for zero custom_size sprites within the `bevy_sprite::sprite` module. Also verified that the example from issue #19880 is behaving as expected. No further testing is required. - How can other people (reviewers) test your changes? Is there anything specific they need to know? Can run the simple application example from the linked issue. Or evaluate the implemented test. --------- Co-authored-by: James Lucas --- crates/bevy_sprite/src/sprite.rs | 39 +++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/crates/bevy_sprite/src/sprite.rs b/crates/bevy_sprite/src/sprite.rs index 581ba69201..39e215df04 100644 --- a/crates/bevy_sprite/src/sprite.rs +++ b/crates/bevy_sprite/src/sprite.rs @@ -124,12 +124,15 @@ impl Sprite { point_relative_to_sprite_center.y *= -1.0; } + if sprite_size.x == 0.0 || sprite_size.y == 0.0 { + return Err(point_relative_to_sprite_center); + } + let sprite_to_texture_ratio = { let texture_size = texture_rect.size(); - let div_or_zero = |a, b| if b == 0.0 { 0.0 } else { a / b }; Vec2::new( - div_or_zero(texture_size.x, sprite_size.x), - div_or_zero(texture_size.y, sprite_size.y), + texture_size.x / sprite_size.x, + texture_size.y / sprite_size.y, ) }; @@ -555,4 +558,34 @@ mod tests { // The pixel is outside the texture atlas, but is still a valid pixel in the image. assert_eq!(compute(Vec2::new(0.0, 35.0)), Err(Vec2::new(2.5, -1.0))); } + + #[test] + fn compute_pixel_space_point_for_sprite_with_zero_custom_size() { + let mut image_assets = Assets::::default(); + let texture_atlas_assets = Assets::::default(); + + let image = image_assets.add(make_image(UVec2::new(5, 10))); + + let sprite = Sprite { + image, + custom_size: Some(Vec2::new(0.0, 0.0)), + ..Default::default() + }; + + let compute = |point| { + sprite.compute_pixel_space_point( + point, + Anchor::default(), + &image_assets, + &texture_atlas_assets, + ) + }; + assert_eq!(compute(Vec2::new(30.0, 15.0)), Err(Vec2::new(30.0, -15.0))); + assert_eq!( + compute(Vec2::new(-10.0, -15.0)), + Err(Vec2::new(-10.0, 15.0)) + ); + // The pixel is outside the texture atlas, but is still a valid pixel in the image. + assert_eq!(compute(Vec2::new(0.0, 35.0)), Err(Vec2::new(0.0, -35.0))); + } }