Experimental cliffs, use column alt for world map

This commit is contained in:
Joshua Barretto 2021-02-14 02:17:21 +00:00
parent e521faef5d
commit 4b0c3ec644
5 changed files with 91 additions and 13 deletions

View File

@ -199,7 +199,8 @@ impl Block {
pub fn get_max_sunlight(&self) -> (u8, u8) {
match self.kind() {
BlockKind::Water => (1, 1),
BlockKind::Leaves => (10, 255),
BlockKind::Leaves => (9, 255),
BlockKind::Wood => (6, 2),
_ if self.is_opaque() => (0, 255),
_ => (0, 0),
}

View File

@ -188,7 +188,6 @@ impl Civs {
chunk.alt += diff;
chunk.basement += diff;
chunk.rockiness = 0.0;
chunk.warp_factor = 0.0;
chunk.surface_veg *= 1.0 - factor * rng.gen_range(0.25..0.9);
});
}

View File

@ -69,7 +69,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
let sim = &self.sim;
let _turb = Vec2::new(
let turb = Vec2::new(
sim.gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32,
sim.gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32,
) * 12.0;
@ -83,7 +83,6 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
let spawn_rate = sim.get_interpolated(wpos, |chunk| chunk.spawn_rate)?;
let alt = sim.get_interpolated_monotone(wpos, |chunk| chunk.alt)?;
let surface_veg = sim.get_interpolated_monotone(wpos, |chunk| chunk.surface_veg)?;
let chunk_warp_factor = sim.get_interpolated_monotone(wpos, |chunk| chunk.warp_factor)?;
let sim_chunk = sim.get(chunk_pos)?;
let neighbor_coef = TerrainChunkSize::RECT_SIZE.map(|e| e as f64);
let my_chunk_idx = vec2_as_uniform_idx(self.sim.map_size_lg(), chunk_pos);
@ -93,6 +92,12 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
let neighbor_chunk = sim.get(neighbor_pos)?;
Some((neighbor_pos, neighbor_chunk, &neighbor_chunk.river))
});
let cliff_height = sim.get_interpolated(wpos, |chunk| chunk.cliff_height)?;
let cliff_scale = 1.0;
let cliff_factor = (alt + self.sim.gen_ctx.hill_nz.get(wposf.div(48.0).into_array()) as f32 * 16.0).rem_euclid(128.0) / 64.0 - 1.0;
let cliff_offset = cliff_factor.abs().powf(if cliff_factor < 0.0 { 1.0 } else { 64.0 }) * cliff_height;
let cliff_scale = (self.sim.gen_ctx.hill_nz.get(wposf.div(128.0).into_array()) + self.sim.gen_ctx.hill_nz.get(wposf.div(48.0).into_array()) * 0.125 + 0.75).max(0.0) as f32;
let alt = alt + cliff_offset * cliff_scale;
let lake_width = (TerrainChunkSize::RECT_SIZE.x as f64 * (2.0f64.sqrt())) + 12.0;
let neighbor_river_data = neighbor_river_data.map(|(posj, chunkj, river)| {
@ -701,7 +706,6 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
1.0,
)
};
let warp_factor = warp_factor * chunk_warp_factor;
// NOTE: To disable warp, uncomment this line.
// let warp_factor = 0.0;
@ -1054,6 +1058,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
path,
cave,
snow_cover,
cliff_offset,
chunk: sim_chunk,
})
@ -1084,6 +1089,7 @@ pub struct ColumnSample<'a> {
pub path: Option<(f32, Vec2<f32>, Path, Vec2<f32>)>,
pub cave: Option<(f32, Vec2<f32>, Cave, Vec2<f32>)>,
pub snow_cover: bool,
pub cliff_offset: f32,
pub chunk: &'a SimChunk,
}

View File

