Fix panics in scene_viewer
and audio_control
(#16983)
# Objective 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. ## Solution Use normal queries and bail early ## Testing Morph interface can be tested with ``` cargo run --example scene_viewer assets/models/animated/MorphStressTest.gltf ``` ## Discussion 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:
parent
e8fc279705
commit
78d2149503
@ -34,11 +34,22 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
#[derive(Component)]
|
||||
struct MyMusic;
|
||||
|
||||
fn update_speed(sink: Single<&AudioSink, With<MyMusic>>, time: Res<Time>) {
|
||||
fn update_speed(music_controller: Query<&AudioSink, With<MyMusic>>, time: Res<Time>) {
|
||||
let Ok(sink) = music_controller.get_single() else {
|
||||
return;
|
||||
};
|
||||
|
||||
sink.set_speed((ops::sin(time.elapsed_secs() / 5.0) + 1.0).max(0.1));
|
||||
}
|
||||
|
||||
fn pause(keyboard_input: Res<ButtonInput<KeyCode>>, sink: Single<&AudioSink, With<MyMusic>>) {
|
||||
fn pause(
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||
music_controller: Query<&AudioSink, With<MyMusic>>,
|
||||
) {
|
||||
let Ok(sink) = music_controller.get_single() else {
|
||||
return;
|
||||
};
|
||||
|
||||
if keyboard_input.just_pressed(KeyCode::Space) {
|
||||
sink.toggle_playback();
|
||||
}
|
||||
@ -46,8 +57,12 @@ fn pause(keyboard_input: Res<ButtonInput<KeyCode>>, sink: Single<&AudioSink, Wit
|
||||
|
||||
fn mute(
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||
mut sink: Single<&mut AudioSink, With<MyMusic>>,
|
||||
mut music_controller: Query<&mut AudioSink, With<MyMusic>>,
|
||||
) {
|
||||
let Ok(mut sink) = music_controller.get_single_mut() else {
|
||||
return;
|
||||
};
|
||||
|
||||
if keyboard_input.just_pressed(KeyCode::KeyM) {
|
||||
sink.toggle_mute();
|
||||
}
|
||||
@ -55,8 +70,12 @@ fn mute(
|
||||
|
||||
fn volume(
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||
mut sink: Single<&mut AudioSink, With<MyMusic>>,
|
||||
mut music_controller: Query<&mut AudioSink, With<MyMusic>>,
|
||||
) {
|
||||
let Ok(mut sink) = music_controller.get_single_mut() else {
|
||||
return;
|
||||
};
|
||||
|
||||
if keyboard_input.just_pressed(KeyCode::Equal) {
|
||||
let current_volume = sink.volume();
|
||||
sink.set_volume(current_volume + 0.1);
|
||||
|
@ -109,11 +109,13 @@ fn run_camera_controller(
|
||||
key_input: Res<ButtonInput<KeyCode>>,
|
||||
mut toggle_cursor_grab: Local<bool>,
|
||||
mut mouse_cursor_grab: Local<bool>,
|
||||
query: Single<(&mut Transform, &mut CameraController), With<Camera>>,
|
||||
mut query: Query<(&mut Transform, &mut CameraController), With<Camera>>,
|
||||
) {
|
||||
let dt = time.delta_secs();
|
||||
|
||||
let (mut transform, mut controller) = query.into_inner();
|
||||
let Ok((mut transform, mut controller)) = query.get_single_mut() else {
|
||||
return;
|
||||
};
|
||||
|
||||
if !controller.initialized {
|
||||
let (yaw, pitch, _roll) = transform.rotation.to_euler(EulerRot::YXZ);
|
||||
|
@ -12,6 +12,8 @@ use crate::scene_viewer_plugin::SceneHandle;
|
||||
use bevy::prelude::*;
|
||||
use std::fmt;
|
||||
|
||||
const FONT_SIZE: f32 = 13.0;
|
||||
|
||||
const WEIGHT_PER_SECOND: f32 = 0.8;
|
||||
const ALL_MODIFIERS: &[KeyCode] = &[KeyCode::ShiftLeft, KeyCode::ControlLeft, KeyCode::AltLeft];
|
||||
const AVAILABLE_KEYS: [MorphKey; 56] = [
|
||||
@ -122,8 +124,8 @@ impl fmt::Display for Target {
|
||||
}
|
||||
}
|
||||
impl Target {
|
||||
fn text_span(&self, key: &str, style: TextFont) -> (String, TextFont) {
|
||||
(format!("[{key}] {self}\n"), style)
|
||||
fn text_span(&self, key: &str, style: TextFont) -> (TextSpan, TextFont) {
|
||||
(TextSpan::new(format!("[{key}] {self}\n")), style)
|
||||
}
|
||||
fn new(
|
||||
entity_name: Option<&Name>,
|
||||
@ -178,13 +180,18 @@ impl MorphKey {
|
||||
}
|
||||
fn update_text(
|
||||
controls: Option<ResMut<WeightsControl>>,
|
||||
text: Single<Entity, With<Text>>,
|
||||
texts: Query<Entity, With<Text>>,
|
||||
morphs: Query<&MorphWeights>,
|
||||
mut writer: TextUiWriter,
|
||||
) {
|
||||
let Some(mut controls) = controls else {
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(text) = texts.get_single() else {
|
||||
return;
|
||||
};
|
||||
|
||||
for (i, target) in controls.weights.iter_mut().enumerate() {
|
||||
let Ok(weights) = morphs.get(target.entity) else {
|
||||
continue;
|
||||
@ -196,7 +203,8 @@ fn update_text(
|
||||
target.weight = actual_weight;
|
||||
}
|
||||
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(
|
||||
@ -254,12 +262,12 @@ fn detect_morphs(
|
||||
}
|
||||
detected.truncate(AVAILABLE_KEYS.len());
|
||||
let style = TextFont {
|
||||
font_size: 13.0,
|
||||
font_size: FONT_SIZE,
|
||||
..default()
|
||||
};
|
||||
let mut spans = vec![
|
||||
("Morph Target Controls\n".into(), style.clone()),
|
||||
("---------------\n".into(), style.clone()),
|
||||
(TextSpan::new("Morph Target Controls\n"), style.clone()),
|
||||
(TextSpan::new("---------------\n"), style.clone()),
|
||||
];
|
||||
let target_to_text =
|
||||
|(i, target): (usize, &Target)| target.text_span(AVAILABLE_KEYS[i].name, style.clone());
|
||||
@ -270,14 +278,15 @@ fn detect_morphs(
|
||||
Text::default(),
|
||||
Node {
|
||||
position_type: PositionType::Absolute,
|
||||
top: Val::Px(10.0),
|
||||
left: Val::Px(10.0),
|
||||
top: Val::Px(12.0),
|
||||
left: Val::Px(12.0),
|
||||
..default()
|
||||
},
|
||||
))
|
||||
.with_children(|p| {
|
||||
p.spawn((TextSpan::new("Morph Target Controls\n"), style.clone()));
|
||||
p.spawn((TextSpan::new("---------------\n"), style));
|
||||
for span in spans {
|
||||
p.spawn(span);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user