Skip to content

Commit

Permalink
split using arbitrary points instead of splines
Browse files Browse the repository at this point in the history
  • Loading branch information
Uriopass committed Jul 13, 2024
1 parent edd1c0e commit 986c156
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 83 deletions.
23 changes: 13 additions & 10 deletions geom/src/polyline3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,16 +376,19 @@ impl PolyLine3 {
}
}

pub fn split(mut self, dst: f32) -> (Self, Self) {
let start = self.cut_start(dst);
let n = start.n_points();
*self.points.get_mut(n - 1).unwrap() = start.last();
self.points.drain(..n - 1);
self.l -= start.length();
(start, self)
}

// dst is distance from start to cut
/// Split the polyline3 into two at the given distance from the start
/// The polylined returned look like this
/// ([start ... cut], [cut ... end])
pub fn split(mut self, dst_from_start: f32) -> (Self, Self) {
let end = self.cut_start(dst_from_start);
self.points.truncate(self.points.len() - end.n_points() + 1);
self.points.push(end.first());
self.l -= end.length();
(self, end)
}

/// dst is distance from start to cut
/// Returns the end of the points after cutting part of the start
pub fn cut_start(&self, mut dst: f32) -> Self {
if dst == 0.0 {
return self.clone();
Expand Down
24 changes: 2 additions & 22 deletions native_app/src/debug_gui/debug_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use engine::{PerfCountersStatic, Tesselator};
use geom::{Camera, Color, LinearColor, Spline3, Vec2};
use prototypes::{GameDuration, GameTime, SECONDS_PER_DAY};
use simulation::map::{
IntersectionID, Map, MapSubscriber, NetworkObjectID, RoadSegmentKind, TraverseKind, UpdateType,
IntersectionID, Map, MapSubscriber, NetworkObjectID, TraverseKind, UpdateType,
};
use simulation::transportation::train::TrainReservations;
use simulation::world_command::WorldCommand;
Expand Down Expand Up @@ -44,7 +44,6 @@ impl Default for DebugObjs {
(false, "Debug electricity", debug_electricity),
(false, "Debug spatialmap", debug_spatialmap),
(false, "Debug transport grid", debug_transport_grid),
(false, "Debug splines", debug_spline),
(false, "Debug lots", debug_lots),
(false, "Debug road points", debug_road_points),
(false, "Debug parking", debug_parking),
Expand Down Expand Up @@ -275,26 +274,6 @@ fn debug(window: egui::Window<'_>, ui: &egui::Context, uiworld: &UiWorld, sim: &
});
}

pub fn debug_spline(tess: &mut Tesselator, sim: &Simulation, _: &UiWorld) -> Option<()> {
for road in sim.map().roads().values() {
if let RoadSegmentKind::Curved((fr_dr, to_der)) = road.segment {
let fr = road.points.first();
let to = road.points.last();
draw_spline(
tess,
Spline3 {
from: fr,
to,
from_derivative: fr_dr.z0(),
to_derivative: to_der.z0(),
},
);
}
}

Some(())
}

pub fn debug_lots(tess: &mut Tesselator, sim: &Simulation, _: &UiWorld) -> Option<()> {
tess.set_color(Color::RED);
for lot in sim.map().lots().values() {
Expand Down Expand Up @@ -410,6 +389,7 @@ pub fn debug_connectivity(tess: &mut Tesselator, sim: &Simulation, uiw: &UiWorld
Some(())
}

#[allow(unused)]
fn draw_spline(tess: &mut Tesselator, mut sp: Spline3) {
sp.from = sp.from.up(0.3);
sp.to = sp.to.up(0.3);
Expand Down
5 changes: 4 additions & 1 deletion simulation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![allow(clippy::type_complexity)]

use crate::init::{GSYSTEMS, INIT_FUNCS, SAVELOAD_FUNCS};
use crate::map::{BuildingKind, Map};
use crate::map::{BuildingKind, Heightmap, Map};
use crate::map_dynamic::{Itinerary, ItineraryLeader};
use crate::souls::add_souls_to_empty_buildings;
use crate::utils::resources::{Ref, RefMut, Resources};
Expand Down Expand Up @@ -288,6 +288,9 @@ impl Simulation {

pub fn load_from_disk(save_name: &str) -> Option<Self> {
let sim: Simulation = common::saveload::CompressedBincode::load(save_name).ok()?;
if sim.resources.try_read::<Map>().ok()?.environment.size().0 == 0 {
return None;
}
Some(sim)
}

Expand Down
57 changes: 11 additions & 46 deletions simulation/src/map/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use crate::map::{
Building, BuildingID, BuildingKind, Environment, Intersection, IntersectionID, Lane, LaneID,
LaneKind, LanePattern, Lot, LotID, LotKind, MapSubscriber, MapSubscribers, ParkingSpotID,
ParkingSpots, ProjectFilter, ProjectKind, Road, RoadID, RoadSegmentKind, SpatialMap,
SubscriberChunkID, TerraformKind, UpdateType, Zone,
SubscriberChunkID, TerraformKind, UpdateType, Zone, ROAD_Z_OFFSET,
};
use geom::OBB;
use geom::{Spline3, Vec2, Vec3};
use geom::{Vec2, Vec3};
use ordered_float::OrderedFloat;
use prototypes::{BuildingGen, Tick};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -488,48 +488,13 @@ impl Map {
self.parking.remove_to_reuse(id);
}

let id = self.add_intersection(pos);

let src_id = r.src;

let (r1, r2) = match r.segment {
RoadSegmentKind::Straight => (
self.connect(src_id, id, &pat, RoadSegmentKind::Straight)?,
self.connect(id, r.dst, &pat, RoadSegmentKind::Straight)?,
),
RoadSegmentKind::Curved((from_derivative, to_derivative)) => {
let s = Spline3 {
from: r.points.first(),
to: r.points.last(),
from_derivative: from_derivative.z0(),
to_derivative: to_derivative.z0(),
};
let t_approx = s.project_t(pos, 1.0);

let (s_from, s_to) = s.split_at(t_approx);

(
self.connect(
src_id,
id,
&pat,
RoadSegmentKind::Curved((
s_from.from_derivative.xy(),
s_from.to_derivative.xy(),
)),
)?,
self.connect(
id,
r.dst,
&pat,
RoadSegmentKind::Curved((
s_to.from_derivative.xy(),
s_to.to_derivative.xy(),
)),
)?,
)
}
};
let id = self.add_intersection(pos - Vec3::z(ROAD_Z_OFFSET));

let dist_along = r.points.length_at_proj(pos);
let (before, after) = r.points.split(dist_along);

let r1 = self.connect(r.src, id, &pat, RoadSegmentKind::Arbitrary(before))?;
let r2 = self.connect(id, r.dst, &pat, RoadSegmentKind::Arbitrary(after))?;

log::info!(
"{} parking spots reused when splitting",
Expand Down Expand Up @@ -874,7 +839,7 @@ impl Map {
.first()
.up(-crate::map::ROAD_Z_OFFSET)
.is_close(src.pos, 0.001),
"{:?} {:?} {:?} {:?}",
"First road point should be close to src intersection's position {:?} {:?} {:?} {:?}",
road.points.first().up(-crate::map::ROAD_Z_OFFSET),
src.pos,
road.id,
Expand All @@ -885,7 +850,7 @@ impl Map {
.last()
.up(-crate::map::ROAD_Z_OFFSET)
.is_close(dst.pos, 0.001),
"{:?} {:?} {:?} {:?}",
"Last road point should be close to dst intersection's position {:?} {:?} {:?} {:?}",
road.points.last().up(-crate::map::ROAD_Z_OFFSET),
dst.pos,
road.id,
Expand Down
12 changes: 8 additions & 4 deletions simulation/src/map/objects/road.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ new_key_type! {
pub struct RoadID;
}

#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum RoadSegmentKind {
Straight,
Curved((Vec2, Vec2)), // The two derivatives for the spline
Arbitrary(PolyLine3),
}

impl RoadSegmentKind {
Expand All @@ -35,8 +36,6 @@ pub struct Road {
pub src: IntersectionID,
pub dst: IntersectionID,

pub segment: RoadSegmentKind,

/// always from src to dst
/// don't try to make points go away from the road as it would be impossible to split them correctly afterward
pub points: PolyLine3,
Expand Down Expand Up @@ -97,7 +96,6 @@ impl Road {
dst: dst.id,
src_interface: 9.0,
dst_interface: 9.0,
segment,
width,
lanes_forward: vec![],
lanes_backward: vec![],
Expand Down Expand Up @@ -477,6 +475,12 @@ impl Road {
from_derivative,
to_derivative,
},
RoadSegmentKind::Arbitrary(pos) => {
if pos.len() < 2 {
unreachable!("Arbitrary road segment with less than 2 points")
}
return (pos, None);
}
};

let iter = spline.smart_points(if precise { 0.1 } else { 1.0 }, 0.0, 1.0);
Expand Down

0 comments on commit 986c156

Please sign in to comment.