diff --git a/client/Cargo.toml b/client/Cargo.toml index 7b75abb..c2f17f5 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -10,13 +10,12 @@ build = "build.rs" [dependencies] bevy = { version = "0.15.1", features = ["jpeg", "trace_tracy", "trace_tracy_memory"] } -bevy_egui = "0.31.1" +bevy_egui = "0.33.0" bevy_asset = "0.15.0" -bevy-inspector-egui = "0.28.0" bevy_reflect = "0.15.0" bevy_render = "0.15.0" bevy_window = "0.15.0" -egui_dock = "0.14.0" +egui_tiles = "0.12.0" spacetimedb-sdk = "1.0" hex = "0.4" random_word = { version = "0.5.0", features = ["en"] } diff --git a/client/Config.toml b/client/Config.toml index 287dc86..498eddb 100644 --- a/client/Config.toml +++ b/client/Config.toml @@ -1,5 +1,5 @@ [server] -host = "http://100.85.241.101:3000" +host = "http://localhost:3000" database = "network-game" [movement] diff --git a/client/src/app.rs b/client/src/app.rs index 31874a2..7754636 100644 --- a/client/src/app.rs +++ b/client/src/app.rs @@ -1,76 +1,16 @@ use crate::helper::debug_gizmos::debug_gizmos; -use crate::helper::egui_dock::{ - reset_camera_viewport, set_camera_viewport, set_gizmo_mode, show_ui_system, UiState, -}; use bevy::prelude::*; -use crate::helper::*; -use bevy_egui::EguiSet; -use bevy_render::extract_resource::ExtractResourcePlugin; -use spacetimedb_sdk::{credentials, DbContext, Error, Event, Identity, Status, Table, TableWithPrimaryKey}; -use crate::plugins::network::systems::database::setup_database; -use crate::module_bindings::DbConnection; - pub struct AppPlugin; -#[derive(Resource, Debug)] -pub struct InspectorVisible(pub bool); - -impl Default for InspectorVisible { - fn default() -> Self { - InspectorVisible(false) - } -} impl Plugin for AppPlugin { fn build(&self, app: &mut App) { - app.insert_resource(UiState::new()); - app.insert_resource(InspectorVisible(true)); app.add_plugins(crate::plugins::ui::ui_plugin::UiPlugin); app.add_plugins(crate::plugins::environment::environment_plugin::EnvironmentPlugin); - app.add_plugins(crate::plugins::network::network_plugin::NetworkPlugin); + //app.add_plugins(crate::plugins::network::network_plugin::NetworkPlugin); app.add_plugins(crate::plugins::input::input_plugin::InputPlugin); - app.add_systems(Update, (debug_gizmos, toggle_ui_system)); - app.add_systems( - PostUpdate, - show_ui_system - .before(EguiSet::ProcessOutput) - .before(bevy_egui::systems::end_pass_system) - .before(TransformSystem::TransformPropagate) - .run_if(should_display_inspector), - ); - app.add_systems( - PostUpdate, - ( - set_camera_viewport - .after(show_ui_system) - .run_if(should_display_inspector), - reset_camera_viewport - .run_if(should_not_display_inspector) - .after(set_camera_viewport), - ), - ); - app.add_systems(Update, set_gizmo_mode); + app.add_systems(Update, (debug_gizmos)); app.register_type::>>(); app.register_type::(); } } - -fn toggle_ui_system( - keyboard_input: Res>, - mut inspector_visible: ResMut, -) { - // ======================= - // 6) Hide Inspector - // ======================= - if keyboard_input.just_pressed(KeyCode::F1) { - inspector_visible.0 = !inspector_visible.0 - } -} - -fn should_display_inspector(inspector_visible: Res) -> bool { - inspector_visible.0 -} - -fn should_not_display_inspector(inspector_visible: Res) -> bool { - !inspector_visible.0 -} diff --git a/client/src/helper/egui_dock.rs b/client/src/helper/egui_dock.rs deleted file mode 100644 index 57f83f1..0000000 --- a/client/src/helper/egui_dock.rs +++ /dev/null @@ -1,342 +0,0 @@ -use bevy::prelude::*; -use bevy_asset::{ReflectAsset, UntypedAssetId}; -use bevy_egui::{egui, EguiContext}; -use bevy_inspector_egui::bevy_inspector::hierarchy::{hierarchy_ui, SelectedEntities}; -use bevy_inspector_egui::bevy_inspector::{ - self, ui_for_entities_shared_components, ui_for_entity_with_children, -}; -use bevy_reflect::TypeRegistry; -use bevy_render::camera::{CameraProjection, Viewport}; -use bevy_window::{PrimaryWindow, Window}; -use egui_dock::{DockArea, DockState, NodeIndex, Style}; -use std::any::TypeId; - -#[cfg(egui_dock_gizmo)] -use transform_gizmo_egui::GizmoMode; - -/// Placeholder type if gizmo is disabled. -#[cfg(not(egui_dock_gizmo))] -#[derive(Clone, Copy)] -pub struct GizmoMode; - -#[derive(Component)] -pub struct MainCamera; - -pub fn show_ui_system(world: &mut World) { - let Ok(egui_context) = world - .query_filtered::<&mut EguiContext, With>() - .get_single(world) - else { - return; - }; - let mut egui_context = egui_context.clone(); - - world.resource_scope::(|world, mut ui_state| { - ui_state.ui(world, egui_context.get_mut()) - }); -} - -// make camera only render to view not obpub structed by UI -pub fn set_camera_viewport( - ui_state: Res, - primary_window: Query<&mut Window, With>, - egui_settings: Query<&bevy_egui::EguiSettings>, - mut cameras: Query<&mut Camera, With>, -) { - let mut cam = cameras.single_mut(); - - let Ok(window) = primary_window.get_single() else { - return; - }; - - let scale_factor = window.scale_factor() * egui_settings.single().scale_factor; - - let viewport_pos = ui_state.viewport_rect.left_top().to_vec2() * scale_factor; - let viewport_size = ui_state.viewport_rect.size() * scale_factor; - - let physical_position = UVec2::new(viewport_pos.x as u32, viewport_pos.y as u32); - let physical_size = UVec2::new(viewport_size.x as u32, viewport_size.y as u32); - - // The desired viewport rectangle at its offset in "physical pixel space" - let rect = physical_position + physical_size; - - let window_size = window.physical_size(); - // wgpu will panic if trying to set a viewport rect which has coordinates extending - // past the size of the render target, i.e. the physical window in our case. - // Typically this shouldn't happen- but during init and resizing etc. edge cases might occur. - // Simply do nothing in those cases. - if rect.x <= window_size.x && rect.y <= window_size.y { - cam.viewport = Some(Viewport { - physical_position, - physical_size, - depth: 0.0..1.0, - }); - } -} - -pub fn reset_camera_viewport(mut cameras: Query<&mut Camera, With>) { - if let Ok(mut cam) = cameras.get_single_mut() { - cam.viewport = None; // Reset the viewport to its default state - } -} -pub fn set_gizmo_mode(input: Res>, mut ui_state: ResMut) { - #[cfg(egui_dock_gizmo)] - let keybinds = [ - (KeyCode::KeyR, GizmoMode::Rotate), - (KeyCode::KeyT, GizmoMode::Translate), - (KeyCode::KeyS, GizmoMode::Scale), - ]; - #[cfg(not(egui_dock_gizmo))] - let keybinds = []; - for (key, mode) in keybinds { - if input.just_pressed(key) { - ui_state.gizmo_mode = mode; - } - } -} - -#[derive(Eq, PartialEq)] -pub enum InspectorSelection { - Entities, - Resource(TypeId, String), - Asset(TypeId, String, UntypedAssetId), -} - -#[derive(Resource)] -pub struct UiState { - state: DockState, - viewport_rect: egui::Rect, - selected_entities: SelectedEntities, - selection: InspectorSelection, - gizmo_mode: GizmoMode, -} - -impl UiState { - pub fn new() -> Self { - let mut state = DockState::new(vec![EguiWindow::GameView]); - let tree = state.main_surface_mut(); - let [game, _inspector] = - tree.split_right(NodeIndex::root(), 0.75, vec![EguiWindow::Inspector]); - let [game, _hierarchy] = tree.split_left(game, 0.2, vec![EguiWindow::Hierarchy]); - let [_game, _bottom] = - tree.split_below(game, 0.8, vec![EguiWindow::Resources, EguiWindow::Assets]); - - Self { - state, - selected_entities: SelectedEntities::default(), - selection: InspectorSelection::Entities, - viewport_rect: egui::Rect::NOTHING, - #[cfg(egui_dock_gizmo)] - gizmo_mode: GizmoMode::Translate, - #[cfg(not(egui_dock_gizmo))] - gizmo_mode: GizmoMode, - } - } - - pub fn ui(&mut self, world: &mut World, ctx: &mut egui::Context) { - let mut tab_viewer = TabViewer { - world, - viewport_rect: &mut self.viewport_rect, - selected_entities: &mut self.selected_entities, - selection: &mut self.selection, - gizmo_mode: self.gizmo_mode, - }; - DockArea::new(&mut self.state) - .style(Style::from_egui(ctx.style().as_ref())) - .show(ctx, &mut tab_viewer); - } -} - -#[derive(Debug)] -pub enum EguiWindow { - GameView, - Hierarchy, - Resources, - Assets, - Inspector, -} - -pub struct TabViewer<'a> { - world: &'a mut World, - selected_entities: &'a mut SelectedEntities, - selection: &'a mut InspectorSelection, - viewport_rect: &'a mut egui::Rect, - gizmo_mode: GizmoMode, -} - -impl egui_dock::TabViewer for TabViewer<'_> { - type Tab = EguiWindow; - - fn ui(&mut self, ui: &mut egui_dock::egui::Ui, window: &mut Self::Tab) { - let type_registry = self.world.resource::().0.clone(); - let type_registry = type_registry.read(); - - match window { - EguiWindow::GameView => { - *self.viewport_rect = ui.clip_rect(); - - draw_gizmo(ui, self.world, self.selected_entities, self.gizmo_mode); - } - EguiWindow::Hierarchy => { - let selected = hierarchy_ui(self.world, ui, self.selected_entities); - if selected { - *self.selection = InspectorSelection::Entities; - } - } - EguiWindow::Resources => select_resource(ui, &type_registry, self.selection), - EguiWindow::Assets => select_asset(ui, &type_registry, self.world, self.selection), - EguiWindow::Inspector => match *self.selection { - InspectorSelection::Entities => match self.selected_entities.as_slice() { - &[entity] => ui_for_entity_with_children(self.world, entity, ui), - entities => ui_for_entities_shared_components(self.world, entities, ui), - }, - InspectorSelection::Resource(type_id, ref name) => { - ui.label(name); - bevy_inspector::by_type_id::ui_for_resource( - self.world, - type_id, - ui, - name, - &type_registry, - ) - } - InspectorSelection::Asset(type_id, ref name, handle) => { - ui.label(name); - bevy_inspector::by_type_id::ui_for_asset( - self.world, - type_id, - handle, - ui, - &type_registry, - ); - } - }, - } - } - - fn title(&mut self, window: &mut Self::Tab) -> egui_dock::egui::WidgetText { - format!("{window:?}").into() - } - - fn clear_background(&self, window: &Self::Tab) -> bool { - !matches!(window, EguiWindow::GameView) - } -} - -#[allow(unused)] -pub fn draw_gizmo( - ui: &mut egui::Ui, - world: &mut World, - selected_entities: &SelectedEntities, - gizmo_mode: GizmoMode, -) { - let (cam_transform, projection) = world - .query_filtered::<(&GlobalTransform, &Projection), With>() - .single(world); - let view_matrix = Mat4::from(cam_transform.affine().inverse()); - let projection_matrix = projection.get_clip_from_view(); - - if selected_entities.len() != 1 { - #[allow(clippy::needless_return)] - return; - } - - /*for selected in selected_entities.iter() { - let Some(transform) = world.get::(selected) else { - continue; - }; - let model_matrix = transform.compute_matrix(); - - let mut gizmo = Gizmo::new(GizmoConfig { - view_matrix: view_matrix.into(), - projection_matrix: projection_matrix.into(), - orientation: GizmoOrientation::Local, - modes: EnumSet::from(gizmo_mode), - ..Default::default() - }); - let Some([result]) = gizmo - .interact(ui, model_matrix.into()) - .map(|(_, res)| res.as_slice()) - else { - continue; - }; - - let mut transform = world.get_mut::(selected).unwrap(); - transform = Transform { - translation: Vec3::from(<[f64; 3]>::from(result.translation)), - rotation: Quat::from_array(<[f64; 4]>::from(result.rotation)), - scale: Vec3::from(<[f64; 3]>::from(result.scale)), - }; - }*/ -} - -pub fn select_resource( - ui: &mut egui::Ui, - type_registry: &TypeRegistry, - selection: &mut InspectorSelection, -) { - let mut resources: Vec<_> = type_registry - .iter() - .filter(|registration| registration.data::().is_some()) - .map(|registration| { - ( - registration.type_info().type_path_table().short_path(), - registration.type_id(), - ) - }) - .collect(); - resources.sort_by(|(name_a, _), (name_b, _)| name_a.cmp(name_b)); - - for (resource_name, type_id) in resources { - let selected = match *selection { - InspectorSelection::Resource(selected, _) => selected == type_id, - _ => false, - }; - - if ui.selectable_label(selected, resource_name).clicked() { - *selection = InspectorSelection::Resource(type_id, resource_name.to_string()); - } - debug!("{}", resource_name); - } -} - -pub fn select_asset( - ui: &mut egui::Ui, - type_registry: &TypeRegistry, - world: &World, - selection: &mut InspectorSelection, -) { - let mut assets: Vec<_> = type_registry - .iter() - .filter_map(|registration| { - let reflect_asset = registration.data::()?; - Some(( - registration.type_info().type_path_table().short_path(), - registration.type_id(), - reflect_asset, - )) - }) - .collect(); - assets.sort_by(|(name_a, ..), (name_b, ..)| name_a.cmp(name_b)); - - for (asset_name, asset_type_id, reflect_asset) in assets { - let handles: Vec<_> = reflect_asset.ids(world).collect(); - - ui.collapsing(format!("{asset_name} ({})", handles.len()), |ui| { - for handle in handles { - let selected = match *selection { - InspectorSelection::Asset(_, _, selected_id) => selected_id == handle, - _ => false, - }; - - if ui - .selectable_label(selected, format!("{:?}", handle)) - .clicked() - { - *selection = - InspectorSelection::Asset(asset_type_id, asset_name.to_string(), handle); - } - } - }); - } -} diff --git a/client/src/helper/mod.rs b/client/src/helper/mod.rs index ad27699..03903cd 100644 --- a/client/src/helper/mod.rs +++ b/client/src/helper/mod.rs @@ -1,4 +1,3 @@ pub mod debug_gizmos; -pub mod egui_dock; pub mod vector_helper; pub mod math; diff --git a/client/src/main.rs b/client/src/main.rs index a754167..d53215b 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -13,7 +13,6 @@ use bevy::render::settings::{Backends, RenderCreation, WgpuSettings}; use bevy::render::RenderPlugin; use bevy::DefaultPlugins; use bevy_egui::EguiPlugin; -use bevy_inspector_egui::DefaultInspectorConfigPlugin; use bevy_window::{PresentMode, Window, WindowPlugin}; use toml; use crate::config::Config; @@ -42,7 +41,6 @@ fn main() { app.add_plugins(AppPlugin); app.add_plugins(EguiPlugin); - app.add_plugins(DefaultInspectorConfigPlugin); diff --git a/client/src/plugins/environment/environment_plugin.rs b/client/src/plugins/environment/environment_plugin.rs index 1b1aac5..9501495 100644 --- a/client/src/plugins/environment/environment_plugin.rs +++ b/client/src/plugins/environment/environment_plugin.rs @@ -5,7 +5,9 @@ impl Plugin for EnvironmentPlugin { app.add_systems( Startup, - (crate::plugins::environment::systems::camera_system::setup), + (crate::plugins::environment::systems::environment_system::setup, crate::plugins::environment::systems::camera_system::setup ), ); + + } } diff --git a/client/src/plugins/environment/systems/camera_system.rs b/client/src/plugins/environment/systems/camera_system.rs index 5fd17a5..860bb7a 100644 --- a/client/src/plugins/environment/systems/camera_system.rs +++ b/client/src/plugins/environment/systems/camera_system.rs @@ -1,4 +1,4 @@ -use crate::helper::egui_dock::MainCamera; + use bevy::input::mouse::{MouseMotion, MouseWheel}; use bevy::math::Vec3; use bevy::prelude::*; @@ -39,7 +39,6 @@ pub fn setup(mut commands: Commands,) { near: 0.0001, ..default() }), - MainCamera, CameraController::default(), Exposure::from_physical_camera(PhysicalCameraParameters { aperture_f_stops: 1.0, diff --git a/client/src/plugins/environment/systems/environment_system.rs b/client/src/plugins/environment/systems/environment_system.rs index f3101db..da7633f 100644 --- a/client/src/plugins/environment/systems/environment_system.rs +++ b/client/src/plugins/environment/systems/environment_system.rs @@ -2,10 +2,31 @@ use bevy::prelude::*; -pub fn setup(mut commands: Commands) { - + +pub(crate) fn setup( + mut commands : Commands, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + + // 2) directional light + commands.spawn(DirectionalLightBundle { + transform: Transform::from_rotation(Quat::from_euler( + EulerRot::XYZ, + -std::f32::consts::FRAC_PI_4, + std::f32::consts::FRAC_PI_4, + 0.0, + )), + directional_light: DirectionalLight { + shadows_enabled: true, + ..Default::default() + }, + ..Default::default() + }); + } + pub fn update(time: Res