Add stub 3D gizmo
This commit is contained in:
parent
17635f056e
commit
4bfd6977c3
|
@ -8,7 +8,8 @@ bytemuck = "^1.0"
|
|||
crossbeam-channel = "^0.5"
|
||||
cyborg = { path = "../", features = ["legion"] }
|
||||
egui = "0.18"
|
||||
egui-winit = "0.18.0"
|
||||
egui-gizmo = "0.7"
|
||||
egui-winit = "0.18"
|
||||
egui_wgpu_backend = "0.18.0"
|
||||
glam = { version = "0.20", features = ["serde"] }
|
||||
gltf = { version = "1.0", features = ["utils"] }
|
||||
|
|
|
@ -211,7 +211,7 @@ impl UserInterface {
|
|||
});
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.add(viewport);
|
||||
viewport.show(ui);
|
||||
ui.heading("Viewport");
|
||||
});
|
||||
}
|
||||
|
@ -260,6 +260,7 @@ pub struct ViewportWidget {
|
|||
pub flycam: Flycam,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub dragging: bool,
|
||||
}
|
||||
|
||||
impl ViewportWidget {
|
||||
|
@ -269,21 +270,39 @@ impl ViewportWidget {
|
|||
flycam: Flycam::new(0.002, 10.0, 0.25),
|
||||
width: 640,
|
||||
height: 480,
|
||||
dragging: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl egui::Widget for &mut ViewportWidget {
|
||||
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
|
||||
fn should_drag(
|
||||
&self,
|
||||
viewport: egui::Rect,
|
||||
gizmo_active: bool,
|
||||
pointer: &egui::PointerState,
|
||||
) -> bool {
|
||||
if gizmo_active {
|
||||
false
|
||||
} else if !pointer.primary_down() {
|
||||
false
|
||||
} else if self.dragging {
|
||||
true
|
||||
} else if let Some(pos) = pointer.interact_pos() {
|
||||
viewport.contains(pos)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn show(&mut self, ui: &mut egui::Ui) {
|
||||
ui.style_mut().spacing.window_margin = egui::style::Margin::same(0.0);
|
||||
let rect = ui.max_rect();
|
||||
let id = egui::Id::new("viewport_widget");
|
||||
let sense = egui::Sense::click_and_drag();
|
||||
let response = ui.interact(rect, id, sense);
|
||||
|
||||
self.width = rect.width().round() as u32;
|
||||
self.height = rect.height().round() as u32;
|
||||
|
||||
self.flycam.resize(self.width, self.height);
|
||||
self.flycam.update();
|
||||
|
||||
use egui::{pos2, Color32, Mesh, Rect, Shape};
|
||||
let mut mesh = Mesh::with_texture(self.texture);
|
||||
let uv = Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0));
|
||||
|
@ -291,11 +310,22 @@ impl egui::Widget for &mut ViewportWidget {
|
|||
mesh.add_rect_with_uv(rect, uv, tint);
|
||||
ui.painter().add(Shape::mesh(mesh));
|
||||
|
||||
if response.dragged() {
|
||||
let delta = response.drag_delta();
|
||||
let gizmo = egui_gizmo::Gizmo::new("My gizmo")
|
||||
.viewport(rect)
|
||||
.view_matrix(self.flycam.get_view().to_cols_array_2d())
|
||||
.projection_matrix(self.flycam.get_projection().to_cols_array_2d());
|
||||
|
||||
let gizmo = gizmo.interact(ui);
|
||||
|
||||
let input = ui.input();
|
||||
|
||||
self.dragging = self.should_drag(rect, gizmo.is_some(), &input.pointer);
|
||||
|
||||
if self.dragging {
|
||||
let delta = input.pointer.delta();
|
||||
self.flycam.process_mouse(delta.x as f64, delta.y as f64);
|
||||
|
||||
for event in ui.input().events.iter() {
|
||||
for event in input.events.iter() {
|
||||
match event {
|
||||
egui::Event::Key { key, pressed, .. } => {
|
||||
use winit::event::{ElementState, VirtualKeyCode};
|
||||
|
@ -324,14 +354,9 @@ impl egui::Widget for &mut ViewportWidget {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
} else if response.drag_released() {
|
||||
} else {
|
||||
self.flycam.defocus();
|
||||
}
|
||||
|
||||
self.flycam.resize(self.width, self.height);
|
||||
self.flycam.update();
|
||||
|
||||
response
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -233,16 +233,21 @@ impl Flycam {
|
|||
pub fn get_eye(&self) -> [f32; 4] {
|
||||
self.position.extend(0.0).to_array()
|
||||
}
|
||||
|
||||
pub fn get_vp(&self) -> [[f32; 4]; 4] {
|
||||
|
||||
pub fn get_view(&self) -> glam::Mat4 {
|
||||
// view matrix is inverted camera pose (world space to camera space)
|
||||
let rotation = Mat4::from_quat(self.get_orientation().inverse());
|
||||
let translation = Mat4::from_translation(-self.position);
|
||||
let view = rotation * translation;
|
||||
|
||||
// perspective projection
|
||||
let proj = Mat4::perspective_rh_gl(self.fovy, self.aspect, self.znear, self.zfar);
|
||||
rotation * translation
|
||||
}
|
||||
|
||||
pub fn get_projection(&self) -> glam::Mat4 {
|
||||
Mat4::perspective_rh_gl(self.fovy, self.aspect, self.znear, self.zfar)
|
||||
}
|
||||
|
||||
pub fn get_vp(&self) -> [[f32; 4]; 4] {
|
||||
let view = self.get_view();
|
||||
let proj = self.get_projection();
|
||||
let vp = proj * view;
|
||||
vp.to_cols_array_2d()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue