Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sprite culling does not update Aabb when Handle<Image> changes #11892

Open
bonsairobo opened this issue Feb 16, 2024 · 0 comments
Open

Sprite culling does not update Aabb when Handle<Image> changes #11892

bonsairobo opened this issue Feb 16, 2024 · 0 comments
Labels
A-Assets Load files from disk to use for things like images, models, and sounds A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior

Comments

@bonsairobo
Copy link
Contributor

bonsairobo commented Feb 16, 2024

Bevy version

0.12

What you did

I upgraded from Bevy 0.10 to 0.12 and noticed that sprites would disappear before they had completely left the camera view. I assume this is just because sprite culling was implemented (with bugs) after 0.10.

What went wrong

Here's a video. Notice how the spinning cards will pop out when their center leaves the view.

card_clipping_bug.mp4

Additional information

I know what the root cause is. When Sprites are spawned, for some reason they have a "placeholder" Image asset which is only 1x1 pixels. The function calculate_bounds_2d relies on the Image to calculate bounds when there is no custom_size set on the Sprite. However, the change detection on this query does not account for Changed<Handle<Image>>.

pub fn calculate_bounds_2d(
mut commands: Commands,
meshes: Res<Assets<Mesh>>,
images: Res<Assets<Image>>,
atlases: Res<Assets<TextureAtlasLayout>>,
meshes_without_aabb: Query<(Entity, &Mesh2dHandle), (Without<Aabb>, Without<NoFrustumCulling>)>,
sprites_to_recalculate_aabb: Query<
(Entity, &Sprite, &Handle<Image>, Option<&TextureAtlas>),
(
Or<(Without<Aabb>, Changed<Sprite>, Changed<TextureAtlas>)>,
Without<NoFrustumCulling>,
),
>,
) {
for (entity, mesh_handle) in &meshes_without_aabb {
if let Some(mesh) = meshes.get(&mesh_handle.0) {
if let Some(aabb) = mesh.compute_aabb() {
commands.entity(entity).try_insert(aabb);
}
}
}
for (entity, sprite, texture_handle, atlas) in &sprites_to_recalculate_aabb {
if let Some(size) = sprite.custom_size.or_else(|| match atlas {
// We default to the texture size for regular sprites
None => images.get(texture_handle).map(|image| image.size_f32()),
// We default to the drawn rect for atlas sprites
Some(atlas) => atlas.texture_rect(&atlases).map(|rect| rect.size()),
}) {
let aabb = Aabb {
center: (-sprite.anchor.as_vec() * size).extend(0.0).into(),
half_extents: (0.5 * size).extend(0.0).into(),
};
commands.entity(entity).try_insert(aabb);
}
}
}

I believe the addition of Changed<Handle<Image>> is necessary but not sufficient to completely fix this issue, as we still need to fix #5069.

Related: #10587

@bonsairobo bonsairobo added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Feb 16, 2024
@alice-i-cecile alice-i-cecile added A-Rendering Drawing game state to the screen A-Assets Load files from disk to use for things like images, models, and sounds and removed S-Needs-Triage This issue needs to be labelled labels Feb 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Assets Load files from disk to use for things like images, models, and sounds A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior
Projects
None yet
Development

No branches or pull requests

2 participants