From 01b2a98d431ea34d415f10b2ac7d166bea57c188 Mon Sep 17 00:00:00 2001 From: DimpyRed Date: Thu, 15 Oct 2020 12:17:28 -0700 Subject: [PATCH 1/4] first iteration --- common/src/worldgen.rs | 74 +++++++++++++++++-- first_iteration.patch | 161 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 first_iteration.patch diff --git a/common/src/worldgen.rs b/common/src/worldgen.rs index ad3249bf..ae7079b0 100644 --- a/common/src/worldgen.rs +++ b/common/src/worldgen.rs @@ -60,13 +60,23 @@ impl NodeStateRoad { } } +pub struct CliffState { + is_cliff: bool, + generates_cliff: bool, + generates_cliff_side: Side, +} + pub struct NodeState { kind: NodeStateKind, surface: Plane, road_state: NodeStateRoad, spice: u64, + cliff_data: CliffState, enviro: EnviroFactors, } + +const A_ADJACENT: [Side; 5] = [Side::B, Side::C, Side::D, Side::E, Side::I]; + impl NodeState { pub fn root() -> Self { Self { @@ -74,6 +84,11 @@ impl NodeState { surface: Plane::from(Side::A), road_state: NodeStateRoad::ROOT, spice: 0, + cliff_data: CliffState { + is_cliff: false, + generates_cliff: false, + generates_cliff_side: Side::A, // dummy + }, enviro: EnviroFactors { max_elevation: 0.0, temperature: 0.0, @@ -96,19 +111,57 @@ impl NodeState { let mut d = graph .descenders(node) .map(|(s, n)| (s, &graph.get(n).as_ref().unwrap().state)); - let enviro = match (d.next(), d.next()) { + + let mut rng = rand_pcg::Pcg64Mcg::seed_from_u64(spice + 1); // cheeky hash + let generates_cliff_side = A_ADJACENT[rng.gen_range(0, 4)]; // hard-coded to include all elements in A_ADJACENT + + let enviro; + let cliff_data; + match (d.next(), d.next()) { (Some(_), None) => { let parent_side = graph.parent(node).unwrap(); let parent_node = graph.neighbor(node, parent_side).unwrap(); let parent_state = &graph.get(parent_node).as_ref().unwrap().state; - EnviroFactors::varied_from(parent_state.enviro, spice) + enviro = EnviroFactors::varied_from(parent_state.enviro, spice); + let is_cliff = { + if parent_state.cliff_data.generates_cliff + && (parent_state.cliff_data.generates_cliff_side == side) + && (parent_state.kind == Land) + { + !parent_state.cliff_data.is_cliff + } else { + parent_state.cliff_data.is_cliff + } + }; + + let generates_cliff = match is_cliff { + true => rng.gen_ratio(4, 5), + false => rng.gen_ratio(1, 3), + }; + + cliff_data = CliffState { + is_cliff, + generates_cliff, + generates_cliff_side, + }; } (Some((a_side, a_state)), Some((b_side, b_state))) => { let ab_node = graph .neighbor(graph.neighbor(node, a_side).unwrap(), b_side) .unwrap(); let ab_state = &graph.get(ab_node).as_ref().unwrap().state; - EnviroFactors::continue_from(a_state.enviro, b_state.enviro, ab_state.enviro) + enviro = + EnviroFactors::continue_from(a_state.enviro, b_state.enviro, ab_state.enviro); + + let is_cliff = a_state.cliff_data.is_cliff + ^ b_state.cliff_data.is_cliff + ^ ab_state.cliff_data.is_cliff; + let generates_cliff = rng.gen_ratio(1, 3); + cliff_data = CliffState { + is_cliff, + generates_cliff, + generates_cliff_side, + }; } _ => unreachable!(), }; @@ -124,6 +177,7 @@ impl NodeState { _ => side * self.surface, }, road_state: child_road, + cliff_data, spice, enviro, } @@ -179,6 +233,7 @@ pub struct ChunkParams { is_road: bool, /// Whether this chunk contains a section of the road's supports is_road_support: bool, + is_cliff: bool, /// Random quantity used to seed terrain gen node_spice: u64, } @@ -198,6 +253,7 @@ impl ChunkParams { && ((state.road_state == East) || (state.road_state == West)), is_road_support: ((state.kind == Land) || (state.kind == DeepLand)) && ((state.road_state == East) || (state.road_state == West)), + is_cliff: state.cliff_data.is_cliff, node_spice: state.spice, }) } @@ -259,7 +315,6 @@ impl ChunkParams { /// only the containing chunk's surrounding nodes' envirofactors. fn generate_terrain(&self, voxels: &mut VoxelData, rng: &mut Pcg64Mcg) { let normal = Normal::new(0.0, 0.03); - for (x, y, z) in VoxelCoords::new(self.dimension) { let coords = na::Vector3::new(x, y, z); let center = voxel_center(self.dimension, coords); @@ -279,7 +334,14 @@ impl ChunkParams { // Small and big terracing effects must not sum to more than 1, // otherwise the terracing fails to be (nonstrictly) monotonic // and the terrain gets trenches ringing around its cliffs. - let elev_pre_noise = elev_pre_terracing + 0.6 * terracing_small + 0.4 * terracing_big; + let elev_pre_noise = + elev_pre_terracing + 0.6 * terracing_small + 0.4 * terracing_big + { + if self.is_cliff { + 14.0 + } else { + 0.0 + } + }; // initial value dist_pre_noise is the difference between the voxel's distance // from the guiding plane and the voxel's calculated elev value. It represents @@ -305,6 +367,7 @@ impl ChunkParams { if dist >= 0.0 { let voxel_mat = VoronoiInfo::terraingen_voronoi(elev, rain, temp, dist); voxels.data_mut(self.dimension)[index(self.dimension, coords)] = voxel_mat; + } } } @@ -424,7 +487,6 @@ impl ChunkParams { } } } - /// Provides information on the type of material in a voxel's six neighbours fn voxel_neighbors(&self, coords: na::Vector3, voxels: &VoxelData) -> [NeighborData; 6] { [ diff --git a/first_iteration.patch b/first_iteration.patch new file mode 100644 index 00000000..ad5ddbd2 --- /dev/null +++ b/first_iteration.patch @@ -0,0 +1,161 @@ +Index: common/src/worldgen.rs +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- common/src/worldgen.rs (date 1594800959000) ++++ common/src/worldgen.rs (date 1597106094000) +@@ -60,13 +60,23 @@ + } + } + ++pub struct CliffState { ++ is_cliff: bool, ++ generates_cliff: bool, ++ generates_cliff_side: Side, ++} ++ + pub struct NodeState { + kind: NodeStateKind, + surface: Plane, + road_state: NodeStateRoad, + spice: u64, ++ cliff_data: CliffState, + enviro: EnviroFactors, + } ++ ++const A_ADJACENT: [Side; 5] = [Side::B, Side::C, Side::D, Side::E, Side::I]; ++ + impl NodeState { + pub fn root() -> Self { + Self { +@@ -74,6 +84,11 @@ + surface: Plane::from(Side::A), + road_state: NodeStateRoad::ROOT, + spice: 0, ++ cliff_data: CliffState { ++ is_cliff: false, ++ generates_cliff: false, ++ generates_cliff_side: Side::A, // dummy ++ }, + enviro: EnviroFactors { + max_elevation: 0.0, + temperature: 0.0, +@@ -96,19 +111,57 @@ + let mut d = graph + .descenders(node) + .map(|(s, n)| (s, &graph.get(n).as_ref().unwrap().state)); +- let enviro = match (d.next(), d.next()) { ++ ++ let mut rng = rand_pcg::Pcg64Mcg::seed_from_u64(spice + 1); // cheeky hash ++ let generates_cliff_side = A_ADJACENT[rng.gen_range(0, 4)]; // hard-coded to include all elements in A_ADJACENT ++ ++ let enviro; ++ let cliff_data; ++ match (d.next(), d.next()) { + (Some(_), None) => { + let parent_side = graph.parent(node).unwrap(); + let parent_node = graph.neighbor(node, parent_side).unwrap(); + let parent_state = &graph.get(parent_node).as_ref().unwrap().state; +- EnviroFactors::varied_from(parent_state.enviro, spice) ++ enviro = EnviroFactors::varied_from(parent_state.enviro, spice); ++ let is_cliff = { ++ if parent_state.cliff_data.generates_cliff ++ && (parent_state.cliff_data.generates_cliff_side == side) ++ && (parent_state.kind == Land) ++ { ++ !parent_state.cliff_data.is_cliff ++ } else { ++ parent_state.cliff_data.is_cliff ++ } ++ }; ++ ++ let generates_cliff = match is_cliff { ++ true => rng.gen_ratio(4, 5), ++ false => rng.gen_ratio(1, 3), ++ }; ++ ++ cliff_data = CliffState { ++ is_cliff, ++ generates_cliff, ++ generates_cliff_side, ++ }; + } + (Some((a_side, a_state)), Some((b_side, b_state))) => { + let ab_node = graph + .neighbor(graph.neighbor(node, a_side).unwrap(), b_side) + .unwrap(); + let ab_state = &graph.get(ab_node).as_ref().unwrap().state; +- EnviroFactors::continue_from(a_state.enviro, b_state.enviro, ab_state.enviro) ++ enviro = ++ EnviroFactors::continue_from(a_state.enviro, b_state.enviro, ab_state.enviro); ++ ++ let is_cliff = a_state.cliff_data.is_cliff ++ ^ b_state.cliff_data.is_cliff ++ ^ ab_state.cliff_data.is_cliff; ++ let generates_cliff = rng.gen_ratio(1, 3); ++ cliff_data = CliffState { ++ is_cliff, ++ generates_cliff, ++ generates_cliff_side, ++ }; + } + _ => unreachable!(), + }; +@@ -124,6 +177,7 @@ + _ => side * self.surface, + }, + road_state: child_road, ++ cliff_data, + spice, + enviro, + } +@@ -143,6 +197,7 @@ + is_road: bool, + /// Whether this chunk contains a section of the road's supports + is_road_support: bool, ++ is_cliff: bool, + node_spice: u64, + } + +@@ -161,6 +216,7 @@ + && ((state.road_state == East) || (state.road_state == West)), + is_road_support: ((state.kind == Land) || (state.kind == DeepLand)) + && ((state.road_state == East) || (state.road_state == West)), ++ is_cliff: state.cliff_data.is_cliff, + node_spice: state.spice, + }) + } +@@ -200,7 +256,13 @@ + // otherwise the terracing fails to be (nonstrictly) monotonic + // and the terrain gets trenches ringing around its cliffs. + let elev_pre_noise = +- elev_pre_terracing + 0.6 * terracing_small + 0.4 * terracing_big; ++ elev_pre_terracing + 0.6 * terracing_small + 0.4 * terracing_big + { ++ if self.is_cliff { ++ 14.0 ++ } else { ++ 0.0 ++ } ++ }; + + // initial value dist_pre_noise is the difference between the voxel's distance + // from the guiding plane and the voxel's calculated elev value. It represents +@@ -405,7 +467,7 @@ + // Maximum difference between elevations at the center of a chunk and any other point in the chunk + // TODO: Compute what this actually is, current value is a guess! Real one must be > 0.6 + // empirically. +- const ELEVATION_MARGIN: f64 = 0.7; ++ /*const ELEVATION_MARGIN: f64 = 0.7; + let center_elevation = self + .surface + .distance_to_chunk(self.chunk, &na::Vector3::repeat(0.5)); +@@ -420,7 +482,7 @@ + // The whole chunk is underground + // TODO: More accurate VoxelData + return VoxelData::Solid(Material::Dirt); +- } ++ }*/ + + let mut voxels = VoxelData::Solid(Material::Void); + let mut rng = rand_pcg::Pcg64Mcg::seed_from_u64(hash(self.node_spice, self.chunk as u64)); From 2be2a798ebc9cb4bc00dcefcc67c8720fcba81af Mon Sep 17 00:00:00 2001 From: DimpyRed Date: Wed, 12 Aug 2020 11:53:57 -0700 Subject: [PATCH 2/4] made occulsion semi-compatible with cliffs --- common/src/worldgen.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/common/src/worldgen.rs b/common/src/worldgen.rs index ae7079b0..c21fb660 100644 --- a/common/src/worldgen.rs +++ b/common/src/worldgen.rs @@ -184,6 +184,7 @@ impl NodeState { } } + struct VoxelCoords { counter: u32, dimension: u8, @@ -219,6 +220,16 @@ impl Iterator for VoxelCoords { } } + +/// Returns the amount of elevation to add based on there being a cliff +fn cliff_boost(is_cliff: bool) -> f64 { + if is_cliff { + 14.0 + } else { + 0.0 + } +} + /// Data needed to generate a chunk pub struct ChunkParams { /// Number of voxels along an edge @@ -278,14 +289,18 @@ impl ChunkParams { let center_elevation = self .surface .distance_to_chunk(self.chunk, &na::Vector3::repeat(0.5)); - if (center_elevation - ELEVATION_MARGIN > me_max / TERRAIN_SMOOTHNESS) + if (center_elevation - ELEVATION_MARGIN + > (me_max + cliff_boost(self.is_cliff)) / TERRAIN_SMOOTHNESS) && !(self.is_road || self.is_road_support) { // The whole chunk is above ground and not part of the road return VoxelData::Solid(Material::Void); } - if (center_elevation + ELEVATION_MARGIN < me_min / TERRAIN_SMOOTHNESS) && !self.is_road { + if (center_elevation + ELEVATION_MARGIN + < (me_min + cliff_boost(self.is_cliff)) / TERRAIN_SMOOTHNESS) + && !self.is_road + { // The whole chunk is underground // TODO: More accurate VoxelData return VoxelData::Solid(Material::Dirt); From 5c4e5de483ae91557d979895ad8aad1c9ee77788 Mon Sep 17 00:00:00 2001 From: DimpyRed Date: Thu, 15 Oct 2020 12:20:55 -0700 Subject: [PATCH 3/4] second iteration --- common/src/worldgen.rs | 193 +++++++++++++++++++++++++++++++---------- first_iteration.patch | 161 ---------------------------------- 2 files changed, 146 insertions(+), 208 deletions(-) delete mode 100644 first_iteration.patch diff --git a/common/src/worldgen.rs b/common/src/worldgen.rs index c21fb660..efa3b3b2 100644 --- a/common/src/worldgen.rs +++ b/common/src/worldgen.rs @@ -61,9 +61,8 @@ impl NodeStateRoad { } pub struct CliffState { - is_cliff: bool, - generates_cliff: bool, - generates_cliff_side: Side, + is_plateau: bool, + adjacent_cliffs: [Option; 2], } pub struct NodeState { @@ -85,9 +84,8 @@ impl NodeState { road_state: NodeStateRoad::ROOT, spice: 0, cliff_data: CliffState { - is_cliff: false, - generates_cliff: false, - generates_cliff_side: Side::A, // dummy + is_plateau: false, + adjacent_cliffs: [None; 2], }, enviro: EnviroFactors { max_elevation: 0.0, @@ -113,37 +111,38 @@ impl NodeState { .map(|(s, n)| (s, &graph.get(n).as_ref().unwrap().state)); let mut rng = rand_pcg::Pcg64Mcg::seed_from_u64(spice + 1); // cheeky hash - let generates_cliff_side = A_ADJACENT[rng.gen_range(0, 4)]; // hard-coded to include all elements in A_ADJACENT + //let generates_cliff_side = A_ADJACENT[rng.gen_range(0, 4)]; // hard-coded to include all elements in A_ADJACENT let enviro; - let cliff_data; + let is_plateau: bool; + let mut inherited_cliff_sides; + let mut candidate_new_sides: Vec = Vec::new(); + match (d.next(), d.next()) { (Some(_), None) => { let parent_side = graph.parent(node).unwrap(); let parent_node = graph.neighbor(node, parent_side).unwrap(); let parent_state = &graph.get(parent_node).as_ref().unwrap().state; enviro = EnviroFactors::varied_from(parent_state.enviro, spice); - let is_cliff = { - if parent_state.cliff_data.generates_cliff - && (parent_state.cliff_data.generates_cliff_side == side) - && (parent_state.kind == Land) - { - !parent_state.cliff_data.is_cliff - } else { - parent_state.cliff_data.is_cliff + + is_plateau = { + let mut inversion = false; + for x in &parent_state.cliff_data.adjacent_cliffs { + if x.is_some() && parent_side == x.unwrap() { + inversion = true; + } } + parent_state.cliff_data.is_plateau ^ inversion }; - let generates_cliff = match is_cliff { - true => rng.gen_ratio(4, 5), - false => rng.gen_ratio(1, 3), - }; + // only adjacent sides will inherit the cliff + inherited_cliff_sides = NodeState::get_cliff_inheritance(parent_state, parent_side); - cliff_data = CliffState { - is_cliff, - generates_cliff, - generates_cliff_side, - }; + for s in &A_ADJACENT { + if Self::valid_side(*s, inherited_cliff_sides, parent_side) { + candidate_new_sides.push(*s); + } + } } (Some((a_side, a_state)), Some((b_side, b_state))) => { let ab_node = graph @@ -153,19 +152,52 @@ impl NodeState { enviro = EnviroFactors::continue_from(a_state.enviro, b_state.enviro, ab_state.enviro); - let is_cliff = a_state.cliff_data.is_cliff - ^ b_state.cliff_data.is_cliff - ^ ab_state.cliff_data.is_cliff; - let generates_cliff = rng.gen_ratio(1, 3); - cliff_data = CliffState { - is_cliff, - generates_cliff, - generates_cliff_side, - }; + is_plateau = a_state.cliff_data.is_plateau + ^ b_state.cliff_data.is_plateau + ^ ab_state.cliff_data.is_plateau; + + let inherited_cliffs_a = NodeState::get_cliff_inheritance(a_state, a_side); + let inherited_cliffs_b = NodeState::get_cliff_inheritance(b_state, b_side); + + inherited_cliff_sides = + NodeState::cliff_union(inherited_cliffs_a, inherited_cliffs_b); + + for s in &A_ADJACENT { + if Self::valid_side2(*s, inherited_cliff_sides, a_side, b_side) { + candidate_new_sides.push(*s); + } + } } _ => unreachable!(), }; + let adjacent_cliffs = match candidate_new_sides.len() { + 0 => inherited_cliff_sides, + _ => { + if rng.gen_ratio( + 1, + match is_plateau { + true => 25, //In the actual game this would be the smaller value + false => 6, + }, + ) { + let index_to_add = rng.gen_range(0, candidate_new_sides.len()); + for y in inherited_cliff_sides.iter_mut() { + if y.is_none() { + *y = Some(candidate_new_sides[index_to_add]); + break; + } + } + } + inherited_cliff_sides + } + }; + + let cliff_data = CliffState { + is_plateau, + adjacent_cliffs, + }; + let child_kind = self.kind.clone().child(side); let child_road = self.road_state.clone().child(side); @@ -182,6 +214,74 @@ impl NodeState { enviro, } } + + fn get_cliff_inheritance(state: &NodeState, side: Side) -> [Option; 2] { + let mut return_value = state.cliff_data.adjacent_cliffs; + for x in return_value.iter_mut() { + if !x.is_none() { + let s = x.unwrap(); + if (s != side) && (!s.adjacent_to(side)) { + *x = None; + } + } + } + return_value + } + + fn cliff_union(a: [Option; 2], b: [Option; 2]) -> [Option; 2] { + let mut return_value = a; + for x in b.iter() { + if !x.is_none() { + let mut cont = true; + //check for duplicates first + for y in return_value.iter_mut() { + if y == x { + cont = false; + break; + } + } + //then check for empty spots + if cont { + for y in return_value.iter_mut() { + if y.is_none() { + *y = Some(x.clone().unwrap()); + break; + } + } + } + } + } + return_value + } + + fn valid_side(test_value: Side, inherited_sides: [Option; 2], parent1: Side) -> bool { + for x in &inherited_sides { + if x.is_some() { + let v = x.unwrap(); + if (v == test_value) || v.adjacent_to(test_value) { + return false; + } + } + } + if (parent1 == test_value) || parent1.adjacent_to(test_value) { + return false; + } + + true + } + + fn valid_side2( + test_value: Side, + inherited_sides: [Option; 2], + parent1: Side, + parent2: Side, + ) -> bool { + if !Self::valid_side(test_value, inherited_sides, parent1) { + return false; + } + + !((parent2 == test_value) || parent2.adjacent_to(test_value)) + } } @@ -224,7 +324,7 @@ impl Iterator for VoxelCoords { /// Returns the amount of elevation to add based on there being a cliff fn cliff_boost(is_cliff: bool) -> f64 { if is_cliff { - 14.0 + 20.0 } else { 0.0 } @@ -244,7 +344,8 @@ pub struct ChunkParams { is_road: bool, /// Whether this chunk contains a section of the road's supports is_road_support: bool, - is_cliff: bool, + is_plateau: bool, + is_cliff_adjacent: bool, /// Random quantity used to seed terrain gen node_spice: u64, } @@ -264,7 +365,8 @@ impl ChunkParams { && ((state.road_state == East) || (state.road_state == West)), is_road_support: ((state.kind == Land) || (state.kind == DeepLand)) && ((state.road_state == East) || (state.road_state == West)), - is_cliff: state.cliff_data.is_cliff, + is_plateau: state.cliff_data.is_plateau, + is_cliff_adjacent: state.cliff_data.adjacent_cliffs != [None, None], node_spice: state.spice, }) } @@ -290,7 +392,7 @@ impl ChunkParams { .surface .distance_to_chunk(self.chunk, &na::Vector3::repeat(0.5)); if (center_elevation - ELEVATION_MARGIN - > (me_max + cliff_boost(self.is_cliff)) / TERRAIN_SMOOTHNESS) + > (me_max + cliff_boost(self.is_plateau)) / TERRAIN_SMOOTHNESS) && !(self.is_road || self.is_road_support) { // The whole chunk is above ground and not part of the road @@ -298,7 +400,8 @@ impl ChunkParams { } if (center_elevation + ELEVATION_MARGIN - < (me_min + cliff_boost(self.is_cliff)) / TERRAIN_SMOOTHNESS) + < (me_min + cliff_boost(self.is_plateau) * (!self.is_cliff_adjacent as i32 as f64)) + / TERRAIN_SMOOTHNESS) && !self.is_road { // The whole chunk is underground @@ -349,14 +452,10 @@ impl ChunkParams { // Small and big terracing effects must not sum to more than 1, // otherwise the terracing fails to be (nonstrictly) monotonic // and the terrain gets trenches ringing around its cliffs. - let elev_pre_noise = - elev_pre_terracing + 0.6 * terracing_small + 0.4 * terracing_big + { - if self.is_cliff { - 14.0 - } else { - 0.0 - } - }; + let elev_pre_noise = elev_pre_terracing + + 0.6 * terracing_small + + 0.4 * terracing_big + + cliff_boost(self.is_plateau); // initial value dist_pre_noise is the difference between the voxel's distance // from the guiding plane and the voxel's calculated elev value. It represents diff --git a/first_iteration.patch b/first_iteration.patch deleted file mode 100644 index ad5ddbd2..00000000 --- a/first_iteration.patch +++ /dev/null @@ -1,161 +0,0 @@ -Index: common/src/worldgen.rs -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- common/src/worldgen.rs (date 1594800959000) -+++ common/src/worldgen.rs (date 1597106094000) -@@ -60,13 +60,23 @@ - } - } - -+pub struct CliffState { -+ is_cliff: bool, -+ generates_cliff: bool, -+ generates_cliff_side: Side, -+} -+ - pub struct NodeState { - kind: NodeStateKind, - surface: Plane, - road_state: NodeStateRoad, - spice: u64, -+ cliff_data: CliffState, - enviro: EnviroFactors, - } -+ -+const A_ADJACENT: [Side; 5] = [Side::B, Side::C, Side::D, Side::E, Side::I]; -+ - impl NodeState { - pub fn root() -> Self { - Self { -@@ -74,6 +84,11 @@ - surface: Plane::from(Side::A), - road_state: NodeStateRoad::ROOT, - spice: 0, -+ cliff_data: CliffState { -+ is_cliff: false, -+ generates_cliff: false, -+ generates_cliff_side: Side::A, // dummy -+ }, - enviro: EnviroFactors { - max_elevation: 0.0, - temperature: 0.0, -@@ -96,19 +111,57 @@ - let mut d = graph - .descenders(node) - .map(|(s, n)| (s, &graph.get(n).as_ref().unwrap().state)); -- let enviro = match (d.next(), d.next()) { -+ -+ let mut rng = rand_pcg::Pcg64Mcg::seed_from_u64(spice + 1); // cheeky hash -+ let generates_cliff_side = A_ADJACENT[rng.gen_range(0, 4)]; // hard-coded to include all elements in A_ADJACENT -+ -+ let enviro; -+ let cliff_data; -+ match (d.next(), d.next()) { - (Some(_), None) => { - let parent_side = graph.parent(node).unwrap(); - let parent_node = graph.neighbor(node, parent_side).unwrap(); - let parent_state = &graph.get(parent_node).as_ref().unwrap().state; -- EnviroFactors::varied_from(parent_state.enviro, spice) -+ enviro = EnviroFactors::varied_from(parent_state.enviro, spice); -+ let is_cliff = { -+ if parent_state.cliff_data.generates_cliff -+ && (parent_state.cliff_data.generates_cliff_side == side) -+ && (parent_state.kind == Land) -+ { -+ !parent_state.cliff_data.is_cliff -+ } else { -+ parent_state.cliff_data.is_cliff -+ } -+ }; -+ -+ let generates_cliff = match is_cliff { -+ true => rng.gen_ratio(4, 5), -+ false => rng.gen_ratio(1, 3), -+ }; -+ -+ cliff_data = CliffState { -+ is_cliff, -+ generates_cliff, -+ generates_cliff_side, -+ }; - } - (Some((a_side, a_state)), Some((b_side, b_state))) => { - let ab_node = graph - .neighbor(graph.neighbor(node, a_side).unwrap(), b_side) - .unwrap(); - let ab_state = &graph.get(ab_node).as_ref().unwrap().state; -- EnviroFactors::continue_from(a_state.enviro, b_state.enviro, ab_state.enviro) -+ enviro = -+ EnviroFactors::continue_from(a_state.enviro, b_state.enviro, ab_state.enviro); -+ -+ let is_cliff = a_state.cliff_data.is_cliff -+ ^ b_state.cliff_data.is_cliff -+ ^ ab_state.cliff_data.is_cliff; -+ let generates_cliff = rng.gen_ratio(1, 3); -+ cliff_data = CliffState { -+ is_cliff, -+ generates_cliff, -+ generates_cliff_side, -+ }; - } - _ => unreachable!(), - }; -@@ -124,6 +177,7 @@ - _ => side * self.surface, - }, - road_state: child_road, -+ cliff_data, - spice, - enviro, - } -@@ -143,6 +197,7 @@ - is_road: bool, - /// Whether this chunk contains a section of the road's supports - is_road_support: bool, -+ is_cliff: bool, - node_spice: u64, - } - -@@ -161,6 +216,7 @@ - && ((state.road_state == East) || (state.road_state == West)), - is_road_support: ((state.kind == Land) || (state.kind == DeepLand)) - && ((state.road_state == East) || (state.road_state == West)), -+ is_cliff: state.cliff_data.is_cliff, - node_spice: state.spice, - }) - } -@@ -200,7 +256,13 @@ - // otherwise the terracing fails to be (nonstrictly) monotonic - // and the terrain gets trenches ringing around its cliffs. - let elev_pre_noise = -- elev_pre_terracing + 0.6 * terracing_small + 0.4 * terracing_big; -+ elev_pre_terracing + 0.6 * terracing_small + 0.4 * terracing_big + { -+ if self.is_cliff { -+ 14.0 -+ } else { -+ 0.0 -+ } -+ }; - - // initial value dist_pre_noise is the difference between the voxel's distance - // from the guiding plane and the voxel's calculated elev value. It represents -@@ -405,7 +467,7 @@ - // Maximum difference between elevations at the center of a chunk and any other point in the chunk - // TODO: Compute what this actually is, current value is a guess! Real one must be > 0.6 - // empirically. -- const ELEVATION_MARGIN: f64 = 0.7; -+ /*const ELEVATION_MARGIN: f64 = 0.7; - let center_elevation = self - .surface - .distance_to_chunk(self.chunk, &na::Vector3::repeat(0.5)); -@@ -420,7 +482,7 @@ - // The whole chunk is underground - // TODO: More accurate VoxelData - return VoxelData::Solid(Material::Dirt); -- } -+ }*/ - - let mut voxels = VoxelData::Solid(Material::Void); - let mut rng = rand_pcg::Pcg64Mcg::seed_from_u64(hash(self.node_spice, self.chunk as u64)); From dd9b25afc38572e7d04bbcf2cda853de12dd7358 Mon Sep 17 00:00:00 2001 From: DimpyRed Date: Thu, 15 Oct 2020 13:08:33 -0700 Subject: [PATCH 4/4] ran fmt --- common/src/worldgen.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/common/src/worldgen.rs b/common/src/worldgen.rs index efa3b3b2..5860b4d4 100644 --- a/common/src/worldgen.rs +++ b/common/src/worldgen.rs @@ -284,7 +284,6 @@ impl NodeState { } } - struct VoxelCoords { counter: u32, dimension: u8, @@ -320,7 +319,6 @@ impl Iterator for VoxelCoords { } } - /// Returns the amount of elevation to add based on there being a cliff fn cliff_boost(is_cliff: bool) -> f64 { if is_cliff { @@ -401,7 +399,7 @@ impl ChunkParams { if (center_elevation + ELEVATION_MARGIN < (me_min + cliff_boost(self.is_plateau) * (!self.is_cliff_adjacent as i32 as f64)) - / TERRAIN_SMOOTHNESS) + / TERRAIN_SMOOTHNESS) && !self.is_road { // The whole chunk is underground @@ -481,7 +479,6 @@ impl ChunkParams { if dist >= 0.0 { let voxel_mat = VoronoiInfo::terraingen_voronoi(elev, rain, temp, dist); voxels.data_mut(self.dimension)[index(self.dimension, coords)] = voxel_mat; - } } }