From 03404c48cab43b2e4a9ca16e412930341e9aa66e Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Sat, 13 Jan 2024 22:21:40 +0000 Subject: [PATCH] UI text rotation and scaling fix (#11326) # Objective UI node text is drawn in the wrong position after rotation or scaling. ![294723406-d031a3e6-a4f9-48b4-a66a-ee963100a8b9](https://github.com/bevyengine/bevy/assets/27962798/2755e2e3-6a03-4ee8-8676-bdcaa72ec678) ## Solution In `extract_text_uinodes` to set the text's offset create a translation matrix and multiply it by the UI node's transform. Previously the offset was just added directly to the translation of the Node's `GlobalTransform`, which meant no scaling or rotation would be applied to the offset. 296440025-537ec11c-1ea1-469c-8eec-2ad4ae012095 296440156-dd04029d-8112-4fa5-89a2-56d7acab66df Fixes #11241 --- crates/bevy_ui/src/render/mod.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 60dfd1fab6..c197637e4b 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -21,7 +21,6 @@ use crate::{ use bevy_app::prelude::*; use bevy_asset::{load_internal_asset, AssetEvent, AssetId, Assets, Handle}; use bevy_ecs::prelude::*; -use bevy_math::Vec3Swizzles; use bevy_math::{Mat4, Rect, URect, UVec4, Vec2, Vec3, Vec4Swizzles}; use bevy_render::{ camera::Camera, @@ -636,19 +635,18 @@ pub fn extract_text_uinodes( continue; } - let mut affine = global_transform.affine(); - // Align the text to the nearest physical pixel: // * Translate by minus the text node's half-size // (The transform translates to the center of the node but the text coordinates are relative to the node's top left corner) // * Multiply the logical coordinates by the scale factor to get its position in physical coordinates // * Round the physical position to the nearest physical pixel // * Multiply by the rounded physical position by the inverse scale factor to return to logical coordinates - let logical_top_left = affine.translation.xy() - 0.5 * uinode.size(); + + let logical_top_left = -0.5 * uinode.size(); let physical_nearest_pixel = (logical_top_left * scale_factor).round(); let logical_top_left_nearest_pixel = physical_nearest_pixel * inverse_scale_factor; - affine.translation = logical_top_left_nearest_pixel.extend(0.).into(); - let transform = Mat4::from(affine); + let transform = Mat4::from(global_transform.affine()) + * Mat4::from_translation(logical_top_left_nearest_pixel.extend(0.)); let mut color = Color::WHITE; let mut current_section = usize::MAX;