diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/src/camera.rs | 2 | ||||
-rw-r--r-- | client/src/renderer.rs | 2 | ||||
-rw-r--r-- | client/src/state.rs | 24 | ||||
-rw-r--r-- | client/src/ui.rs | 61 | ||||
-rw-r--r-- | client/src/ui.wgsl | 3 |
5 files changed, 51 insertions, 41 deletions
diff --git a/client/src/camera.rs b/client/src/camera.rs index d2d4bda..4264e40 100644 --- a/client/src/camera.rs +++ b/client/src/camera.rs @@ -47,7 +47,7 @@ impl Camera { Mat3::from_euler(EulerRot::YXZ, self.rot.x, self.rot.y, self.rot.z) } pub fn to_matrix(&self) -> Mat4 { - Mat4::perspective_rh(self.fov, self.aspect, 0.1, 300.) + Mat4::perspective_rh(self.fov, self.aspect, 0.01, 300.) * Mat4::from_mat3(self.rotation_mat().inverse()) * Mat4::from_translation(-self.pos) } diff --git a/client/src/renderer.rs b/client/src/renderer.rs index 3359b4e..b4c2c05 100644 --- a/client/src/renderer.rs +++ b/client/src/renderer.rs @@ -170,7 +170,7 @@ impl<'a> Renderer<'a> { &mut self, scene: &SceneTree, camera: &Camera, - input_state: &InputState, + input_state: &mut InputState, ) -> Result<()> { if self.surface_needs_reconfigure { self.surface diff --git a/client/src/state.rs b/client/src/state.rs index 560c8bd..60be957 100644 --- a/client/src/state.rs +++ b/client/src/state.rs @@ -16,6 +16,7 @@ */ use crate::{ audio::Audio, camera::Camera, download::Downloader, network::Network, renderer::Renderer, + ui::UiEvent, }; use anyhow::{Context, Result}; use glam::{Vec2, Vec3}; @@ -49,7 +50,7 @@ pub struct InputState { pub move_dir: Vec3, pub mouse_acc: Vec2, pub cursor_pos: Vec2, - pub egui_events: Vec<egui::Event>, + pub ui_events: Vec<UiEvent>, } impl<'a> State<'a> { @@ -68,7 +69,7 @@ impl<'a> State<'a> { move_dir: Vec3::ZERO, mouse_acc: Vec2::ZERO, cursor_pos: Vec2::ZERO, - egui_events: Vec::new(), + ui_events: Vec::new(), }, prefab_index_res: None, prefab_index_res_loaded: None, @@ -80,7 +81,7 @@ impl<'a> State<'a> { pub fn draw(&mut self) { if let Err(e) = self .renderer - .draw(&self.tree, &self.camera, &self.input_state) + .draw(&self.tree, &self.camera, &mut self.input_state) { warn!("draw failed: {e:?}"); } @@ -91,20 +92,8 @@ impl<'a> State<'a> { } pub fn click(&mut self, button: MouseButton, down: bool) { self.input_state - .egui_events - .push(egui::Event::PointerButton { - pos: egui::Pos2::new(self.input_state.cursor_pos.x, self.input_state.cursor_pos.y), - button: match button { - MouseButton::Left => egui::PointerButton::Primary, - MouseButton::Right => egui::PointerButton::Secondary, - MouseButton::Middle => egui::PointerButton::Middle, - MouseButton::Back => egui::PointerButton::Extra1, - MouseButton::Forward => egui::PointerButton::Extra2, - MouseButton::Other(_) => egui::PointerButton::Extra1, - }, - pressed: down, - modifiers: egui::Modifiers::default(), - }); + .ui_events + .push(UiEvent::Click(self.input_state.cursor_pos, button, down)); if !down || button != MouseButton::Right { return; @@ -196,7 +185,6 @@ impl<'a> State<'a> { } } - self.input_state.egui_events.clear(); Ok(()) } } 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(); } } diff --git a/client/src/ui.wgsl b/client/src/ui.wgsl index 4f55e25..a444f71 100644 --- a/client/src/ui.wgsl +++ b/client/src/ui.wgsl @@ -39,8 +39,7 @@ fn unpack_color(color: u32) -> vec4<f32> { @vertex fn vs_main(@builtin(vertex_index) vindex: u32, vi: VertexIn) -> VertexOut { - var clip = project * vec4(vi.pos / 10., 0., 1.); - // var clip = vec4(vi.pos / 100., 0., 1.); + var clip = project * vec4(vi.pos, 0., 1.); let vo = VertexOut(clip, vi.uv, unpack_color(vi.color)); return vo; } |