From 9fed2c15344eff8cfb9db2097e7f44957897b5d2 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 11 Jun 2019 19:39:25 +0100 Subject: [PATCH] Merged stumps, adjusted scale code --- Cargo.lock | 1 + client/src/lib.rs | 20 +++++++++++-- common/src/terrain/biome.rs | 2 +- common/src/terrain/chonk.rs | 4 +++ common/src/terrain/mod.rs | 20 +++++++++++++ voxygen/shaders/include/sky.glsl | 4 +-- voxygen/shaders/postprocess.frag | 3 +- voxygen/src/session.rs | 6 ++++ world/Cargo.toml | 1 + world/src/all.rs | 7 +++++ world/src/block/mod.rs | 9 ++++-- world/src/block/tree.rs | 26 +++++++++++++++-- world/src/column/mod.rs | 18 ++++++++---- world/src/config.rs | 4 +++ world/src/lib.rs | 1 + world/src/sim/location.rs | 50 +++++++++++++++++++++++++++++++- world/src/sim/mod.rs | 25 +++++++++++++--- 17 files changed, 179 insertions(+), 22 deletions(-) create mode 100644 world/src/all.rs diff --git a/Cargo.lock b/Cargo.lock index d3c7c8e832..bebb7e3540 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2676,6 +2676,7 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "minifb 0.11.2 (git+https://github.com/emoon/rust_minifb.git)", "noise 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "vek 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "veloren-common 0.2.0", ] diff --git a/client/src/lib.rs b/client/src/lib.rs index f491359419..83ad07f696 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(label_break_value, duration_float)] +#![feature(label_break_value, duration_float, euclidean_division)] pub mod error; @@ -12,13 +12,19 @@ use common::{ msg::{ClientMsg, ClientState, ServerInfo, ServerMsg}, net::PostBox, state::State, - terrain::chonk::ChonkMetrics, + terrain::{ + TerrainChunk, + TerrainChunkSize, + chonk::ChonkMetrics, + }, + vol::VolSize, }; use log::{debug, info, log_enabled}; use std::{ collections::HashMap, net::SocketAddr, time::{Duration, Instant}, + sync::Arc, }; use threadpool::ThreadPool; use vek::*; @@ -148,6 +154,16 @@ impl Client { self.loaded_distance } + pub fn current_chunk(&self) -> Option> { + let chunk_pos = Vec2::from(self + .state + .read_storage::() + .get(self.entity) + .cloned()?.0).map2(Vec2::from(TerrainChunkSize::SIZE), |e: f32, sz| (e as u32).div_euclid(sz) as i32); + + self.state.terrain().get_key_arc(chunk_pos).cloned() + } + /// Send a chat message to the server. #[allow(dead_code)] pub fn send_chat(&mut self, msg: String) { diff --git a/common/src/terrain/biome.rs b/common/src/terrain/biome.rs index b816da7079..4c5b29aacf 100644 --- a/common/src/terrain/biome.rs +++ b/common/src/terrain/biome.rs @@ -1,6 +1,6 @@ use serde_derive::{Deserialize, Serialize}; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] pub enum BiomeKind { Void, Grassland, diff --git a/common/src/terrain/chonk.rs b/common/src/terrain/chonk.rs index e83886b94c..50bf080449 100644 --- a/common/src/terrain/chonk.rs +++ b/common/src/terrain/chonk.rs @@ -36,6 +36,10 @@ impl Chonk { } } + pub fn meta(&self) -> &TerrainChunkMeta { + &self.meta + } + pub fn get_min_z(&self) -> i32 { self.z_offset } diff --git a/common/src/terrain/mod.rs b/common/src/terrain/mod.rs index 9c8edef0be..ef7259db90 100644 --- a/common/src/terrain/mod.rs +++ b/common/src/terrain/mod.rs @@ -27,15 +27,35 @@ impl VolSize for TerrainChunkSize { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TerrainChunkMeta { + name: Option, biome: BiomeKind, } impl TerrainChunkMeta { + pub fn new(name: Option, biome: BiomeKind) -> Self { + Self { + name, + biome, + } + } + pub fn void() -> Self { Self { + name: None, biome: BiomeKind::Void, } } + + pub fn name(&self) -> &str { + self.name + .as_ref() + .map(|s| s.as_str()) + .unwrap_or("Wilderness") + } + + pub fn biome(&self) -> BiomeKind { + self.biome + } } // Terrain type aliases diff --git a/voxygen/shaders/include/sky.glsl b/voxygen/shaders/include/sky.glsl index 6ee29fb132..3bb9b64307 100644 --- a/voxygen/shaders/include/sky.glsl +++ b/voxygen/shaders/include/sky.glsl @@ -3,8 +3,8 @@ const float PI = 3.141592; vec3 get_sky_color(vec3 dir, float time_of_day) { const float TIME_FACTOR = (PI * 2.0) / (3600.0 * 24.0); - const vec3 SKY_TOP = vec3(0.1, 0.5, 1.0); - const vec3 SKY_BOTTOM = vec3(0.025, 0.08, 0.2); + const vec3 SKY_TOP = vec3(0.05, 0.2, 0.9); + const vec3 SKY_BOTTOM = vec3(0.025, 0.1, 0.5); const vec3 SUN_HALO_COLOR = vec3(1.0, 0.7, 0.5) * 0.5; const vec3 SUN_SURF_COLOR = vec3(1.0, 0.9, 0.35) * 200.0; diff --git a/voxygen/shaders/postprocess.frag b/voxygen/shaders/postprocess.frag index 5e56224797..f1f644b4e6 100644 --- a/voxygen/shaders/postprocess.frag +++ b/voxygen/shaders/postprocess.frag @@ -166,8 +166,9 @@ void main() { vec4 fxaa_color = fxaa_apply(src_color, uv * screen_res.xy, screen_res.xy); vec4 hsva_color = vec4(rgb2hsv(fxaa_color.rgb), fxaa_color.a); - hsva_color.y *= 1.27; + hsva_color.y *= 1.3; hsva_color.x -= 0.015; + hsva_color.z *= 0.85; //hsva_color.z = 1.0 - 1.0 / (1.0 * hsva_color.z + 1.0); vec4 final_color = vec4(hsv2rgb(hsva_color.rgb), hsva_color.a); diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 6e20d3e725..795ce25eb5 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -69,6 +69,12 @@ impl SessionState { } } + // TODO: Get rid of this + match self.client.borrow().current_chunk() { + Some(chunk) => println!("Chunk location: {:?}", chunk.meta().name()), + None => {}, + } + Ok(()) } diff --git a/world/Cargo.toml b/world/Cargo.toml index dc07295de9..d73e150608 100644 --- a/world/Cargo.toml +++ b/world/Cargo.toml @@ -10,6 +10,7 @@ vek = "0.9" noise = "0.5" fxhash = "0.2" lazy_static = "1.3" +rand = "0.5" [dev-dependencies] minifb = { git = "https://github.com/emoon/rust_minifb.git" } diff --git a/world/src/all.rs b/world/src/all.rs new file mode 100644 index 0000000000..41f8eee75a --- /dev/null +++ b/world/src/all.rs @@ -0,0 +1,7 @@ +#[derive(Copy, Clone)] +pub enum ForestKind { + Palm, + Oak, + Pine, + SnowPine, +} diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 2d0dc0e1c2..d6a9895765 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -13,7 +13,6 @@ use crate::{ CONFIG, World, }; -use self::tree::TREES; pub struct BlockGen<'a> { world: &'a World, @@ -48,6 +47,7 @@ impl<'a> Sampler for BlockGen<'a> { chaos, surface_color, tree_density, + forest_kind, close_trees, cave_xy, cave_alt, @@ -164,8 +164,11 @@ impl<'a> Sampler for BlockGen<'a> { let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, tree_sample.alt as i32); let rpos = wpos - tree_pos3d; - block.or(TREES[*tree_seed as usize % TREES.len()] - .get((rpos * 160) / 160) // Scaling + + let trees = tree::kinds(tree_sample.forest_kind); // Choose tree kind + + block.or(trees[*tree_seed as usize % trees.len()] + .get((rpos * 128) / 128) // Scaling .map(|b| b.clone()) .unwrap_or(Block::empty())) } diff --git a/world/src/block/tree.rs b/world/src/block/tree.rs index 061f6fec88..17bc34ec42 100644 --- a/world/src/block/tree.rs +++ b/world/src/block/tree.rs @@ -2,9 +2,19 @@ use common::{assets, terrain::Structure}; use lazy_static::lazy_static; use std::sync::Arc; use vek::*; +use crate::all::ForestKind; + +pub fn kinds(forest_kind: ForestKind) -> &'static [Arc] { + match forest_kind { + ForestKind::Palm => &PALMS, + ForestKind::Oak => &OAKS, + ForestKind::Pine => &PINES, + ForestKind::SnowPine => &SNOW_PINES, + } +} lazy_static! { - pub static ref TREES: [Arc; 90] = [ + pub static ref OAKS: Vec> = vec![ // green oaks assets::load_map("world/tree/oak_green/1.vox", |s: Structure| s .with_center(Vec3::new(15, 18, 14))) @@ -61,6 +71,9 @@ lazy_static! { assets::load_map("world/tree/oak_stump/9.vox", |s: Structure| s .with_center(Vec3::new(26, 26, 10))) .unwrap(), + ]; + + pub static ref PINES: Vec> = vec![ // green pines assets::load_map("world/tree/pine_green/1.vox", |s: Structure| s .with_center(Vec3::new(15, 15, 14))) @@ -136,6 +149,8 @@ lazy_static! { assets::load_map("world/tree/pine_blue/8.vox", |s: Structure| s .with_center(Vec3::new(12, 10, 12))) .unwrap(), + ]; + /* // temperate small assets::load_map("world/tree/temperate_small/1.vox", |s: Structure| s .with_center(Vec3::new(4, 4, 7))) @@ -223,6 +238,9 @@ lazy_static! { assets::load_map("world/tree/poplar/10.vox", |s: Structure| s .with_center(Vec3::new(7, 7, 10))) .unwrap(), + */ + + pub static ref PALMS: Vec> = vec![ // palm trees assets::load_map("world/tree/desert_palm/1.vox", |s: Structure| s .with_center(Vec3::new(12, 12, 10))) @@ -254,6 +272,9 @@ lazy_static! { assets::load_map("world/tree/desert_palm/10.vox", |s: Structure| s .with_center(Vec3::new(10, 10, 10))) .unwrap(), + ]; + + pub static ref SNOW_PINES: Vec> = vec![ // snow pines assets::load_map("world/tree/snow_pine/1.vox", |s: Structure| s .with_center(Vec3::new(15, 15, 14))) @@ -279,6 +300,7 @@ lazy_static! { assets::load_map("world/tree/snow_pine/8.vox", |s: Structure| s .with_center(Vec3::new(12, 10, 12))) .unwrap(), + ]; /* // snow birches -> need roots! assets::load_map("world/tree/snow_birch/1.vox", |s: Structure| s @@ -317,7 +339,6 @@ lazy_static! { assets::load_map("world/tree/snow_birch/12.vox", |s: Structure| s .with_center(Vec3::new(10, 9, 4))) .unwrap(), - */ // willows assets::load_map("world/tree/willow/1.vox", |s: Structure| s .with_center(Vec3::new(15, 14, 1))) @@ -326,4 +347,5 @@ lazy_static! { .with_center(Vec3::new(11, 12, 1))) .unwrap(), ]; + */ } diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 7faa8b104d..4664d2431c 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -2,11 +2,12 @@ use std::ops::{Add, Div, Mul, Neg, Sub}; use vek::*; use noise::NoiseFn; use common::{ - terrain::Block, - vol::Vox, + terrain::{Block, TerrainChunkSize}, + vol::{Vox, VolSize}, }; use crate::{ CONFIG, + all::ForestKind, util::Sampler, World, }; @@ -29,6 +30,7 @@ impl<'a> Sampler for ColumnGen<'a> { fn get(&mut self, wpos: Vec2) -> Option { let wposf = wpos.map(|e| e as f64); + let chunk_pos = wpos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| e as u32 / sz); let sim = self.world.sim(); @@ -39,6 +41,8 @@ impl<'a> Sampler for ColumnGen<'a> { let cliffiness = sim.get_interpolated(wpos, |chunk| chunk.cliffiness)?; let tree_density = sim.get_interpolated(wpos, |chunk| chunk.tree_density)?; + let forest_kind = sim.get(chunk_pos)?.forest_kind; + let alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? + sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32 * chaos.max(0.2) @@ -60,12 +64,12 @@ impl<'a> Sampler for ColumnGen<'a> { // Colours let cold_grass = Rgb::new(0.0, 0.3, 0.1); - let warm_grass = Rgb::new(0.25, 0.9, 0.05); + let warm_grass = Rgb::new(0.35, 1.0, 0.05); let cold_stone = Rgb::new(0.55, 0.7, 0.75); let warm_stone = Rgb::new(0.65, 0.65, 0.35); let beach_sand = Rgb::new(0.93, 0.84, 0.4); let desert_sand = Rgb::new(0.98, 0.8, 0.15); - let snow = Rgb::new(0.9, 0.9, 1.3); + let snow = Rgb::broadcast(1.0); let grass = Rgb::lerp(cold_grass, warm_grass, marble); let sand = Rgb::lerp(beach_sand, desert_sand, marble); @@ -75,10 +79,10 @@ impl<'a> Sampler for ColumnGen<'a> { Rgb::lerp( snow, grass, - temp.add(0.4).add(marble * 0.05).mul(256.0).sub(0.4), + temp.sub(CONFIG.snow_temp).sub(marble * 0.05).mul(256.0), ), sand, - temp.sub(0.4).mul(32.0).add(0.4), + temp.sub(CONFIG.desert_temp).mul(32.0), ); // Caves @@ -134,6 +138,7 @@ impl<'a> Sampler for ColumnGen<'a> { (alt - CONFIG.sea_level - 2.0) / 5.0, ), tree_density, + forest_kind, close_trees: sim.gen_ctx.tree_gen.get(wpos), cave_xy, cave_alt, @@ -149,6 +154,7 @@ pub struct ColumnSample { pub chaos: f32, pub surface_color: Rgb, pub tree_density: f32, + pub forest_kind: ForestKind, pub close_trees: [(Vec2, u32); 9], pub cave_xy: f32, pub cave_alt: f32, diff --git a/world/src/config.rs b/world/src/config.rs index 3e5d801e42..035b4c60d4 100644 --- a/world/src/config.rs +++ b/world/src/config.rs @@ -1,9 +1,13 @@ pub struct Config { pub sea_level: f32, pub mountain_scale: f32, + pub snow_temp: f32, + pub desert_temp: f32, } pub const CONFIG: Config = Config { sea_level: 140.0, mountain_scale: 1200.0, + snow_temp: -0.4, + desert_temp: 0.4, }; diff --git a/world/src/lib.rs b/world/src/lib.rs index 15289dfafa..2f5ccc01ca 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -1,6 +1,7 @@ #![feature(euclidean_division, bind_by_move_pattern_guards)] mod config; +mod all; mod util; mod block; mod column; diff --git a/world/src/sim/location.rs b/world/src/sim/location.rs index fb02b051d4..6eed4b555d 100644 --- a/world/src/sim/location.rs +++ b/world/src/sim/location.rs @@ -1 +1,49 @@ -pub struct Location; +use rand::Rng; + +#[derive(Copy, Clone, Debug)] +pub enum LocationKind { + Settlement, + Mountain, + Forest, +} + +#[derive(Clone, Debug)] +pub struct Location { + name: String, + kind: LocationKind, + kingdom: Kingdom, +} + +#[derive(Clone, Debug)] +pub struct Kingdom { + name: String, +} + +fn generate_name() -> String { + let consts = [ + "st", "tr", "b", "n", "p", "ph", "cr", "g", "c", + "d", "k", "kr", "kl", "gh", "sl", "st", "cr", "sp", + "th", "dr", "pr", "dr", "gr", "br", "ryth", "rh", "sl", + "f", "fr", "p", "pr", "qu", "s", "sh", "z", "k", + "br", "wh", "tr", "h", "bl", "sl", "r", "kl", "sl", + "w", "v", "vr", "kr", + ]; + let vowels = ["oo", "o", "oa", "au", "e", "ee", "ea", "ou", "u", "a", "i", "ie"]; + let tails = [ + "er", "in", "o", "on", "an", + "ar", "is", "oon", "er", "aru", + "ab", "um", "id", "and", "eld", + "ald", "oft", "aft", "ift", "ity", + "ell", "oll", "ill", "all", + ]; + + let mut name = String::new(); + for i in 0..rand::random::() % 2 { + name += rand::thread_rng().choose(&consts).unwrap(); + name += rand::thread_rng().choose(&vowels).unwrap(); + } + name += rand::thread_rng().choose(&consts).unwrap(); + name += rand::thread_rng().choose(&tails).unwrap(); + + name +} diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 19c999a2bf..44829d60d9 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -15,6 +15,7 @@ use common::{ }; use crate::{ CONFIG, + all::ForestKind, util::StructureGen2d, }; use self::location::Location; @@ -69,7 +70,7 @@ impl WorldSim { cave_0_nz: SuperSimplex::new().set_seed(seed + 10), cave_1_nz: SuperSimplex::new().set_seed(seed + 11), - tree_gen: StructureGen2d::new(seed, 24, 16), + tree_gen: StructureGen2d::new(seed, 32, 24), }; let mut chunks = Vec::new(); @@ -166,6 +167,7 @@ pub struct SimChunk { pub rockiness: f32, pub cliffiness: f32, pub tree_density: f32, + pub forest_kind: ForestKind, pub location: Option>, } @@ -208,7 +210,7 @@ impl SimChunk { + (0.0 + alt_main + gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32 - * alt_main.max(0.05) + * alt_main.max(0.1) * chaos * 1.6) .add(1.0) @@ -216,14 +218,16 @@ impl SimChunk { .mul(chaos) .mul(CONFIG.mountain_scale); + let temp = (gen_ctx.temp_nz.get((wposf.div(8192.0)).into_array()) as f32); + Self { chaos, alt_base, alt, - temp: (gen_ctx.temp_nz.get((wposf.div(8192.0)).into_array()) as f32), + temp, rockiness: (gen_ctx.rock_nz.get((wposf.div(1024.0)).into_array()) as f32) .sub(0.1) - .mul(1.2) + .mul(1.3) .max(0.0), cliffiness: (gen_ctx.cliff_nz.get((wposf.div(2048.0)).into_array()) as f32) .sub(0.15) @@ -237,6 +241,19 @@ impl SimChunk { .mul(1.0 - chaos * 0.85) .add(0.1) .mul(if alt > CONFIG.sea_level + 2.0 { 1.0 } else { 0.0 }), + forest_kind: if temp > 0.0 { + if temp > CONFIG.desert_temp { + ForestKind::Palm + } else { + ForestKind::Oak + } + } else { + if temp > CONFIG.snow_temp { + ForestKind::Pine + } else { + ForestKind::SnowPine + } + }, location: None, } }