@ -133,7 +133,7 @@ pub fn sample_pos(
let humidity = humidity.min(1.0).max(0.0);
let temperature = temperature.min(1.0).max(-1.0) * 0.5 + 0.5;
let wpos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
let column_rgb = samples
let column_rgb_alt = samples
.and_then(|samples| {
chunk_idx
.and_then(|chunk_idx| samples.get(chunk_idx))
@ -146,7 +146,7 @@ pub fn sample_pos(
let basement = sample.basement;
let grass_depth = (1.5 + 2.0 * sample.chaos).min(alt - basement);
let wposz = if is_basement { basement } else { alt };
if is_basement && wposz < alt - grass_depth {
let rgb = if is_basement && wposz < alt - grass_depth {
Lerp::lerp(
sample.sub_surface_color,
sample.stone_col.map(|e| e as f32 / 255.0),
@ -160,11 +160,13 @@ pub fn sample_pos(
((wposz as f32 - (alt - grass_depth)) / grass_depth).sqrt(),
)
.map(|e| e as f64)
}
};
(rgb, alt)
});
let downhill_wpos = downhill.unwrap_or(wpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32));
let alt = if is_basement { basement } else { alt };
let alt = if is_basement { basement } else { column_rgb_alt.map_or(alt, |(_, alt)| alt) };
let true_water_alt = (alt.max(water_alt) as f64 - focus.z) / gain as f64;
let true_alt = (alt as f64 - focus.z) / gain as f64;
@ -183,7 +185,7 @@ pub fn sample_pos(
if is_shaded { 1.0 } else { alt },
if is_shaded || is_humidity { 1.0 } else { 0.0 },
);
let column_rgb = column_rgb.unwrap_or(default_rgb);
let column_rgb = column_rgb_alt.map(|(rgb, _)| rgb).unwrap_or(default_rgb);
let mut connections = [None; 8];
let mut has_connections = false;
// TODO: Support non-river connections.

View File

@ -30,7 +30,7 @@ use crate::{
site::Site,
util::{
seed_expan, FastNoise, FastNoise2d, RandomField, RandomPerm, Sampler, StructureGen2d, LOCALITY,
NEIGHBORS,
NEIGHBORS, CARDINALS, DHashSet,
},
IndexRef, CONFIG,
};
@ -44,6 +44,7 @@ use common::{
},
vol::RectVolSize,
lottery::Lottery,
spiral::Spiral2d,
};
use common_net::msg::WorldMapMsg;
use enum_iterator::IntoEnumIterator;
@ -1401,6 +1402,8 @@ impl WorldSim {
rng,
};
this.generate_cliffs();
if opts.seed_elements {
this.seed_elements();
}
@ -1513,6 +1516,72 @@ impl WorldSim {
}
}
pub fn generate_cliffs(&mut self) {
let mut rng = self.rng.clone();
for _ in 0..self.get_size().product() / 10 {
let mut pos = self.get_size().map(|e| rng.gen_range(0..e) as i32);
let mut cliffs = DHashSet::default();
let mut cliff_path = Vec::new();
for _ in 0..64 {
if self.get_gradient_approx(pos).map_or(false, |g| g > 1.5) {
if !cliffs.insert(pos) {
break;
}
cliff_path.push((pos, 0.0));
pos += CARDINALS
.iter()
.copied()
.max_by_key(|rpos| self.get_gradient_approx(pos + rpos).map_or(0, |g| (g * 1000.0) as i32))
.unwrap(); // Can't fail
} else {
break;
}
}
// for locs in cliff_path.windows(3) {
// let to_prev_idx = NEIGHBORS
// .iter()
// .enumerate()
// .find(|(_, dir)| **dir == locs[0].0 - locs[1].0)
// .expect("Track locations must be neighbors")
// .0;
// let to_next_idx = NEIGHBORS
// .iter()
// .enumerate()
// .find(|(_, dir)| **dir == locs[2].0 - locs[1].0)
// .expect("Track locations must be neighbors")
// .0;
// self.get_mut(locs[0].0).unwrap().cliff.0.neighbors |=
// 1 << ((to_prev_idx as u8 + 4) % 8);
// self.get_mut(locs[1].0).unwrap().cliff.0.neighbors |=
// (1 << (to_prev_idx as u8)) | (1 << (to_next_idx as u8));
// self.get_mut(locs[2].0).unwrap().cliff.0.neighbors |=
// 1 << ((to_next_idx as u8 + 4) % 8);
// self.get_mut(locs[1].0).unwrap().cliff.0.offset = Vec2::new(rng.gen_range(-16..17), rng.gen_range(-16..17));
// }
for cliff in cliffs {
let alt = self.get(cliff).map_or(0.0, |c| c.alt);
Spiral2d::new()
.take((4usize * 2 + 1).pow(2))
.for_each(|rpos| {
let dist = rpos.map(|e| e as f32).magnitude();
if let Some(c) = self.get_mut(cliff + rpos) {
let warp = 1.0 / (1.0 + dist);
c.tree_density *= (1.0 - warp);
c.cliff_height = Lerp::lerp(44.0, 0.0, (-1.0 + dist / 3.5));
}
});
}
}
}
/// Prepare the world for simulation
pub fn seed_elements(&mut self) {
let mut rng = self.rng.clone();
@ -2056,7 +2125,6 @@ pub struct SimChunk {
pub forest_kind: ForestKind,
pub spawn_rate: f32,
pub river: RiverData,
pub warp_factor: f32,
pub surface_veg: f32,
pub sites: Vec<Id<Site>>,
@ -2064,6 +2132,7 @@ pub struct SimChunk {
pub path: (Way, Path),
pub cave: (Way, Cave),
pub cliff_height: f32,
pub contains_waypoint: bool,
}
@ -2284,13 +2353,14 @@ impl SimChunk {
},
spawn_rate: 1.0,
river,
warp_factor: 1.0,
surface_veg: 1.0,
sites: Vec::new(),
place: None,
path: Default::default(),
cave: Default::default(),
cliff_height: 0.0,
contains_waypoint: false,
}
}