Fix panics in scene_viewer and audio_control (#16983)

Fixes #16978

While testing, discovered that the morph weight interface in
`scene_viewer` has been broken for a while (panics when loaded model has
morph weights), probably since #15591. Fixed that too.

While testing, saw example text in morph interface with [wrong
padding](https://bevyengine.org/learn/contribute/helping-out/creating-examples/#visual-guidelines).
Fixed that too. Left the small font size because there may be a lot of
morphs to display, so that seems intentional.

Use normal queries and bail early

Morph interface can be tested with
```
cargo run --example scene_viewer assets/models/animated/MorphStressTest.gltf
```

I noticed that this fix is different than what is happening in #16976.
Feel free to discard this for an alternative fix. I opened this anyway
to document the issue with morph weight display.

This is on top of #16966 which is required to test.

---------

Co-authored-by: François Mockers <francois.mockers@vleue.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
This commit is contained in:
Rob Parrett 2024-12-26 14:10:34 -08:00 committed by François Mockers
parent 1f72e078ae
commit 6138575c6c

View File

@ -12,6 +12,8 @@ use crate::scene_viewer_plugin::SceneHandle;
use bevy::prelude::*; use bevy::prelude::*;
use std::fmt; use std::fmt;
const FONT_SIZE: f32 = 13.0;
const WEIGHT_PER_SECOND: f32 = 0.8; const WEIGHT_PER_SECOND: f32 = 0.8;
const ALL_MODIFIERS: &[KeyCode] = &[KeyCode::ShiftLeft, KeyCode::ControlLeft, KeyCode::AltLeft]; const ALL_MODIFIERS: &[KeyCode] = &[KeyCode::ShiftLeft, KeyCode::ControlLeft, KeyCode::AltLeft];
const AVAILABLE_KEYS: [MorphKey; 56] = [ const AVAILABLE_KEYS: [MorphKey; 56] = [
@ -122,8 +124,8 @@ impl fmt::Display for Target {
} }
} }
impl Target { impl Target {
fn text_span(&self, key: &str, style: TextFont) -> (String, TextFont) { fn text_span(&self, key: &str, style: TextFont) -> (TextSpan, TextFont) {
(format!("[{key}] {self}\n"), style) (TextSpan::new(format!("[{key}] {self}\n")), style)
} }
fn new( fn new(
entity_name: Option<&Name>, entity_name: Option<&Name>,
@ -178,13 +180,18 @@ impl MorphKey {
} }
fn update_text( fn update_text(
controls: Option<ResMut<WeightsControl>>, controls: Option<ResMut<WeightsControl>>,
text: Single<Entity, With<Text>>, texts: Query<Entity, With<Text>>,
morphs: Query<&MorphWeights>, morphs: Query<&MorphWeights>,
mut writer: TextUiWriter, mut writer: TextUiWriter,
) { ) {
let Some(mut controls) = controls else { let Some(mut controls) = controls else {
return; return;
}; };
let Ok(text) = texts.get_single() else {
return;
};
for (i, target) in controls.weights.iter_mut().enumerate() { for (i, target) in controls.weights.iter_mut().enumerate() {
let Ok(weights) = morphs.get(target.entity) else { let Ok(weights) = morphs.get(target.entity) else {
continue; continue;
@ -196,7 +203,8 @@ fn update_text(
target.weight = actual_weight; target.weight = actual_weight;
} }
let key_name = &AVAILABLE_KEYS[i].name; let key_name = &AVAILABLE_KEYS[i].name;
*writer.text(*text, i + 3) = format!("[{key_name}] {target}\n");
*writer.text(text, i + 3) = format!("[{key_name}] {target}\n");
} }
} }
fn update_morphs( fn update_morphs(
@ -254,12 +262,12 @@ fn detect_morphs(
} }
detected.truncate(AVAILABLE_KEYS.len()); detected.truncate(AVAILABLE_KEYS.len());
let style = TextFont { let style = TextFont {
font_size: 13.0, font_size: FONT_SIZE,
..default() ..default()
}; };
let mut spans = vec![ let mut spans = vec![
("Morph Target Controls\n".into(), style.clone()), (TextSpan::new("Morph Target Controls\n"), style.clone()),
("---------------\n".into(), style.clone()), (TextSpan::new("---------------\n"), style.clone()),
]; ];
let target_to_text = let target_to_text =
|(i, target): (usize, &Target)| target.text_span(AVAILABLE_KEYS[i].name, style.clone()); |(i, target): (usize, &Target)| target.text_span(AVAILABLE_KEYS[i].name, style.clone());
@ -270,14 +278,15 @@ fn detect_morphs(
Text::default(), Text::default(),
Node { Node {
position_type: PositionType::Absolute, position_type: PositionType::Absolute,
top: Val::Px(10.0), top: Val::Px(12.0),
left: Val::Px(10.0), left: Val::Px(12.0),
..default() ..default()
}, },
)) ))
.with_children(|p| { .with_children(|p| {
p.spawn((TextSpan::new("Morph Target Controls\n"), style.clone())); for span in spans {
p.spawn((TextSpan::new("---------------\n"), style)); p.spawn(span);
}
}); });
} }