diff --git a/Cargo.lock b/Cargo.lock index 040cd25..fc1de9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -340,6 +340,45 @@ dependencies = [ "bevy_internal", ] +[[package]] +name = "bevy-inspector-egui" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65b98d6fca1209c36c4d403c377f303aad22d940281fe1a9e431217516f0622" +dependencies = [ + "bevy-inspector-egui-derive", + "bevy_app", + "bevy_asset", + "bevy_core", + "bevy_core_pipeline", + "bevy_ecs", + "bevy_egui", + "bevy_hierarchy", + "bevy_log", + "bevy_math", + "bevy_pbr", + "bevy_reflect", + "bevy_render", + "bevy_utils", + "bevy_window", + "egui", + "image", + "once_cell", + "pretty-type-name", + "smallvec", +] + +[[package]] +name = "bevy-inspector-egui-derive" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec800b7cf98151b5dbff80f0eb6dffcb4bcfceef6e457888b395ead4eb7e75ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "bevy_a11y" version = "0.12.0" @@ -1861,6 +1900,18 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "entity-inspector" +version = "0.0.0" +dependencies = [ + "bevy", + "bevy-inspector-egui", + "bevy_egui", + "color-eyre", + "egui", + "tracing", +] + [[package]] name = "epaint" version = "0.23.0" @@ -3180,6 +3231,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "pretty-type-name" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f73cdaf19b52e6143685c3606206e114a4dfa969d6b14ec3894c88eb38bd4b" + [[package]] name = "proc-macro-crate" version = "1.3.1" diff --git a/Cargo.toml b/Cargo.toml index c25c358..899b18e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "skills/manipulation-flatscreen", "skills/openxr-6dof", "skills/xr-ik-mirror", + "skills/entity-inspector", ] # These settings will apply to all members of the workspace that opt in to them diff --git a/skills/entity-inspector/Cargo.toml b/skills/entity-inspector/Cargo.toml new file mode 100644 index 0000000..abc5e84 --- /dev/null +++ b/skills/entity-inspector/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "entity-inspector" +version.workspace = true +license.workspace = true +repository.workspace = true +edition.workspace = true +rust-version.workspace = true +publish = false + +# Current maintainer(s) +authors = ["lucas lelievre "] + +[dependencies] +bevy.workspace = true +egui.workspace = true +bevy_egui.workspace = true +bevy-inspector-egui.workspace = true +color-eyre.workspace = true +tracing.workspace = true diff --git a/skills/entity-inspector/README.md b/skills/entity-inspector/README.md new file mode 100644 index 0000000..578f80d --- /dev/null +++ b/skills/entity-inspector/README.md @@ -0,0 +1,8 @@ +# `entity-inspector` + +A entity inspector + +To run the code: +```bash +cargo run -p entity-inspector +``` diff --git a/skills/entity-inspector/src/main.rs b/skills/entity-inspector/src/main.rs new file mode 100644 index 0000000..cd16935 --- /dev/null +++ b/skills/entity-inspector/src/main.rs @@ -0,0 +1,135 @@ +use bevy::{pbr::DirectionalLightShadowMap, prelude::*, window::PrimaryWindow}; +use bevy_egui::{EguiContext, EguiPlugin}; +use bevy_inspector_egui::{ + bevy_inspector::hierarchy::SelectedEntities, DefaultInspectorConfigPlugin, +}; +use color_eyre::eyre::Result; +use tracing::info; + +const ASSET_FOLDER: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../../assets/"); + +fn main() -> Result<()> { + // Set up nice error messages + color_eyre::install()?; + + info!("Running `entity-inspector` skill"); + + App::new() + .add_plugins(DefaultPlugins.set(AssetPlugin { + file_path: ASSET_FOLDER.to_string(), + ..Default::default() + })) + .add_plugins(EguiPlugin) + .add_plugins(DefaultInspectorConfigPlugin) + .add_systems(Startup, setup) + .add_systems(Update, animate_light) + .add_systems(PostUpdate, inspector_ui) + .run(); + + Ok(()) +} + +fn setup( + assets: Res, + mut meshes: ResMut>, + mut materials: ResMut>, + mut commands: Commands, +) { + info!("Running setup system"); + + // Load assets + let tree_img: Handle = assets.load("tree.png"); + + // Build cube + commands.spawn(PbrBundle { + mesh: meshes.add(shape::Cube::default().into()), + material: materials.add(StandardMaterial { + base_color_texture: Some(tree_img), + ..default() + }), + ..default() + }); + + // Build the rest of the scene + commands.spawn(DirectionalLightBundle { + directional_light: DirectionalLight { + shadows_enabled: true, + illuminance: 10000., + ..default() + }, + transform: Transform::from_xyz(8.0, 16.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y), + ..default() + }); + commands.insert_resource(DirectionalLightShadowMap { size: 4096 }); + commands.spawn(Camera3dBundle { + transform: Transform::from_xyz(0.0, 6., 12.0) + .looking_at(Vec3::new(0., 1., 0.), Vec3::Y), + ..default() + }); + commands.spawn(PbrBundle { + mesh: meshes.add( + shape::Plane { + size: 10., + subdivisions: 4, + } + .into(), + ), + material: materials.add(Color::MIDNIGHT_BLUE.into()), + transform: Transform::from_xyz(0., 0., 0.), + ..default() + }); +} + +fn animate_light(mut query: Query<&mut Transform, With>) { + for mut t in query.iter_mut() { + let t: &mut Transform = &mut t; + t.rotate_y(0.01); + } +} + +fn inspector_ui(world: &mut World, mut selected_entities: Local) { + let mut egui_context = world + .query_filtered::<&mut EguiContext, With>() + .single(world) + .clone(); + + egui::SidePanel::left("hierarchy") + .default_width(200.0) + .show(egui_context.get_mut(), |ui| { + egui::ScrollArea::vertical().show(ui, |ui| { + ui.heading("Hierarchy"); + + bevy_inspector_egui::bevy_inspector::hierarchy::hierarchy_ui( + world, + ui, + &mut selected_entities, + ); + + ui.label("Press escape to toggle UI"); + ui.allocate_space(ui.available_size()); + }); + }); + + egui::SidePanel::right("inspector") + .default_width(250.0) + .show(egui_context.get_mut(), |ui| { + egui::ScrollArea::vertical().show(ui, |ui| { + ui.heading("Inspector"); + + match selected_entities.as_slice() { + &[entity] => { + bevy_inspector_egui::bevy_inspector::ui_for_entity( + world, entity, ui, + ); + } + entities => { + bevy_inspector_egui::bevy_inspector::ui_for_entities_shared_components( + world, entities, ui, + ); + } + } + + ui.allocate_space(ui.available_size()); + }); + }); +}