summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-17 23:32:27 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-17 23:32:27 +0100
commitf5ffcaf01b91daf0019dd6534b035398fa51f2f0 (patch)
treeef271596fee967ded3c7c1668033bba97823afbd
parent1ca762dedcdd6c87086560dd56ab3566b08243d0 (diff)
downloadweareserver-f5ffcaf01b91daf0019dd6534b035398fa51f2f0.tar
weareserver-f5ffcaf01b91daf0019dd6534b035398fa51f2f0.tar.bz2
weareserver-f5ffcaf01b91daf0019dd6534b035398fa51f2f0.tar.zst
fix ui unprojection
-rw-r--r--client/src/camera.rs2
-rw-r--r--client/src/renderer.rs2
-rw-r--r--client/src/state.rs24
-rw-r--r--client/src/ui.rs61
-rw-r--r--client/src/ui.wgsl3
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;
}