From 9e9d65b4568f99ac0e5ed226a0e3f247416a5b73 Mon Sep 17 00:00:00 2001 From: TEKGroneschild Date: Tue, 11 Jun 2024 17:56:44 +0200 Subject: [PATCH] More height offset options. reletive to ground and reletive to start --- .../src/newgui/hud/toolbox/roadbuild.rs | 97 ++++++++++++------- native_app/src/newgui/tools/roadbuild.rs | 54 ++++++----- 2 files changed, 92 insertions(+), 59 deletions(-) diff --git a/native_app/src/newgui/hud/toolbox/roadbuild.rs b/native_app/src/newgui/hud/toolbox/roadbuild.rs index 14f32474..c6b7fc09 100644 --- a/native_app/src/newgui/hud/toolbox/roadbuild.rs +++ b/native_app/src/newgui/hud/toolbox/roadbuild.rs @@ -3,11 +3,11 @@ use yakui::{ image, reflow, Alignment, Color, CrossAxisAlignment, Dim2, MainAxisAlignment, MainAxisSize, Vec2 }; -use goryak::{image_button, mincolumn, padxy, primary}; +use goryak::{image_button, mincolumn, minrow, padxy, primary}; use simulation::map::LanePatternBuilder; use crate::newgui::hud::toolbox::updown_value; -use crate::newgui::roadbuild::{RoadBuildResource, Snapping}; +use crate::newgui::roadbuild::{HeightReference, RoadBuildResource, Snapping}; use crate::newgui::textures::UiTextures; use crate::uiworld::UiWorld; @@ -24,43 +24,66 @@ pub fn roadbuild_properties(uiw: &UiWorld) { let active = (c, c.with_alpha(0.7)); let default = (Color::WHITE.with_alpha(0.3), Color::WHITE.with_alpha(0.5)); - mincolumn(0.0, || { - let (snapping_none, snapping_grid, snapping_angel) = match state.snapping { - Snapping::None => {(active, default, default)}, - Snapping::SnapToGrid => {(default, active, default)}, - Snapping::SnapToAngle => {(default, default, active)}, - }; - - if image_button( - uiw.read::().get("snap_notting"), - Vec2::new(25.0, 25.0), - snapping_none.0, - snapping_none.1, - primary(), - "no snapping", - ).clicked { state.snapping = Snapping::None; } + mincolumn(4.0, || { + minrow(2.0, || { + let (snapping_none, snapping_grid, snapping_angel) = match state.snapping { + Snapping::None => {(active, default, default)}, + Snapping::SnapToGrid => {(default, active, default)}, + Snapping::SnapToAngle => {(default, default, active)}, + }; + if image_button( + uiw.read::().get("snap_notting"), + Vec2::new(30.0, 30.0), + snapping_none.0, snapping_none.1, + primary(), "no snapping", + ).clicked { state.snapping = Snapping::None; } + if image_button( + uiw.read::().get("snap_grid"), + Vec2::new(30.0, 30.0), + snapping_grid.0, snapping_grid.1, + primary(), "snap to grid", + ).clicked { state.snapping = Snapping::SnapToGrid; } + if image_button( + uiw.read::().get("snap_angle"), + Vec2::new(30.0, 30.0), + snapping_angel.0, snapping_angel.1, + primary(), "snap to angle", + ).clicked { state.snapping = Snapping::SnapToAngle; } + }); - if image_button( - uiw.read::().get("snap_grid"), - Vec2::new(25.0, 25.0), - snapping_grid.0, - snapping_grid.1, - primary(), - "snap to grid", - ) - .clicked { state.snapping = Snapping::SnapToGrid; } - - if image_button( - uiw.read::().get("snap_angle"), - Vec2::new(25.0, 25.0), - snapping_angel.0, - snapping_angel.1, - primary(), - "snap to angle", - ) - .clicked { state.snapping = Snapping::SnapToAngle; } + minrow(2.0, || { + let (hos_ground, hos_start, hos_incline, hos_decline) = match state.height_reference { + HeightReference::Ground => {(active, default, default, default)}, + HeightReference::Start => {(default, active, default, default)}, + HeightReference::MaxIncline => {(default, default, active, default)}, + HeightReference::MaxDecline => {(default, default, default, active)}, + }; + if image_button( + uiw.read::().get("height_reference_ground"), + Vec2::new(30.0, 30.0), + hos_ground.0, hos_ground.1, + primary(), "Relative to ground", + ).clicked { state.height_reference = HeightReference::Ground; } + if image_button( + uiw.read::().get("height_reference_start"), + Vec2::new(30.0, 30.0), + hos_start.0, hos_start.1, + primary(), "Relative to start", + ).clicked { state.height_reference = HeightReference::Start; } + if image_button( + uiw.read::().get("height_reference_incline"), + Vec2::new(30.0, 30.0), + hos_incline.0, hos_incline.1, + primary(), "Maximum incline", + ).clicked { state.height_reference = HeightReference::MaxIncline; } + if image_button( + uiw.read::().get("height_reference_decline"), + Vec2::new(30.0, 30.0), + hos_decline.0, hos_decline.1, + primary(), "Maximum decline", + ).clicked { state.height_reference = HeightReference::MaxDecline; } + }); }); - // Road elevation updown_value(&mut state.height_offset, 2.0, "m"); diff --git a/native_app/src/newgui/tools/roadbuild.rs b/native_app/src/newgui/tools/roadbuild.rs index 65477d7a..3c6738b0 100644 --- a/native_app/src/newgui/tools/roadbuild.rs +++ b/native_app/src/newgui/tools/roadbuild.rs @@ -44,28 +44,37 @@ pub fn roadbuild(sim: &Simulation, uiworld: &UiWorld) { return; } - let nosnapping = inp.act.contains(&InputAction::NoSnapping); - // Prepare mousepos depending on snap to grid - let unproj = unwrap_ret!(inp.unprojected); let grid_size = 20.0; + let unproj = unwrap_ret!(inp.unprojected); + let mut interpoliation_points: Vec = Vec::new(); + let nosnapping = inp.act.contains(&InputAction::NoSnapping); + + let mouse_height = match (state.height_reference, state.build_state) { + (HeightReference::Start, Start(id)|StartInterp(id)|Connection(id, _)) + => id.pos.z + state.height_offset, + (HeightReference::Ground|HeightReference::Start, _) => unproj.z + state.height_offset, + (HeightReference::MaxIncline|HeightReference::MaxDecline, _) => unproj.z, // work in progress + }; + + // Prepare mousepos depending on snap to grid or snap to angle let mousepos = match state.snapping { Snapping::None => { - unproj.up(state.height_offset) + unproj.z0().up(mouse_height) }, Snapping::SnapToGrid => { - let v = unproj.xy().snap(grid_size, grid_size); - v.z(unwrap_ret!(map.environment.height(v)) + state.height_offset) + unproj.xy().snap(grid_size, grid_size).z(mouse_height) }, Snapping::SnapToAngle => { - state.streight_points = state._update_points(map, unproj.up(state.height_offset)); - state.streight_points.iter() - .filter_map(|&point| { - let distance = point.distance(unproj); + interpoliation_points = state.update_points(map, unproj); + interpoliation_points.iter() + .map(|point| {point.xy()}) + .filter_map(|point| { + let distance = point.distance(unproj.xy()); if distance < grid_size {Some((point, distance))} else { None } }) .reduce(|acc, e| { if acc.1 < e.1 {acc} else { e } }) - .unwrap_or((unproj.up(state.height_offset), 0.0)).0 + .unwrap_or((unproj.xy(), 0.0)).0.z0().up(mouse_height) } }; @@ -278,7 +287,7 @@ pub fn roadbuild(sim: &Simulation, uiworld: &UiWorld) { } } - state.update_drawing(map, immdraw, cur_proj, patwidth, is_valid, points); + state.update_drawing(map, immdraw, cur_proj, patwidth, is_valid, points, interpoliation_points); if is_valid && inp.just_act.contains(&InputAction::Select) { log::info!("left clicked with state {:?} and {:?}", state.build_state, cur_proj.kind); @@ -335,8 +344,7 @@ pub struct RoadBuildResource { pub pattern_builder: LanePatternBuilder, pub snapping: Snapping, pub height_offset: f32, -// pub height_reference: HeightReference, - pub streight_points: Vec, + pub height_reference: HeightReference, } #[derive(Default, Clone, Copy)] @@ -345,12 +353,13 @@ pub enum Snapping { SnapToGrid, SnapToAngle } -// #[derive(Default, Clone, Copy)] -// pub enum HeightReference { -// #[default] Ground, -// Start, Absolute, -// MaxIncline, MaxDecline -// } +#[derive(Default, Clone, Copy)] +pub enum HeightReference { + #[default] Ground, + Start, + MaxIncline, + MaxDecline +} fn check_angle(map: &Map, from: MapProject, to: Vec2, is_rail: bool) -> bool { let max_turn_angle = if is_rail { @@ -441,6 +450,7 @@ impl RoadBuildResource { patwidth: f32, is_valid: bool, points: Option, + interpoliation_points: Vec, ) { let mut proj_pos = proj.pos; proj_pos.z += 0.4; @@ -450,7 +460,7 @@ impl RoadBuildResource { simulation::colors().gui_danger }; - self.streight_points.iter().for_each(|p|{ + interpoliation_points.iter().for_each(|p|{ immdraw.circle(*p, 2.0); }); @@ -503,7 +513,7 @@ impl RoadBuildResource { immdraw.polyline(p.into_vec(), patwidth, false).color(col); } - pub fn _update_points( + pub fn update_points( &self, map: &Map, mousepos: Vec3,