mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improved path rendering on the map, removed ugly path noise
This commit is contained in:
parent
60bf396e4f
commit
8d4f1da3a6
@ -32,7 +32,7 @@ vec2 cloud_at(vec3 pos) {
|
||||
float density = max((value - CLOUD_THRESHOLD) - abs(pos.z - CLOUD_AVG_HEIGHT) / 200.0, 0.0) * CLOUD_DENSITY;
|
||||
|
||||
const float SHADE_GRADIENT = 1.5 / (CLOUD_AVG_HEIGHT - CLOUD_HEIGHT_MIN);
|
||||
float shade = ((pos.z - CLOUD_AVG_HEIGHT) / (CLOUD_HEIGHT_MAX - CLOUD_HEIGHT_MIN)) * 2.5 + 0.7;
|
||||
float shade = ((pos.z - CLOUD_AVG_HEIGHT) / (CLOUD_HEIGHT_MAX - CLOUD_HEIGHT_MIN)) * 10.5 + 0.7;
|
||||
|
||||
return vec2(shade, density / (1.0 + vsum(abs(pos - cam_pos.xyz)) / 5000));
|
||||
}
|
||||
|
@ -91,36 +91,6 @@ impl Civs {
|
||||
this.tick(&mut ctx, 1.0);
|
||||
}
|
||||
|
||||
// Temporary!
|
||||
for track in this.tracks.iter() {
|
||||
for locs in track.path.nodes().windows(3) {
|
||||
let to_prev_idx = NEIGHBORS
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, dir)| **dir == locs[0] - locs[1])
|
||||
.expect("Track locations must be neighbors")
|
||||
.0;
|
||||
let to_next_idx = NEIGHBORS
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, dir)| **dir == locs[2] - locs[1])
|
||||
.expect("Track locations must be neighbors")
|
||||
.0;
|
||||
|
||||
let mut chunk = ctx.sim.get_mut(locs[1]).unwrap();
|
||||
chunk.path.neighbors |= (1 << (to_prev_idx as u8)) | (1 << (to_next_idx as u8));
|
||||
chunk.path.offset = Vec2::new(
|
||||
ctx.rng.gen_range(-16.0, 16.0),
|
||||
ctx.rng.gen_range(-16.0, 16.0),
|
||||
);
|
||||
}
|
||||
|
||||
for loc in track.path.iter() {
|
||||
ctx.sim.get_mut(*loc).unwrap().place =
|
||||
Some(this.civs.iter().next().unwrap().homeland);
|
||||
}
|
||||
}
|
||||
|
||||
// Flatten ground around sites
|
||||
for site in this.sites.iter() {
|
||||
if let SiteKind::Settlement = &site.kind {
|
||||
@ -380,6 +350,30 @@ impl Civs {
|
||||
.filter(|(_, route_cost)| *route_cost < cost * 3.0)
|
||||
.is_none()
|
||||
{
|
||||
// Write the track to the world as a path
|
||||
for locs in path.nodes().windows(3) {
|
||||
let to_prev_idx = NEIGHBORS
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, dir)| **dir == locs[0] - locs[1])
|
||||
.expect("Track locations must be neighbors")
|
||||
.0;
|
||||
let to_next_idx = NEIGHBORS
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, dir)| **dir == locs[2] - locs[1])
|
||||
.expect("Track locations must be neighbors")
|
||||
.0;
|
||||
|
||||
let mut chunk = ctx.sim.get_mut(locs[1]).unwrap();
|
||||
chunk.path.neighbors |= (1 << (to_prev_idx as u8)) | (1 << (to_next_idx as u8));
|
||||
chunk.path.offset = Vec2::new(
|
||||
ctx.rng.gen_range(-16.0, 16.0),
|
||||
ctx.rng.gen_range(-16.0, 16.0),
|
||||
);
|
||||
}
|
||||
|
||||
// Take note of the track
|
||||
let track = self.tracks.insert(Track { cost, path });
|
||||
self.track_map
|
||||
.entry(site)
|
||||
@ -491,14 +485,21 @@ fn find_path(
|
||||
/// (TODO: by whom?)
|
||||
fn walk_in_dir(sim: &WorldSim, a: Vec2<i32>, dir: Vec2<i32>) -> Option<f32> {
|
||||
if loc_suitable_for_walking(sim, a) && loc_suitable_for_walking(sim, a + dir) {
|
||||
let a_alt = sim.get(a)?.alt;
|
||||
let b_alt = sim.get(a + dir)?.alt;
|
||||
let water_cost = if sim.get(a + dir)?.river.near_water() {
|
||||
25.0
|
||||
let a_chunk = sim.get(a)?;
|
||||
let b_chunk = sim.get(a + dir)?;
|
||||
|
||||
let hill_cost = ((b_chunk.alt - a_chunk.alt).abs() / 2.5).powf(2.0);
|
||||
let water_cost = if b_chunk.river.near_water() {
|
||||
50.0
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
Some(1.0 + ((b_alt - a_alt).abs() / 2.5).powf(2.0) + water_cost)
|
||||
let wild_cost = if b_chunk.path.is_path() {
|
||||
0.0 // Traversing existing paths has no additional cost!
|
||||
} else {
|
||||
2.0
|
||||
};
|
||||
Some(1.0 + hill_cost + water_cost + wild_cost)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -43,21 +43,33 @@ pub fn apply_paths_to<'a>(
|
||||
|
||||
// Try to use the column at the centre of the path for sampling to make them
|
||||
// flatter
|
||||
let col_pos = offs + path_nearest.map(|e| e.floor() as i32) - wpos2d;
|
||||
let col = get_column(col_pos)
|
||||
let col_pos = (offs - wpos2d).map(|e| e as f32) + path_nearest;
|
||||
let col00 = get_column(col_pos.map(|e| e.floor() as i32) + Vec2::new(0, 0));
|
||||
let col10 = get_column(col_pos.map(|e| e.floor() as i32) + Vec2::new(1, 0));
|
||||
let col01 = get_column(col_pos.map(|e| e.floor() as i32) + Vec2::new(0, 1));
|
||||
let col11 = get_column(col_pos.map(|e| e.floor() as i32) + Vec2::new(1, 1));
|
||||
let riverless_alt = match (col00, col10, col01, col11) {
|
||||
(Some(col00), Some(col10), Some(col01), Some(col11)) => Lerp::lerp(
|
||||
Lerp::lerp(col00.riverless_alt, col10.riverless_alt, path_nearest.x.fract()),
|
||||
Lerp::lerp(col01.riverless_alt, col11.riverless_alt, path_nearest.x.fract()),
|
||||
path_nearest.y.fract(),
|
||||
),
|
||||
_ => col_sample.riverless_alt,
|
||||
};
|
||||
let col = get_column(col_pos.map(|e| e.floor() as i32))
|
||||
.unwrap_or(col_sample);
|
||||
let (bridge_offset, depth) = if let Some(water_dist) = col.water_dist {
|
||||
(
|
||||
((water_dist.max(0.0) * 0.2).min(f32::consts::PI).cos() + 1.0) * 5.0,
|
||||
((1.0 - ((water_dist + 2.0) * 0.3).min(0.0).cos().abs())
|
||||
* (col.riverless_alt + 5.0 - col.alt).max(0.0)
|
||||
* (riverless_alt + 5.0 - col.alt).max(0.0)
|
||||
* 1.75
|
||||
+ 3.0) as i32,
|
||||
)
|
||||
} else {
|
||||
(0.0, 3)
|
||||
};
|
||||
let surface_z = (col.riverless_alt + bridge_offset).floor() as i32;
|
||||
let surface_z = (riverless_alt + bridge_offset).floor() as i32;
|
||||
|
||||
for z in inset - depth..inset {
|
||||
vol.set(
|
||||
|
@ -147,7 +147,7 @@ impl MapConfig {
|
||||
let pos =
|
||||
(focus_rect + Vec2::new(i as f64, j as f64) * scale).map(|e: f64| e as i32);
|
||||
|
||||
let (alt, basement, water_alt, humidity, temperature, downhill, river_kind, place) =
|
||||
let (alt, basement, water_alt, humidity, temperature, downhill, river_kind, is_path) =
|
||||
sampler
|
||||
.get(pos)
|
||||
.map(|sample| {
|
||||
@ -159,7 +159,7 @@ impl MapConfig {
|
||||
sample.temp,
|
||||
sample.downhill,
|
||||
sample.river.river_kind,
|
||||
sample.place,
|
||||
sample.path.is_path(),
|
||||
)
|
||||
})
|
||||
.unwrap_or((
|
||||
@ -170,7 +170,7 @@ impl MapConfig {
|
||||
0.0,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
));
|
||||
let humidity = humidity.min(1.0).max(0.0);
|
||||
let temperature = temperature.min(1.0).max(-1.0) * 0.5 + 0.5;
|
||||
@ -297,8 +297,8 @@ impl MapConfig {
|
||||
),
|
||||
};
|
||||
|
||||
let rgba = if let Some(place) = place {
|
||||
(((place.id() * 64) % 256) as u8, 0, 0, 0)
|
||||
let rgba = if is_path {
|
||||
(0x20, 0x19, 0x13, 255)
|
||||
} else {
|
||||
rgba
|
||||
};
|
||||
|
@ -1831,7 +1831,7 @@ impl WorldSim {
|
||||
end: (end_pos + ctrl_pos) / 2.0,
|
||||
};
|
||||
let nearest_interval = bez
|
||||
.binary_search_point_by_steps(wpos.map(|e| e as f32), 6, 0.01)
|
||||
.binary_search_point_by_steps(wpos.map(|e| e as f32), 16, 0.001)
|
||||
.0
|
||||
.clamped(0.0, 1.0);
|
||||
let pos = bez.evaluate(nearest_interval);
|
||||
|
@ -7,6 +7,12 @@ pub struct PathData {
|
||||
pub neighbors: u8, // One bit for each neighbor
|
||||
}
|
||||
|
||||
impl PathData {
|
||||
pub fn is_path(&self) -> bool {
|
||||
self.neighbors != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PathData {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
Loading…
Reference in New Issue
Block a user