Merge pull request #11529 from horizon-rust/fix/followup-10571

Text displays: animated text is never cached, and a culled one keeps its glyphs
This commit is contained in:
rdbt authored and GitHub committed 2026-11-07 12:31:27 +00:00
commit bc0ddfbff0
2 files changed
+21 -6

No files matched your search

@@ -348,13 +348,14 @@ impl Game<'_> {
let background = self.settings.text_background(0.25);
let mut displays = std::mem::take(&mut self.text_displays);
for display in displays.values_mut().filter(|d| d.shows == Shows::Text) {
let cached = display.lines.take();
display.last_progress = display.progress(partial as f32);
let d = display.shown.blend(&display.from, display.last_progress);
let position = display.previous.lerp(display.position, partial);
if d.text.is_empty() || !self.display_in_view(camera, position, &d, scale) {
// Out of view: its glyphs stay cached for when it comes back.
continue;
}
let cached = display.lines.take();
let rotation = std::array::from_fn(|i| {
display.old_rotation[i]
+ angle(display.rotation[i] - display.old_rotation[i]) * partial as f32
@@ -514,6 +515,11 @@ mod tests {
d.text = std::sync::Arc::new(horizon_client::text::Text::legacy("§kSecret"));
let cache = CachedQuads::new(&atlas, &d, 0);
assert!(!cache.matches(&d, 0, atlas.font.epoch(), atlas.revision));
// A plugin hologram sends `§k` inside a literal JSON string: the font
// resolves it, so its glyphs still change every frame.
d.text = std::sync::Arc::new(horizon_client::text::Text::literal("§kSecret"));
let cache = CachedQuads::new(&atlas, &d, 0);
assert!(!cache.matches(&d, 0, atlas.font.epoch(), atlas.revision));
}
#[test]
+14 -5
View File
@@ -418,7 +418,10 @@ impl Lines {
/// Local geometry, independent of the display's interpolated world pose.
pub struct CachedQuads {
key: (Arc<Text>, i32, i32, i8, u8, u32, u64, u64),
key: (Arc<Text>, i32, i32, i8, u8, u32, u64, u64, bool),
/// Drawn differently every frame: obfuscated (`§k`) glyphs, legacy codes
/// included, or an inline object (a head whose skin arrives later).
animated: bool,
pub lines: Lines,
pub batch: crate::hud::HudBatch,
bounds: (glam::Vec3, glam::Vec3),
@@ -426,10 +429,7 @@ pub struct CachedQuads {
impl CachedQuads {
pub fn matches(&self, d: &TextDisplayData, background: u32, epoch: u64, revision: u64) -> bool {
!d.text
.spans
.iter()
.any(|s| s.style.obfuscated == Some(true))
!self.animated
&& self.key
== (
d.text.clone(),
@@ -440,6 +440,7 @@ impl CachedQuads {
background,
epoch,
revision,
crate::lang::bidirectional(),
)
}
@@ -454,6 +455,12 @@ impl CachedQuads {
lo = lo.min(p);
hi = hi.max(p);
}
let animated = d
.text
.resolved()
.spans
.iter()
.any(|s| s.style.obfuscated == Some(true) || s.style.inline_object.is_some());
Self {
key: (
d.text.clone(),
@@ -464,7 +471,9 @@ impl CachedQuads {
background,
atlas.font.epoch(),
atlas.revision,
crate::lang::bidirectional(),
),
animated,
lines,
batch,
bounds: (lo, hi),