From bb7794e52a632e7f378c54f8ec4ab2cd5c65aa98 Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Wed, 25 Jun 2025 16:09:12 -0700 Subject: [PATCH] Starting humming bird binary, adding debugging tooltip --- examples/sensors.rs | 4 ++ src/base_game.rs | 1 + src/bin/hum/main.rs | 7 ++++ src/debug.rs | 100 +++++++++++++++++++++++++++++++++++++------- 4 files changed, 98 insertions(+), 14 deletions(-) create mode 100644 src/bin/hum/main.rs diff --git a/examples/sensors.rs b/examples/sensors.rs index ad1802b..9e2bc6b 100644 --- a/examples/sensors.rs +++ b/examples/sensors.rs @@ -54,6 +54,7 @@ fn setup_physics_scene( commands.spawn(( Collider::cuboid(100.0, 0.1, 100.0), Transform::from_xyz(0.0, -1.0, 0.0), + Pickable::IGNORE, Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(50.0)))), MeshMaterial3d(materials.add(StandardMaterial { base_color: RED.into(), @@ -81,6 +82,7 @@ fn setup_physics_scene( ExternalImpulse::default(), Transform::from_xyz(0.0, 4.0, 0.0), ActiveEvents::all(), + Name::new("Ball"), Mesh3d(meshes.add(SphereMeshBuilder::new( 0.5, SphereKind::Uv { @@ -100,6 +102,7 @@ fn setup_physics_scene( Collider::cuboid(1.0, 1.0, 1.0), Transform::from_xyz(0.0, 0.0, 2.0), Mesh3d(meshes.add(Cuboid::new(2.0, 2.0, 2.0))), + Name::new("Green Area"), MeshMaterial3d(materials.add(StandardMaterial { base_color: GREEN.with_alpha(0.5).into(), alpha_mode: AlphaMode::Blend, @@ -114,6 +117,7 @@ fn setup_physics_scene( Collider::cuboid(1.0, 1.0, 1.0), Transform::from_xyz(0.0, 0.0, -2.0), Mesh3d(meshes.add(Cuboid::new(2.0, 2.0, 2.0))), + Name::new("Blue Area"), MeshMaterial3d(materials.add(StandardMaterial { base_color: BLUE.with_alpha(0.5).into(), alpha_mode: AlphaMode::Blend, diff --git a/src/base_game.rs b/src/base_game.rs index 7f376f4..5b9ff67 100644 --- a/src/base_game.rs +++ b/src/base_game.rs @@ -7,6 +7,7 @@ impl Plugin for BaseGamePlugin { fn build(&self, app: &mut App) { app.add_plugins(DefaultPlugins) .add_plugins(DebuggingPlugin) + .add_plugins(MeshPickingPlugin) .add_plugins(RapierPhysicsPlugin::::default()) .add_systems(Startup, setup_camera); } diff --git a/src/bin/hum/main.rs b/src/bin/hum/main.rs new file mode 100644 index 0000000..488c023 --- /dev/null +++ b/src/bin/hum/main.rs @@ -0,0 +1,7 @@ +use games::*; + +fn main() { + App::new() + .add_plugins(BaseGamePlugin) + .run(); +} diff --git a/src/debug.rs b/src/debug.rs index 27424fc..e31ac49 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -6,6 +6,7 @@ pub struct DebuggingPlugin; impl Plugin for DebuggingPlugin { fn build(&self, app: &mut App) { app.init_state::() + .init_resource::() .add_plugins(RapierDebugRenderPlugin::default().disabled()) .add_systems(Startup, init_debug_ui) .add_systems( @@ -17,6 +18,11 @@ impl Plugin for DebuggingPlugin { ) .run_if(state_changed::), toggle_debug_state.run_if(on_keyboard_press(KeyCode::F12)), + ( + hover_mesh.run_if(on_event::>), + tooltip_follow.run_if(any_component_changed::), + sync_resource_to_ui::.run_if(resource_changed::), + ).run_if(in_state(DebuggingState::On)) ), ); } @@ -32,20 +38,6 @@ pub enum DebuggingState { On, } -/// Toggles the debug state from off -> on // off -> on when triggered -fn toggle_debug_state( - mut next: ResMut>, - curr: Res>, -) { - use DebuggingState::*; - - next.set(match curr.get() { - On => Off, - Off => On, - }); - debug!("Toggling debug state: {:?} -> {:?}", curr, next); -} - /// Create the Debugging UI fn init_debug_ui(mut commands: Commands) { commands.spawn(( @@ -60,6 +52,35 @@ fn init_debug_ui(mut commands: Commands) { ..default() }, )); + + commands.spawn(( + DebuggingState::On, + Text("Tooltip Placeholder".into()), + TextColor(WHITE.into()), + SyncResource::::default(), + BackgroundColor(BLACK.with_alpha(0.9).into()), + Node { + position_type: PositionType::Absolute, + margin: UiRect { left: Val::Px(20.0), ..default() }, + align_content: AlignContent::Center, + justify_content: JustifyContent::Center, + ..default() + }, + )); +} + +/// Toggles the debug state from off -> on // off -> on when triggered +fn toggle_debug_state( + mut next: ResMut>, + curr: Res>, +) { + use DebuggingState::*; + + next.set(match curr.get() { + On => Off, + Off => On, + }); + debug!("Toggling debug state: {:?} -> {:?}", curr, next); } /// Simple system that enables/disables rapier debug visuals when the debugging state changes @@ -69,3 +90,54 @@ fn toggle_rapier_debug_render( ) { context.enabled = *state.get() == DebuggingState::On; } + +/// Add a generic Tooltip that follows the mouse in debug mode +#[derive(Default, Resource)] +struct ToolTip(String); + +impl Display for ToolTip { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +fn tooltip_follow( + mut tooltip: Single<(&mut Node, &mut Visibility), With>>, + window: Single<&Window>, +) { + if let Some(Vec2 { x, y }) = window.cursor_position() { + *tooltip.1 = Visibility::Inherited; + tooltip.0.left = Val::Px(x); + tooltip.0.top = Val::Px(y); + } else { + *tooltip.1 = Visibility::Hidden; + } +} + +/// When you hover over a mesh, update the tooltip with some info +fn hover_mesh( + mut over_events: EventReader>, + mut out_events: EventReader>, + mut tooltip: ResMut, + meshes: Query<(&Transform, Option<&Name>), With>, +) { + out_events.read().filter_map(|Pointer { target, .. }| { + meshes.contains(*target).then_some(*target) + }).for_each(|_| { + tooltip.0 = "".into(); + }); + over_events.read().filter_map(|Pointer { target, .. }| { + meshes.contains(*target).then_some(*target) + }).for_each(|e| { + if let Ok((t, n)) = meshes.get(e) { + let pos = (t.translation.x, t.translation.y, t.translation.z); + let name = match n { + Some(x) => x, + None => "???", + }; + tooltip.0 = format!("ID: {e}\nPos: {pos:.3?}\nName: {name}"); + } else { + warn!("Failed to query data"); + } + }); +}