From 0b9d4d12f71f931d27ff781b57cf1228e2d93d0a Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Mon, 4 Aug 2025 16:01:23 +0200 Subject: [PATCH] Simpler default --- Cargo.toml | 4 +- README.md | 2 +- examples/bevy_gui.rs | 217 +++++ src/bin/render_lines_gui.rs | 1363 -------------------------------- src/main.rs | 1486 +++++++++++++++++++++++++++++++---- 5 files changed, 1537 insertions(+), 1535 deletions(-) create mode 100644 examples/bevy_gui.rs delete mode 100644 src/bin/render_lines_gui.rs diff --git a/Cargo.toml b/Cargo.toml index c01b7dc..f00332d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,8 @@ name = "laserspace" version = "0.1.0" edition = "2024" +authors = ["Ruben van de Ven "] +default-run = "laserspace" [dependencies] bevy = "0.15.3" @@ -35,5 +37,5 @@ geo = "0.30.0" opt-level = 3 [[bin]] -name="renderer" +name="laserspace" path="src/main.rs" diff --git a/README.md b/README.md index 9394f92..3d5f18b 100644 --- a/README.md +++ b/README.md @@ -32,5 +32,5 @@ By using ZMQ as input, the mapping of the lines is decoupled from the generation ## Usage ```bash -cargo run --bin render_lines_gui +cargo run ZMQ_QUEUE_ADDRESS ``` diff --git a/examples/bevy_gui.rs b/examples/bevy_gui.rs new file mode 100644 index 0000000..ddf0f10 --- /dev/null +++ b/examples/bevy_gui.rs @@ -0,0 +1,217 @@ +use bevy::prelude::*; + +use bevy_nannou::prelude::*; +use bevy_nannou::NannouPlugin; + +use nannou_laser::point::Rgb; + +use trap::laser::apply_homography_matrix; +use trap::laser::python_cv_h_into_mat3; +use trap::laser::LaserApi; +use trap::laser::LaserModel; +use trap::laser::LaserTimer; +use trap::laser::TMP_PYTHON_LASER_H; +use trap::shapes::PositionAndIntensity; +use trap::tracks::LaserPoints; +use trap::tracks::RenderableLines; +use trap::tracks::SpawnedTime; +use trap::tracks::Track; +use trap::zmqplugin::ZmqPlugin; +// use iyes_perf_ui::PerfUiPlugin; + +use nannou_laser as laser; +use trap::zmqplugin::ZmqReceiveTarget; + +use std::time::Duration; + + +pub mod trap; + +fn main() { + let mut app = App::new(); + // app.add_plugins((DefaultPlugins, NannouPlugin)) + app.add_plugins((DefaultPlugins, NannouPlugin)) + // .add_plugins(bevy::diagnostic::FrameTimeDiagnosticsPlugin) + // .add_plugins(bevy::diagnostic::EntityCountDiagnosticsPlugin) + // .add_plugins(bevy::diagnostic::SystemInformationDiagnosticsPlugin) + // .add_plugins(PerfUiPlugin) + .add_systems(Startup, setup) + .add_systems(Startup, setup_laser) + // .add_systems(Update, update) + .add_systems(Update, exit_system) + + + .add_plugins(ZmqPlugin { + // url: "tcp://localhost:5558".to_string(), + url: "tcp://100.109.175.82:99174".to_string(), + // url: "tcp://127.0.0.1:99173".to_string(), + filter: "".to_string(), + target: ZmqReceiveTarget::LINES + }) + + + .run(); +} + + +// Because of world.insert_non_send_resource, this is an exclusive system +// see: https://bevy-cheatbook.github.io/programming/exclusive.html +fn setup_laser(mut commands: Commands) { + + // laser works on non-exclusive system (like the normal setup()), _but_ world + // is needed in the laser callback + + // Initialise the state that we want to live on the laser thread and spawn the stream. + let laser_model = LaserModel::new(); + let _laser_api = laser::Api::new(); + // let detected_dacs = _laser_api.detect_dacs(DacVariant::DacVariantHelios); + + // while let Ok(res) = detected_dacs { + // if let laser::DetectDacs::Helios { previous_dac } = res { + // info!("DACS: {:?}", previous_dac); + // } + // } + + let laser_stream = _laser_api + .new_frame_stream(laser_model, laser_frame_producer) + // .detected_dac(dac) + .build() + .unwrap(); + + + let api = LaserApi { + _laser_api, + laser_stream, + // current_points: Vec::new(), + }; + commands.spawn((api, LaserTimer { + // create the non-repeating fuse timer + timer: Timer::new(Duration::from_millis(1000), TimerMode::Repeating), + })); +} + +fn setup(mut commands: Commands) { + // Spawn a camera for our main window + // TODO: look into https://docs.rs/visioncortex/latest/visioncortex/struct.PerspectiveTransform.html + + commands.spawn(render::NannouCamera); + +} + + +fn text2points_with_color(position_and_intensity: PositionAndIntensity, color: Rgb) -> laser::Point{ + let used_color = color.map(|v| v * position_and_intensity[2]); + let p = [position_and_intensity[0], -position_and_intensity[1]]; + laser::Point::new(p, color) +} + +fn text2points(position_and_intensity: PositionAndIntensity) -> laser::Point{ + let color = match position_and_intensity[2] { + 1.0 => [1.0; 3], + 0.0 => [0.0; 3], + _ => [1.0; 3] // TODO add provided color + }; + let p = [position_and_intensity[0], -position_and_intensity[1]]; + laser::Point::new(p, color) +} + +// impl Into for [[f32;3]; 3] { +// fn from(m) -> Self{ + +// } +// } + +const LASER_H: Mat3 = python_cv_h_into_mat3(TMP_PYTHON_LASER_H); +// const LASER_H: Mat3 = python_cv_h_into_mat3(TMP_PYTHON_LASER_H_FOR_NANNOU); + +fn laser_frame_producer(model: &mut LaserModel, frame: &mut laser::Frame){ + + // let dt = model.t.elapsed().as_millis(); + // let use_second = (dt % 1000) > 500; + + // let positions = match use_second { + // true => trap::shapes::YOUR_FUTURE, + // false => trap::shapes::ARE_YOU_SURE, + // }; + + let points = model.current_points.clone(); + + 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 s = 1.; // when using TMP_PYTHON_LASER_H_FOR_NANNOU -- doesn't work? + let s = 0xFFF as f32; // when using TMP_PYTHON_LASER_H + + let new_point = laser::Point { + position: [new_position[0]/s, new_position[1]/s], + .. point + }; + new_points.push(new_point); + } + + info!("Points {}", new_points.len()); + // println!("{:?}", new_points); + frame.add_lines(new_points); +} + + +fn get_laser_lines(use_second: bool) -> Vec{ + let positions = match use_second { + true => trap::shapes::YOUR_FUTURE, + false => trap::shapes::ARE_YOU_SURE, + }; + let points = positions.iter().cloned().map(text2points).collect(); + return points + +} + + + + + +fn exit_system(keys: Res>, mut exit: EventWriter) { + if keys.just_pressed(KeyCode::KeyQ) { + info!("Sending exit command"); + exit.send(AppExit::Success); + } +} + +fn update( + // mut commands: Commands, + // keys: Res>, + draws: Query<&Draw>, + mut lasers: Query<(&mut LaserApi, &mut LaserTimer)>, + tracks: Query<(&Track, &SpawnedTime)>, + time: Res