Add stub 3D gizmo
This commit is contained in:
parent
17635f056e
commit
4bfd6977c3
|
@ -8,7 +8,8 @@ bytemuck = "^1.0"
|
||||||
crossbeam-channel = "^0.5"
|
crossbeam-channel = "^0.5"
|
||||||
cyborg = { path = "../", features = ["legion"] }
|
cyborg = { path = "../", features = ["legion"] }
|
||||||
egui = "0.18"
|
egui = "0.18"
|
||||||
egui-winit = "0.18.0"
|
egui-gizmo = "0.7"
|
||||||
|
egui-winit = "0.18"
|
||||||
egui_wgpu_backend = "0.18.0"
|
egui_wgpu_backend = "0.18.0"
|
||||||
glam = { version = "0.20", features = ["serde"] }
|
glam = { version = "0.20", features = ["serde"] }
|
||||||
gltf = { version = "1.0", features = ["utils"] }
|
gltf = { version = "1.0", features = ["utils"] }
|
||||||
|
|
|
@ -211,7 +211,7 @@ impl UserInterface {
|
||||||
});
|
});
|
||||||
|
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
ui.add(viewport);
|
viewport.show(ui);
|
||||||
ui.heading("Viewport");
|
ui.heading("Viewport");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -260,6 +260,7 @@ pub struct ViewportWidget {
|
||||||
pub flycam: Flycam,
|
pub flycam: Flycam,
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
|
pub dragging: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ViewportWidget {
|
impl ViewportWidget {
|
||||||
|
@ -269,21 +270,39 @@ impl ViewportWidget {
|
||||||
flycam: Flycam::new(0.002, 10.0, 0.25),
|
flycam: Flycam::new(0.002, 10.0, 0.25),
|
||||||
width: 640,
|
width: 640,
|
||||||
height: 480,
|
height: 480,
|
||||||
|
dragging: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl egui::Widget for &mut ViewportWidget {
|
fn should_drag(
|
||||||
fn ui(self, ui: &mut egui::Ui) -> egui::Response {
|
&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);
|
ui.style_mut().spacing.window_margin = egui::style::Margin::same(0.0);
|
||||||
let rect = ui.max_rect();
|
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.width = rect.width().round() as u32;
|
||||||
self.height = rect.height().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};
|
use egui::{pos2, Color32, Mesh, Rect, Shape};
|
||||||
let mut mesh = Mesh::with_texture(self.texture);
|
let mut mesh = Mesh::with_texture(self.texture);
|
||||||
let uv = Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0));
|
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);
|
mesh.add_rect_with_uv(rect, uv, tint);
|
||||||
ui.painter().add(Shape::mesh(mesh));
|
ui.painter().add(Shape::mesh(mesh));
|
||||||
|
|
||||||
if response.dragged() {
|
let gizmo = egui_gizmo::Gizmo::new("My gizmo")
|
||||||
let delta = response.drag_delta();
|
.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);
|
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 {
|
match event {
|
||||||
egui::Event::Key { key, pressed, .. } => {
|
egui::Event::Key { key, pressed, .. } => {
|
||||||
use winit::event::{ElementState, VirtualKeyCode};
|
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.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] {
|
pub fn get_eye(&self) -> [f32; 4] {
|
||||||
self.position.extend(0.0).to_array()
|
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)
|
// view matrix is inverted camera pose (world space to camera space)
|
||||||
let rotation = Mat4::from_quat(self.get_orientation().inverse());
|
let rotation = Mat4::from_quat(self.get_orientation().inverse());
|
||||||
let translation = Mat4::from_translation(-self.position);
|
let translation = Mat4::from_translation(-self.position);
|
||||||
let view = rotation * translation;
|
rotation * translation
|
||||||
|
}
|
||||||
// perspective projection
|
|
||||||
let proj = Mat4::perspective_rh_gl(self.fovy, self.aspect, self.znear, self.zfar);
|
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;
|
let vp = proj * view;
|
||||||
vp.to_cols_array_2d()
|
vp.to_cols_array_2d()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue