diff --git a/Cargo.lock b/Cargo.lock index e3cb4c7..ea395f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5131,6 +5131,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "serde_spanned" version = "0.6.8" @@ -5721,6 +5732,7 @@ dependencies = [ "nannou_laser", "serde", "serde_json", + "serde_repr", "zmq", ] diff --git a/Cargo.toml b/Cargo.toml index cd73534..e8756a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ zmq = "0.10.0" nannou = "0.19.0" nannou_egui = { version = "0.19.0", features = ["wayland"] } +serde_repr = "0.1.20" [dev-dependencies] diff --git a/src/bin/render_lines_gui.rs b/src/bin/render_lines_gui.rs index 777000a..0e22515 100644 --- a/src/bin/render_lines_gui.rs +++ b/src/bin/render_lines_gui.rs @@ -3,12 +3,14 @@ //! UI. use bevy::math::Mat3; +use bevy_nannou::prelude::DARK_GRAY; use nannou::lyon::geom::euclid::Transform2D; use nannou::{geom::Rect, math::map_range as nannou_map_range}; use nannou::prelude::*; use nannou_egui::{self, egui, Egui}; use nannou_laser::{self as laser, util::map_range}; use serde_json::Result; +use trap_rust::trap::tracks::CoordinateSpace; use trap_rust::trap::{laser::{apply_homography_matrix, python_cv_h_into_mat3, LaserModel, TMP_PYTHON_LASER_H}, tracks::{LaserPoints, RenderableLines}}; use zmq::Socket; use std::sync::{mpsc, Arc}; @@ -37,6 +39,7 @@ struct Model { last_update: Instant, // dimming_factor: f32, lost_alpha: f32, + connected: bool, } struct LaserSettings { @@ -103,6 +106,7 @@ fn zmq_receive(model: &mut Model) { // let msg: Frame = serde_json::from_str(&json[4..]).expect("No valid json?"); let res: Result = serde_json::from_str(&json); model.lost_alpha = 1.; + model.connected = true; lines = match res { Ok(lines) => lines, // if Ok(255), set x to 255 @@ -110,13 +114,13 @@ fn zmq_receive(model: &mut Model) { println!("No valid json?"); println!("{}", _e); // empty if invalid - RenderableLines{ - lines: Vec::new() - } + RenderableLines::new() }, // if Err("some message"), panic with error message "some message" }; } else if model.last_update < Instant::now() - Duration::from_millis(100){ // set lines empty, if no new input for > 100ms (10fps) + model.connected = false; + if model.lost_alpha > 0.{ println!("No input, clear lines!!"); @@ -126,9 +130,7 @@ fn zmq_receive(model: &mut Model) { } lines = model.current_lines.with_alpha(model.lost_alpha); } else { - lines = RenderableLines{ - lines: Vec::new() - } + lines = RenderableLines::new() } } else { // No new lines, break @@ -241,6 +243,7 @@ fn model(app: &App) -> Model { current_lines: current_lines, last_update: Instant::now(), lost_alpha: 1., + connected: true, // dimming_factor: 1., } } @@ -265,12 +268,19 @@ const LASER_H: Mat3 = python_cv_h_into_mat3(TMP_PYTHON_LASER_H); fn laser_frame_producer(model: &mut LaserModel, frame: &mut laser::Frame){ let points: LaserPoints = (&model.current_lines).into(); + let space = &model.current_lines.space; let pointno = points.len(); let mut new_points = Vec::new(); for point in points.into_iter() { let p = point.position; - let new_position = apply_homography_matrix(LASER_H, &p); + let new_position = match space { + CoordinateSpace::World => apply_homography_matrix(LASER_H, &p), + CoordinateSpace::Laser => p, + _ => panic!("Invalid coordinate space"), + + }; + // let new_position = apply_homography_matrix(LASER_H, &p); // let s = 1.; // when using TMP_PYTHON_LASER_H_FOR_NANNOU -- doesn't work? let s = 0xFFF as f32 / 2.; // when using TMP_PYTHON_LASER_H let position = [new_position[0]/s - 1., new_position[1]/s - 1.]; @@ -514,7 +524,15 @@ fn view_line_canvas(app: &App, model: &Model, frame: Frame) { let draw = app.draw(); // set background to blue - draw.background().color(DARKGRAY); + + let bgcolor = match model.current_lines.space { + CoordinateSpace::Laser => MEDIUMSLATEBLUE, + _ => match model.connected{ + true => DARKGRAY, + false => LIGHTCORAL, + }, + }; + draw.background().color(bgcolor); let win = app.window_rect(); @@ -522,6 +540,8 @@ fn view_line_canvas(app: &App, model: &Model, frame: Frame) { let translate_x = -300.; let translate_y = -100.; + + draw_grid(&draw, &win, scale, 1.); // let t = app.time; diff --git a/src/trap/tracks.rs b/src/trap/tracks.rs index 10ec466..c253856 100644 --- a/src/trap/tracks.rs +++ b/src/trap/tracks.rs @@ -2,7 +2,7 @@ use bevy::prelude::*; use serde::{Serialize,Deserialize}; use std::time::Instant; use nannou_laser as laser; - +use serde_repr::*; #[derive(Serialize,Deserialize)] pub struct Frame { @@ -67,14 +67,25 @@ impl RenderableLine { } } +// see also trap/lines.py for matching values +#[derive(Clone, Debug, Serialize_repr, Deserialize_repr)] +#[repr(u8)] +pub enum CoordinateSpace { + Image = 1, + UndistortedImage = 2, + World = 3, + Laser = 4, +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RenderableLines{ - pub lines: Vec + pub lines: Vec, + pub space: CoordinateSpace, // enum in python } impl RenderableLines{ pub fn new() -> Self{ - RenderableLines { lines: Vec::new() } + RenderableLines { lines: Vec::new(), space: CoordinateSpace::World } } // pub fn append(&mut self, &mut rl: RenderableLines){ @@ -93,7 +104,7 @@ impl RenderableLines{ return self.clone(); } - Self { lines: self.lines.iter().map(|l| { l.with_alpha(alpha)}).collect() } + Self { lines: self.lines.iter().map(|l| { l.with_alpha(alpha)}).collect(), space: self.space.clone() } } } @@ -124,7 +135,7 @@ impl From<&Track> for RenderableLines{ } lines.push(RenderableLine{points}) } - RenderableLines { lines } + RenderableLines { lines, space: CoordinateSpace::World } } } diff --git a/src/trap/zmqplugin.rs b/src/trap/zmqplugin.rs index adfa4b1..93e056b 100644 --- a/src/trap/zmqplugin.rs +++ b/src/trap/zmqplugin.rs @@ -57,6 +57,7 @@ fn receive_zmq_lines( if items[0].is_readable() { let json = subscriber.recv_string(0).unwrap().unwrap(); // dbg!(&json[4..]); + dbg!(&json); // let msg: Frame = serde_json::from_str(&json[4..]).expect("No valid json?"); let res: Result = serde_json::from_str(&json);