diff --git a/src/bin/render_lines_gui.rs b/src/bin/render_lines_gui.rs index d1136c0..310ed4a 100644 --- a/src/bin/render_lines_gui.rs +++ b/src/bin/render_lines_gui.rs @@ -22,6 +22,8 @@ use std::time::{Instant, Duration}; use std::collections::HashMap; use serde::{Serialize,Deserialize}; +use nannou::winit::dpi::PhysicalPosition; + use homography::find_homography; use cv_core::FeatureMatch; // use opencv::prelude::Mat; @@ -313,7 +315,7 @@ fn model(app: &App) -> GuiModel { .new_window() .size(1024, 768) // .key_pressed(key_pressed) - // .mouse_wheel(canvas_zoom) + .mouse_wheel(map_wheel_zoom) .mouse_pressed(map_mouse_pressed) .mouse_released(map_mouse_released) .mouse_moved(map_mouse_moved) @@ -743,7 +745,7 @@ fn update(_app: &App, model: &mut GuiModel, update: Update) { } if ui - .add(egui::Slider::new(&mut selected_config.filters.scale.factor, 0.0..=2.).text("Scale")) + .add(egui::Slider::new(&mut selected_config.filters.scale.factor, 0.001..=2.).text("Scale")) .changed() { let factor = selected_config.filters.scale.factor; @@ -835,8 +837,9 @@ fn view_line_canvas(app: &App, model: &GuiModel, frame: Frame) { // get canvas to draw on let draw = app.draw(); - // set background to blue - + // LaserPoints supports a mode that sends points directly into the laser + // if this mode is enabled by the sender, set background to blue + // Red if nothing is sending / not for too long. let bgcolor = match model.current_lines.space { CoordinateSpace::Laser => MEDIUMSLATEBLUE, _ => match model.connected{ @@ -852,13 +855,13 @@ fn view_line_canvas(app: &App, model: &GuiModel, frame: Frame) { let translate_x = model.canvas_translate.x; let translate_y = model.canvas_translate.y; + // background grid draw_grid(&draw, &win, scale, 1.); - // let t = app.time; - // let n_points = 10; let thickness = 2.0; - draw.ellipse() + // draw origin indicator + draw.ellipse() .x_y(0. + translate_x, 0. + translate_y) .radius(3.) .color(BLUE); @@ -868,9 +871,9 @@ fn view_line_canvas(app: &App, model: &GuiModel, frame: Frame) { .color(RED) .points([0. * scale + translate_x, 0. * -scale + translate_y].into(), [1. * scale + translate_x, 0. * -scale + translate_y].into()); - // let hz = ((app.mouse.x + win.right()) / win.w()).powi(4) * 1000.0; + - // TODO refactor to using euclid::point2D for scale + // draw current laser lines for line in &model.current_lines.lines{ let vertices = line.points.iter().map(|p| { let color = srgba(p.color.red, p.color.green, p.color.blue, p.color.alpha); @@ -885,6 +888,7 @@ fn view_line_canvas(app: &App, model: &GuiModel, frame: Frame) { .points_colored(vertices); } + // show each configured laser in the canvas. Highlight the selected. for (dac_id, config) in model.per_laser_config.iter() { let rect = shape_rect(LaserSpace::READY); let points = config.filters.reverse(&rect); @@ -893,9 +897,12 @@ fn view_line_canvas(app: &App, model: &GuiModel, frame: Frame) { let vertices = points.points.iter().map(|p| { let color = if model.selected_stream == Some(dac_id.clone()) { - srgba(1.,0.,0.,1.) + // Srgba::hex("e52d9f"); + // ORCHID. to_srgba() + srgba(229./255.,45./255.,159./255.,0.8) } else { - srgba(p.color[0], p.color[1], p.color[0], 0.5) + // ORCHID; + srgba(1.,1.,1., 0.2) }; let pos = [p.position[0] * scale + translate_x, p.position[1] * -scale + translate_y]; @@ -1094,7 +1101,7 @@ fn map_mouse_moved(_app: &App, model: &mut GuiModel, pos: Point2) { let distorted_laser_corners: Vec<[f32;2]> = config.filters.reverse_without_homography(&laser_corners).into(); - // 4. find new homography: + // 4. find new homography on pairs of points, and convert to compatible matrix type let matches: Vec>> = world_corners.iter().zip(distorted_laser_corners).map(|(world, laser)| { FeatureMatch( nalgebra::Point2::new(world[0] as f64, world[1] as f64), @@ -1102,12 +1109,18 @@ fn map_mouse_moved(_app: &App, model: &mut GuiModel, pos: Point2) { ) }).collect::>(); - let m = find_homography(matches).unwrap(); - let mat: Mat3 = Mat3::from_cols_array(&[m[0] as f32, m[1] as f32, m[2] as f32, m[3] as f32, m[4] as f32, m[5] as f32, m[6] as f32, m[7] as f32, m[8] as f32]); - config.filters.homography.homography_matrix = mat; + // 5. update config in Gui and laser stream threat + config.filters.homography.homography_matrix = mat.clone(); + + let selected_laser_stream = model.laser_streams.get(&dac_id); + if let Some(stream) = selected_laser_stream { + stream.send(move |laser_model: &mut LaserModel| { + laser_model.config.filters.homography.homography_matrix = mat; + }).unwrap(); + } } @@ -1173,6 +1186,11 @@ fn map_mouse_released(_app: &App, model: &mut GuiModel, _button: MouseButton) { model.canvas_dragging_corner = None; } -fn mouse_wheel(_app: &App, _model: &mut GuiModel, _dt: MouseScrollDelta, _phase: TouchPhase) { - // canvas zoom +fn map_wheel_zoom(_app: &App, model: &mut GuiModel, dt: MouseScrollDelta, _phase: TouchPhase) { + let (x,y) = match dt { + MouseScrollDelta::PixelDelta(PhysicalPosition::{ x, y }) => (x as f32, y as f32), + MouseScrollDelta::LineDelta(x, y) => (x,y), + }; + + model.canvas_scale += y; } diff --git a/src/trap/filters.rs b/src/trap/filters.rs index f896a69..bd222ab 100644 --- a/src/trap/filters.rs +++ b/src/trap/filters.rs @@ -149,7 +149,7 @@ impl Filter for HomographyFilter { let s = 0xFFF as f32 / 2.; let normalised_pos: [f32;2] = [new_position[0]/s - 1., new_position[1]/s - 1.]; laser::Point { - position: normalised_pos, + position: new_position, .. point.clone() } @@ -165,9 +165,9 @@ impl Filter for HomographyFilter { let inv_matrix = self.homography_matrix.inverse(); let projected_positions: Vec = points.points.iter().map(|point| { - let s = 0xFFF as f32 / 2.; let p = point.position; - let de_normalised_position: [f32;2] = [(p[0] + 1.)*s, (p[1]+1.)*s]; + // let s = 0xFFF as f32 / 2.; + // let de_normalised_position: [f32;2] = [(p[0] + 1.)*s, (p[1]+1.)*s]; let new_position = match space { CoordinateSpace::World => p, CoordinateSpace::Laser => apply_homography_matrix(inv_matrix, &p),