diff options
Diffstat (limited to 'client/src/ui.rs')
-rw-r--r-- | client/src/ui.rs | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/client/src/ui.rs b/client/src/ui.rs index aa062fe..c477d07 100644 --- a/client/src/ui.rs +++ b/client/src/ui.rs @@ -16,7 +16,7 @@ */ use crate::state::InputState; use egui::{ - Context, Event, ImageData, TextureId, ViewportId, ViewportInfo, + Context, Event, ImageData, PointerButton, TextureId, ViewportId, ViewportInfo, epaint::{ImageDelta, Primitive, Vertex}, }; use glam::{Affine3A, Mat2, Mat3, Mat4, Vec2, Vec3Swizzles, Vec4Swizzles, vec2, vec4}; @@ -43,6 +43,7 @@ use wgpu::{ util::{DeviceExt, TextureDataOrder}, vertex_attr_array, }; +use winit::event::MouseButton; pub struct UiRenderer { device: Arc<Device>, @@ -66,6 +67,10 @@ pub struct UiSurface { vertex_capacity: usize, } +pub enum UiEvent { + Click(Vec2, MouseButton, bool), +} + impl UiRenderer { pub fn new(device: Arc<Device>, queue: Arc<Queue>, format: TextureFormat) -> Self { let module = device.create_shader_module(include_wgsl!("ui.wgsl")); @@ -278,7 +283,7 @@ impl UiRenderer { target: &TextureView, depth: &TextureView, projection: Mat4, - input_state: &InputState, + input_state: &mut InputState, surface_configuration: &SurfaceConfiguration, ) { let mut surfaces = self.surfaces.write().unwrap(); @@ -323,7 +328,7 @@ impl UiRenderer { let mut surfaces_closed = Vec::new(); for (viewport_id, surf) in surfaces.iter_mut() { - let scale = 0.03; + let scale = 0.005; let projection = projection * Mat4::from_translation(surf.transform.translation.into()) * Mat4::from_mat3a(surf.transform.matrix3) @@ -336,31 +341,33 @@ impl UiRenderer { surface_configuration.height as f32, ); - let mouse_xy_clip = (input_state.cursor_pos / screen_size) * 2. - 1.; - if projection.determinant() < 0e-4 { warn!("bad UI projection") } let unproject = projection.inverse(); - let mut mouse_world_1 = unproject * vec4(mouse_xy_clip.x, -mouse_xy_clip.y, 0.0, 1.0); - let mut mouse_world_2 = unproject * vec4(mouse_xy_clip.x, -mouse_xy_clip.y, 1.0, 1.0); - mouse_world_1 /= mouse_world_1.w; - mouse_world_2 /= mouse_world_2.w; - let mouse_world_1 = mouse_world_1.xyz(); - let mouse_world_2 = mouse_world_2.xyz(); + let unproject_mouse = |pos: Vec2| { + let mouse_xy_clip = (pos / screen_size) * 2. - 1.; + let mut mouse_world_1 = + unproject * vec4(mouse_xy_clip.x, -mouse_xy_clip.y, 0.0, 1.0); + let mut mouse_world_2 = + unproject * vec4(mouse_xy_clip.x, -mouse_xy_clip.y, 1.0, 1.0); + mouse_world_1 /= mouse_world_1.w; + mouse_world_2 /= mouse_world_2.w; + let mouse_world_1 = mouse_world_1.xyz(); + let mouse_world_2 = mouse_world_2.xyz(); - let ray_norm = (mouse_world_2 - mouse_world_1).normalize(); - let ray_t = mouse_world_1.z / ray_norm.z; - let ray_hit = mouse_world_1 - ray_norm * ray_t; + let ray_norm = (mouse_world_2 - mouse_world_1).normalize(); + let ray_t = mouse_world_1.z / ray_norm.z; + let ray_hit = mouse_world_1 - ray_norm * ray_t; - debug_assert!(ray_hit.z.abs() < 0.1, "mouse was not projected properly"); + debug_assert!(ray_hit.z.abs() < 0.1, "mouse was not projected properly"); - eprintln!("z={} t={ray_t}", mouse_world_1.z); - eprintln!("hit={ray_hit}"); + ray_hit.xy() + }; - let cursor_pos = ray_hit.xy(); + let cursor_pos = unproject_mouse(input_state.cursor_pos); let mut raw_input = raw_input.clone(); if cursor_pos != self.last_pointer { @@ -372,7 +379,21 @@ impl UiRenderer { } raw_input .events - .extend(input_state.egui_events.iter().cloned()); + .extend(input_state.ui_events.iter().map(|e| match e { + UiEvent::Click(pos, button, down) => egui::Event::PointerButton { + pos: egui::Pos2::from(unproject_mouse(*pos).to_array()), + button: match button { + MouseButton::Left => PointerButton::Primary, + MouseButton::Right => PointerButton::Secondary, + MouseButton::Middle => PointerButton::Middle, + MouseButton::Back => PointerButton::Extra1, + MouseButton::Forward => PointerButton::Extra2, + MouseButton::Other(_) => PointerButton::Extra1, + }, + pressed: *down, + modifiers: egui::Modifiers::default(), + }, + })); let mut close = false; let full_output = self.ctx.run(raw_input.clone(), |ctx| { @@ -490,5 +511,7 @@ impl UiRenderer { info!("ui surface closed: {s:?}"); surfaces.remove(&s); } + + input_state.ui_events.clear(); } } |