From 0ffa97f9af9c5dec20e0ec9c6517cfec280a9211 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Fri, 1 May 2020 04:21:45 -0400 Subject: [PATCH] new arcball abstraction to clean up code --- src/graphics_gl.rs | 4 +- src/graphics_imgui.rs | 71 +++---------------- src/main.rs | 1 + src/mouse.rs | 84 +++++++++++++++++++++++ src/point_cloud/point_cloud_renderer.rs | 2 +- src/point_cloud/point_cloud_visualiser.rs | 5 +- 6 files changed, 101 insertions(+), 66 deletions(-) create mode 100644 src/mouse.rs diff --git a/src/graphics_gl.rs b/src/graphics_gl.rs index ad0c2fec42..44202e5093 100644 --- a/src/graphics_gl.rs +++ b/src/graphics_gl.rs @@ -30,6 +30,7 @@ use opengl::debug::enable_opengl_debugging; use arcball::ArcballCamera; use cgmath::Vector2; use cgmath::Vector3; +use mouse::SdlArcball; //use shader::Shader; @@ -131,8 +132,7 @@ pub fn run(capture_provider: Arc, calibration_data: k4a_sys::k4 true, ColorizationStrategy::Color, calibration_data, - Arc::new(Mutex::new(ArcballCamera::new(Vector3::new(0.0, 0.0, 0.0), 1.0, - [1280.0, 720.0]))) + Arc::new(Mutex::new(SdlArcball::new(100.0, 100.0))) ); // TODO - constructed in PointCloudWindow. diff --git a/src/graphics_imgui.rs b/src/graphics_imgui.rs index 300084f9ee..95bd09b59b 100644 --- a/src/graphics_imgui.rs +++ b/src/graphics_imgui.rs @@ -25,27 +25,21 @@ use std::fs::{File, OpenOptions}; use std::io::{Write, Read}; use std::os::unix::io::AsRawFd; use std::path::Path; -use std::sync::{Arc, Mutex, PoisonError}; +use std::sync::{Arc, Mutex, PoisonError, MutexGuard}; use std::time::{Instant, Duration}; use cgmath::Vector3; use cgmath::Vector2; use webcam::{WebcamWriter}; use std::error::Error; use arcball::ArcballCamera; +use mouse::SdlArcball; pub fn run(capture_provider: Arc, calibration_data: k4a_sys::k4a_calibration_t) { let mut webcam_writer = WebcamWriter::open_file("/dev/video0", 1280, 720, 3) .expect("should be able to create webcamwriter"); - let mut arcball_camera = Arc::new( - Mutex::new( - ArcballCamera::new(Vector3::new(0.0, 0.0, 0.0), 1.0, [1280.0, 720.0]))); - //[display_dims.0 as f32, display_dims.1 as f32]); - - // Track if left/right mouse is down - let mut mouse_pressed = [false, false]; - let mut prev_mouse = Vector2::new(0.0, 0.0); + let sdl_arcball = Arc::new(Mutex::new(SdlArcball::new(1280.0, 720.0))); let sdl_context = sdl2::init().unwrap(); let video = sdl_context.video().unwrap(); @@ -85,7 +79,7 @@ pub fn run(capture_provider: Arc, calibration_data: k4a_sys::k4 true, colorization_strategy, calibration_data, - arcball_camera.clone(), + sdl_arcball.clone(), ); //rebinder.restore(); @@ -106,7 +100,6 @@ pub fn run(capture_provider: Arc, calibration_data: k4a_sys::k4 let imgui_kinect_final_output = TextureId::from(texture.texture_id() as usize); - let mut imgui_sdl2 = imgui_sdl2::ImguiSdl2::new(&mut imgui, &window); let renderer = imgui_opengl_renderer::Renderer::new(&mut imgui, |s| video.gl_get_proc_address(s) as _); @@ -130,58 +123,14 @@ pub fn run(capture_provider: Arc, calibration_data: k4a_sys::k4 Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => { break 'running }, - Event::MouseButtonDown { timestamp, window_id, which, mouse_btn, clicks, x, y } => { - //println!("Mouse down"); - match mouse_btn { - sdl2::mouse::MouseButton::Left => mouse_pressed[0] = true, - sdl2::mouse::MouseButton::Right => mouse_pressed[1] = true, - _ => {}, - } - }, - Event::MouseButtonUp { timestamp, window_id, which, mouse_btn, clicks, x, y } => { - //println!("Mouse up"); - match mouse_btn { - sdl2::mouse::MouseButton::Left => mouse_pressed[0] = false, - sdl2::mouse::MouseButton::Right => mouse_pressed[1] = false, - _ => {}, - } - }, - Event::MouseMotion { timestamp, window_id, which, mousestate, x, y, xrel, yrel } => { - //println!("XY Mouse: {},{}", x, y); - if mouse_pressed[0] { - match arcball_camera.lock() { - Ok(mut arcball) => { - arcball.rotate( - Vector2::new(prev_mouse.x as f32, prev_mouse.y as f32), - Vector2::new(x as f32, y as f32), - ); - }, - Err(_) => {}, - } - } else if mouse_pressed[1] { - let mouse_delta = Vector2::new( - (x as f32 - prev_mouse.x as f32), - (prev_mouse.y as f32 - y as f32), // Invert scrolling - ); - match arcball_camera.lock() { - Ok(mut arcball) => { - arcball.pan(mouse_delta, 0.16); - }, - Err(_) => {}, - } - } - prev_mouse = Vector2::new(x as f32, y as f32); - }, - Event::MouseWheel { timestamp, window_id, which, x, y, direction } => { - match arcball_camera.lock() { - Ok(mut arcball) => { - arcball.zoom(y as f32, 0.16); - }, - Err(_) => {}, - } - }, _ => {} } + + // Also send to the arcball to update the view matrix. + match sdl_arcball.lock() { + Ok(mut arcball) => arcball.process_event(&event), + Err(_) => {}, + } } diff --git a/src/main.rs b/src/main.rs index 53b3e29385..f8a16fbd98 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,6 +70,7 @@ use rand::Rng; pub mod conversion; pub mod graphics_gl; +pub mod mouse; pub mod graphics_imgui; pub mod imgui_support; pub mod k4a_sys_wrapper; diff --git a/src/mouse.rs b/src/mouse.rs new file mode 100644 index 0000000000..9e52382a3c --- /dev/null +++ b/src/mouse.rs @@ -0,0 +1,84 @@ +use arcball::ArcballCamera; +use cgmath::{Vector2, Matrix4}; +use cgmath::Vector3; +use sdl2::event::Event; +use sdl2::mouse::MouseButton; + +/// Wrap a camera arcball for use with SDL +pub struct SdlArcball { + // TODO: Enable camera resizing (or change of texture to differently sized texture) + arcball: ArcballCamera, + left_mouse_active: bool, + right_mouse_active: bool, + last_x: f32, + last_y: f32, +} + +impl SdlArcball { + /// CTOR + pub fn new(width: f32, height: f32) -> Self { + let center = Vector3::new(0.0, 0.0, 0.0); + let zoom_speed = 1.0; + let screen = [width, height]; + let arcball = ArcballCamera::new(center, zoom_speed, screen); + Self { + arcball, + left_mouse_active: false, + right_mouse_active: false, + last_x: 0.0, + last_y: 0.0, + } + } + + pub fn process_event(&mut self, event: &Event) { + match event { + Event::MouseWheel { timestamp, window_id, which, x, y, direction } => { + self.mouse_wheel(*y); + }, + Event::MouseButtonDown { timestamp, window_id, which, mouse_btn, clicks, x, y } => { + self.mouse_button_press(mouse_btn, true); + }, + Event::MouseButtonUp { timestamp, window_id, which, mouse_btn, clicks, x, y } => { + self.mouse_button_press(mouse_btn, false); + }, + Event::MouseMotion { timestamp, window_id, which, mousestate, x, y, xrel, yrel } => { + let x = *x as f32; + let y = *y as f32; + self.mouse_motion(x, y); + self.last_x = x; + self.last_y = y; + }, + _ => {}, + } + } + + pub fn get_mat4(&self) -> Matrix4 { + self.arcball.get_mat4() + } + + fn mouse_wheel(&mut self, y: i32) { + self.arcball.zoom(y as f32, 0.16); + } + + fn mouse_button_press(&mut self, mouse_button: &MouseButton, down: bool) { + match mouse_button { + MouseButton::Left => self.left_mouse_active = down, + MouseButton::Right => self.right_mouse_active = down, + _ => {}, + } + } + + fn mouse_motion(&mut self, x: f32, y: f32) { + if self.left_mouse_active { + let previous = Vector2::new(self.last_x, self.last_y); + let current = Vector2::new(x, y); + self.arcball.rotate(previous, current); + } else if self.right_mouse_active { + let mouse_delta = Vector2::new( + (x - self.last_x), + (self.last_y - y), // Invert scrolling + ); + self.arcball.pan(mouse_delta, 0.16); + } + } +} diff --git a/src/point_cloud/point_cloud_renderer.rs b/src/point_cloud/point_cloud_renderer.rs index 23f0433dcf..439d259326 100644 --- a/src/point_cloud/point_cloud_renderer.rs +++ b/src/point_cloud/point_cloud_renderer.rs @@ -364,7 +364,7 @@ impl PointCloudRenderer { /// Update the view matrix /// pub fn update_view_projection(&mut self, proj_view: [[f32; 4]; 4]) { - println!("Matrix: {:?}", proj_view); + //println!("Matrix: {:?}", proj_view); self.proj_view = proj_view; } diff --git a/src/point_cloud/point_cloud_visualiser.rs b/src/point_cloud/point_cloud_visualiser.rs index a5c8618ce8..d1c1fd8126 100644 --- a/src/point_cloud/point_cloud_visualiser.rs +++ b/src/point_cloud/point_cloud_visualiser.rs @@ -21,6 +21,7 @@ use point_cloud::util::{ValueRange, get_depth_mode_range, colorize_depth_blue_to use arcball::ArcballCamera; use std::rc::Rc; use std::sync::{Arc, Mutex, PoisonError, MutexGuard}; +use mouse::SdlArcball; pub type Result = std::result::Result; @@ -93,7 +94,7 @@ pub enum ColorizationStrategy { } pub struct PointCloudVisualizer { - arcball_camera: Arc>>, + arcball_camera: Arc>, m_dimensions_width : i32, m_dimensions_height : i32, @@ -150,7 +151,7 @@ impl PointCloudVisualizer { pub fn new(enable_color_point_cloud: bool, initial_colorization_strategy: ColorizationStrategy, calibration_data: k4a_sys::k4a_calibration_t, - arcball_camera: Arc>>) -> Self + arcball_camera: Arc>) -> Self { // Resolution of the point cloud texture // constexpr ImageDimensions PointCloudVisualizerTextureDimensions = { 1280, 1152 };