Text2d bounding box fix (#20148)

# Objective

`calculate_bounds_text2d` generates `Aabb`s with the wrong size and
position for `Text2d` entities with `TextBounds`, which breaks culling.

## Solution

Calculate the correct bounds.

Fixes #20145

## Testing

```
cargo run --example testbed_2d
```

#### main
<img width="661" height="469" alt="text2daabb"
src="https://github.com/user-attachments/assets/c10b64ed-6e0d-4c4e-a81d-6ae2248d752a"
/>

#### This PR

<img width="441" height="308" alt="fixed-text2d-aabbs"
src="https://github.com/user-attachments/assets/bc715bf0-b77f-4149-9c6d-a5a8c1982780"
/>
This commit is contained in:
ickshonpe 2025-07-15 18:14:49 +01:00 committed by GitHub
parent 57086d4416
commit f774d6b7ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 13 additions and 14 deletions

View File

@ -17,7 +17,7 @@ use bevy_ecs::{
system::{Commands, Local, Query, Res, ResMut},
};
use bevy_image::prelude::*;
use bevy_math::Vec2;
use bevy_math::{Vec2, Vec3};
use bevy_reflect::{prelude::ReflectDefault, Reflect};
use bevy_render::sync_world::TemporaryRenderEntity;
use bevy_render::view::{self, Visibility, VisibilityClass};
@ -186,6 +186,7 @@ pub fn extract_text2d_sprite(
let top_left = (Anchor::TOP_LEFT.0 - anchor.as_vec()) * size;
let transform =
*global_transform * GlobalTransform::from_translation(top_left.extend(0.)) * scaling;
let mut color = LinearRgba::WHITE;
let mut current_span = usize::MAX;
@ -366,22 +367,17 @@ pub fn calculate_bounds_text2d(
text_bounds.width.unwrap_or(layout_info.size.x),
text_bounds.height.unwrap_or(layout_info.size.y),
);
let center = (-anchor.as_vec() * size + (size.y - layout_info.size.y) * Vec2::Y)
.extend(0.)
.into();
let half_extents = (0.5 * layout_info.size).extend(0.0).into();
let x1 = (Anchor::TOP_LEFT.0.x - anchor.as_vec().x) * size.x;
let x2 = (Anchor::TOP_LEFT.0.x - anchor.as_vec().x + 1.) * size.x;
let y1 = (Anchor::TOP_LEFT.0.y - anchor.as_vec().y - 1.) * size.y;
let y2 = (Anchor::TOP_LEFT.0.y - anchor.as_vec().y) * size.y;
let new_aabb = Aabb::from_min_max(Vec3::new(x1, y1, 0.), Vec3::new(x2, y2, 0.));
if let Some(mut aabb) = aabb {
*aabb = Aabb {
center,
half_extents,
};
*aabb = new_aabb;
} else {
commands.entity(entity).try_insert(Aabb {
center,
half_extents,
});
commands.entity(entity).try_insert(new_aabb);
}
}
}

View File

@ -165,7 +165,7 @@ mod text {
&mut commands,
300. * Vec3::X + y * Vec3::Y,
justify,
Some(TextBounds::new(150., 55.)),
Some(TextBounds::new(150., 60.)),
);
}
@ -221,6 +221,9 @@ mod text {
Transform::from_translation(dest + Vec3::Z),
anchor,
DespawnOnExitState(super::Scene::Text),
ShowAabbGizmo {
color: Some(palettes::tailwind::AMBER_400.into()),
},
children![
(
TextSpan::new(format!("{}, {}\n", anchor.x, anchor.y)),