Skip to content

Commit

Permalink
More height offset options.
Browse files Browse the repository at this point in the history
reletive to ground and reletive to start
  • Loading branch information
Groneschild committed Jun 11, 2024
1 parent 5e1eb4e commit 9e9d65b
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 59 deletions.
97 changes: 60 additions & 37 deletions native_app/src/newgui/hud/toolbox/roadbuild.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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::<UiTextures>().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::<UiTextures>().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::<UiTextures>().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::<UiTextures>().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::<UiTextures>().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::<UiTextures>().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::<UiTextures>().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::<UiTextures>().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::<UiTextures>().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::<UiTextures>().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");

Expand Down
54 changes: 32 additions & 22 deletions native_app/src/newgui/tools/roadbuild.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vec3> = 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)
}
};

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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<Vec3>,
pub height_reference: HeightReference,
}

#[derive(Default, Clone, Copy)]
Expand All @@ -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 {
Expand Down Expand Up @@ -441,6 +450,7 @@ impl RoadBuildResource {
patwidth: f32,
is_valid: bool,
points: Option<PolyLine3>,
interpoliation_points: Vec<Vec3>,
) {
let mut proj_pos = proj.pos;
proj_pos.z += 0.4;
Expand All @@ -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);
});

Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 9e9d65b

Please sign in to comment.