Merged stumps, adjusted scale code

This commit is contained in:
Joshua Barretto 2019-06-11 19:39:25 +01:00
parent e7649e1db4
commit 9fed2c1534
17 changed files with 179 additions and 22 deletions

1
Cargo.lock generated
View File

@ -2676,6 +2676,7 @@ dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "vek 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
"veloren-common 0.2.0", "veloren-common 0.2.0",
] ]

View File

@ -1,4 +1,4 @@
#![feature(label_break_value, duration_float)] #![feature(label_break_value, duration_float, euclidean_division)]
pub mod error; pub mod error;
@ -12,13 +12,19 @@ use common::{
msg::{ClientMsg, ClientState, ServerInfo, ServerMsg}, msg::{ClientMsg, ClientState, ServerInfo, ServerMsg},
net::PostBox, net::PostBox,
state::State, state::State,
terrain::chonk::ChonkMetrics, terrain::{
TerrainChunk,
TerrainChunkSize,
chonk::ChonkMetrics,
},
vol::VolSize,
}; };
use log::{debug, info, log_enabled}; use log::{debug, info, log_enabled};
use std::{ use std::{
collections::HashMap, collections::HashMap,
net::SocketAddr, net::SocketAddr,
time::{Duration, Instant}, time::{Duration, Instant},
sync::Arc,
}; };
use threadpool::ThreadPool; use threadpool::ThreadPool;
use vek::*; use vek::*;
@ -148,6 +154,16 @@ impl Client {
self.loaded_distance self.loaded_distance
} }
pub fn current_chunk(&self) -> Option<Arc<TerrainChunk>> {
let chunk_pos = Vec2::from(self
.state
.read_storage::<comp::phys::Pos>()
.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. /// Send a chat message to the server.
#[allow(dead_code)] #[allow(dead_code)]
pub fn send_chat(&mut self, msg: String) { pub fn send_chat(&mut self, msg: String) {

View File

@ -1,6 +1,6 @@
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum BiomeKind { pub enum BiomeKind {
Void, Void,
Grassland, Grassland,

View File

@ -36,6 +36,10 @@ impl Chonk {
} }
} }
pub fn meta(&self) -> &TerrainChunkMeta {
&self.meta
}
pub fn get_min_z(&self) -> i32 { pub fn get_min_z(&self) -> i32 {
self.z_offset self.z_offset
} }

View File

@ -27,15 +27,35 @@ impl VolSize for TerrainChunkSize {
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TerrainChunkMeta { pub struct TerrainChunkMeta {
name: Option<String>,
biome: BiomeKind, biome: BiomeKind,
} }
impl TerrainChunkMeta { impl TerrainChunkMeta {
pub fn new(name: Option<String>, biome: BiomeKind) -> Self {
Self {
name,
biome,
}
}
pub fn void() -> Self { pub fn void() -> Self {
Self { Self {
name: None,
biome: BiomeKind::Void, 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 // Terrain type aliases

View File

@ -3,8 +3,8 @@ const float PI = 3.141592;
vec3 get_sky_color(vec3 dir, float time_of_day) { vec3 get_sky_color(vec3 dir, float time_of_day) {
const float TIME_FACTOR = (PI * 2.0) / (3600.0 * 24.0); 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_TOP = vec3(0.05, 0.2, 0.9);
const vec3 SKY_BOTTOM = vec3(0.025, 0.08, 0.2); 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_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; const vec3 SUN_SURF_COLOR = vec3(1.0, 0.9, 0.35) * 200.0;

View File

@ -166,8 +166,9 @@ void main() {
vec4 fxaa_color = fxaa_apply(src_color, uv * screen_res.xy, screen_res.xy); 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); 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.x -= 0.015;
hsva_color.z *= 0.85;
//hsva_color.z = 1.0 - 1.0 / (1.0 * hsva_color.z + 1.0); //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); vec4 final_color = vec4(hsv2rgb(hsva_color.rgb), hsva_color.a);

View File

@ -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(()) Ok(())
} }

View File

@ -10,6 +10,7 @@ vek = "0.9"
noise = "0.5" noise = "0.5"
fxhash = "0.2" fxhash = "0.2"
lazy_static = "1.3" lazy_static = "1.3"
rand = "0.5"
[dev-dependencies] [dev-dependencies]
minifb = { git = "https://github.com/emoon/rust_minifb.git" } minifb = { git = "https://github.com/emoon/rust_minifb.git" }

7
world/src/all.rs Normal file
View File

@ -0,0 +1,7 @@
#[derive(Copy, Clone)]
pub enum ForestKind {
Palm,
Oak,
Pine,
SnowPine,
}

View File

@ -13,7 +13,6 @@ use crate::{
CONFIG, CONFIG,
World, World,
}; };
use self::tree::TREES;
pub struct BlockGen<'a> { pub struct BlockGen<'a> {
world: &'a World, world: &'a World,
@ -48,6 +47,7 @@ impl<'a> Sampler for BlockGen<'a> {
chaos, chaos,
surface_color, surface_color,
tree_density, tree_density,
forest_kind,
close_trees, close_trees,
cave_xy, cave_xy,
cave_alt, cave_alt,
@ -164,8 +164,11 @@ impl<'a> Sampler for BlockGen<'a> {
let tree_pos3d = let tree_pos3d =
Vec3::new(tree_pos.x, tree_pos.y, tree_sample.alt as i32); Vec3::new(tree_pos.x, tree_pos.y, tree_sample.alt as i32);
let rpos = wpos - tree_pos3d; 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()) .map(|b| b.clone())
.unwrap_or(Block::empty())) .unwrap_or(Block::empty()))
} }

View File

@ -2,9 +2,19 @@ use common::{assets, terrain::Structure};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use std::sync::Arc; use std::sync::Arc;
use vek::*; use vek::*;
use crate::all::ForestKind;
pub fn kinds(forest_kind: ForestKind) -> &'static [Arc<Structure>] {
match forest_kind {
ForestKind::Palm => &PALMS,
ForestKind::Oak => &OAKS,
ForestKind::Pine => &PINES,
ForestKind::SnowPine => &SNOW_PINES,
}
}
lazy_static! { lazy_static! {
pub static ref TREES: [Arc<Structure>; 90] = [ pub static ref OAKS: Vec<Arc<Structure>> = vec![
// green oaks // green oaks
assets::load_map("world/tree/oak_green/1.vox", |s: Structure| s assets::load_map("world/tree/oak_green/1.vox", |s: Structure| s
.with_center(Vec3::new(15, 18, 14))) .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 assets::load_map("world/tree/oak_stump/9.vox", |s: Structure| s
.with_center(Vec3::new(26, 26, 10))) .with_center(Vec3::new(26, 26, 10)))
.unwrap(), .unwrap(),
];
pub static ref PINES: Vec<Arc<Structure>> = vec![
// green pines // green pines
assets::load_map("world/tree/pine_green/1.vox", |s: Structure| s assets::load_map("world/tree/pine_green/1.vox", |s: Structure| s
.with_center(Vec3::new(15, 15, 14))) .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 assets::load_map("world/tree/pine_blue/8.vox", |s: Structure| s
.with_center(Vec3::new(12, 10, 12))) .with_center(Vec3::new(12, 10, 12)))
.unwrap(), .unwrap(),
];
/*
// temperate small // temperate small
assets::load_map("world/tree/temperate_small/1.vox", |s: Structure| s assets::load_map("world/tree/temperate_small/1.vox", |s: Structure| s
.with_center(Vec3::new(4, 4, 7))) .with_center(Vec3::new(4, 4, 7)))
@ -223,6 +238,9 @@ lazy_static! {
assets::load_map("world/tree/poplar/10.vox", |s: Structure| s assets::load_map("world/tree/poplar/10.vox", |s: Structure| s
.with_center(Vec3::new(7, 7, 10))) .with_center(Vec3::new(7, 7, 10)))
.unwrap(), .unwrap(),
*/
pub static ref PALMS: Vec<Arc<Structure>> = vec![
// palm trees // palm trees
assets::load_map("world/tree/desert_palm/1.vox", |s: Structure| s assets::load_map("world/tree/desert_palm/1.vox", |s: Structure| s
.with_center(Vec3::new(12, 12, 10))) .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 assets::load_map("world/tree/desert_palm/10.vox", |s: Structure| s
.with_center(Vec3::new(10, 10, 10))) .with_center(Vec3::new(10, 10, 10)))
.unwrap(), .unwrap(),
];
pub static ref SNOW_PINES: Vec<Arc<Structure>> = vec![
// snow pines // snow pines
assets::load_map("world/tree/snow_pine/1.vox", |s: Structure| s assets::load_map("world/tree/snow_pine/1.vox", |s: Structure| s
.with_center(Vec3::new(15, 15, 14))) .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 assets::load_map("world/tree/snow_pine/8.vox", |s: Structure| s
.with_center(Vec3::new(12, 10, 12))) .with_center(Vec3::new(12, 10, 12)))
.unwrap(), .unwrap(),
];
/* /*
// snow birches -> need roots! // snow birches -> need roots!
assets::load_map("world/tree/snow_birch/1.vox", |s: Structure| s 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 assets::load_map("world/tree/snow_birch/12.vox", |s: Structure| s
.with_center(Vec3::new(10, 9, 4))) .with_center(Vec3::new(10, 9, 4)))
.unwrap(), .unwrap(),
*/
// willows // willows
assets::load_map("world/tree/willow/1.vox", |s: Structure| s assets::load_map("world/tree/willow/1.vox", |s: Structure| s
.with_center(Vec3::new(15, 14, 1))) .with_center(Vec3::new(15, 14, 1)))
@ -326,4 +347,5 @@ lazy_static! {
.with_center(Vec3::new(11, 12, 1))) .with_center(Vec3::new(11, 12, 1)))
.unwrap(), .unwrap(),
]; ];
*/
} }

View File

@ -2,11 +2,12 @@ use std::ops::{Add, Div, Mul, Neg, Sub};
use vek::*; use vek::*;
use noise::NoiseFn; use noise::NoiseFn;
use common::{ use common::{
terrain::Block, terrain::{Block, TerrainChunkSize},
vol::Vox, vol::{Vox, VolSize},
}; };
use crate::{ use crate::{
CONFIG, CONFIG,
all::ForestKind,
util::Sampler, util::Sampler,
World, World,
}; };
@ -29,6 +30,7 @@ impl<'a> Sampler for ColumnGen<'a> {
fn get(&mut self, wpos: Vec2<i32>) -> Option<ColumnSample> { fn get(&mut self, wpos: Vec2<i32>) -> Option<ColumnSample> {
let wposf = wpos.map(|e| e as f64); 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(); 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 cliffiness = sim.get_interpolated(wpos, |chunk| chunk.cliffiness)?;
let tree_density = sim.get_interpolated(wpos, |chunk| chunk.tree_density)?; 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)? let alt = sim.get_interpolated(wpos, |chunk| chunk.alt)?
+ sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32 + sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32
* chaos.max(0.2) * chaos.max(0.2)
@ -60,12 +64,12 @@ impl<'a> Sampler for ColumnGen<'a> {
// Colours // Colours
let cold_grass = Rgb::new(0.0, 0.3, 0.1); 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 cold_stone = Rgb::new(0.55, 0.7, 0.75);
let warm_stone = Rgb::new(0.65, 0.65, 0.35); let warm_stone = Rgb::new(0.65, 0.65, 0.35);
let beach_sand = Rgb::new(0.93, 0.84, 0.4); let beach_sand = Rgb::new(0.93, 0.84, 0.4);
let desert_sand = Rgb::new(0.98, 0.8, 0.15); 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 grass = Rgb::lerp(cold_grass, warm_grass, marble);
let sand = Rgb::lerp(beach_sand, desert_sand, marble); let sand = Rgb::lerp(beach_sand, desert_sand, marble);
@ -75,10 +79,10 @@ impl<'a> Sampler for ColumnGen<'a> {
Rgb::lerp( Rgb::lerp(
snow, snow,
grass, 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, sand,
temp.sub(0.4).mul(32.0).add(0.4), temp.sub(CONFIG.desert_temp).mul(32.0),
); );
// Caves // Caves
@ -134,6 +138,7 @@ impl<'a> Sampler for ColumnGen<'a> {
(alt - CONFIG.sea_level - 2.0) / 5.0, (alt - CONFIG.sea_level - 2.0) / 5.0,
), ),
tree_density, tree_density,
forest_kind,
close_trees: sim.gen_ctx.tree_gen.get(wpos), close_trees: sim.gen_ctx.tree_gen.get(wpos),
cave_xy, cave_xy,
cave_alt, cave_alt,
@ -149,6 +154,7 @@ pub struct ColumnSample {
pub chaos: f32, pub chaos: f32,
pub surface_color: Rgb<f32>, pub surface_color: Rgb<f32>,
pub tree_density: f32, pub tree_density: f32,
pub forest_kind: ForestKind,
pub close_trees: [(Vec2<i32>, u32); 9], pub close_trees: [(Vec2<i32>, u32); 9],
pub cave_xy: f32, pub cave_xy: f32,
pub cave_alt: f32, pub cave_alt: f32,

View File

@ -1,9 +1,13 @@
pub struct Config { pub struct Config {
pub sea_level: f32, pub sea_level: f32,
pub mountain_scale: f32, pub mountain_scale: f32,
pub snow_temp: f32,
pub desert_temp: f32,
} }
pub const CONFIG: Config = Config { pub const CONFIG: Config = Config {
sea_level: 140.0, sea_level: 140.0,
mountain_scale: 1200.0, mountain_scale: 1200.0,
snow_temp: -0.4,
desert_temp: 0.4,
}; };

View File

@ -1,6 +1,7 @@
#![feature(euclidean_division, bind_by_move_pattern_guards)] #![feature(euclidean_division, bind_by_move_pattern_guards)]
mod config; mod config;
mod all;
mod util; mod util;
mod block; mod block;
mod column; mod column;

View File

@ -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::<u32>() % 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
}

View File

@ -15,6 +15,7 @@ use common::{
}; };
use crate::{ use crate::{
CONFIG, CONFIG,
all::ForestKind,
util::StructureGen2d, util::StructureGen2d,
}; };
use self::location::Location; use self::location::Location;
@ -69,7 +70,7 @@ impl WorldSim {
cave_0_nz: SuperSimplex::new().set_seed(seed + 10), cave_0_nz: SuperSimplex::new().set_seed(seed + 10),
cave_1_nz: SuperSimplex::new().set_seed(seed + 11), 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(); let mut chunks = Vec::new();
@ -166,6 +167,7 @@ pub struct SimChunk {
pub rockiness: f32, pub rockiness: f32,
pub cliffiness: f32, pub cliffiness: f32,
pub tree_density: f32, pub tree_density: f32,
pub forest_kind: ForestKind,
pub location: Option<Arc<Location>>, pub location: Option<Arc<Location>>,
} }
@ -208,7 +210,7 @@ impl SimChunk {
+ (0.0 + (0.0
+ alt_main + alt_main
+ gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32 + gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32
* alt_main.max(0.05) * alt_main.max(0.1)
* chaos * chaos
* 1.6) * 1.6)
.add(1.0) .add(1.0)
@ -216,14 +218,16 @@ impl SimChunk {
.mul(chaos) .mul(chaos)
.mul(CONFIG.mountain_scale); .mul(CONFIG.mountain_scale);
let temp = (gen_ctx.temp_nz.get((wposf.div(8192.0)).into_array()) as f32);
Self { Self {
chaos, chaos,
alt_base, alt_base,
alt, 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) rockiness: (gen_ctx.rock_nz.get((wposf.div(1024.0)).into_array()) as f32)
.sub(0.1) .sub(0.1)
.mul(1.2) .mul(1.3)
.max(0.0), .max(0.0),
cliffiness: (gen_ctx.cliff_nz.get((wposf.div(2048.0)).into_array()) as f32) cliffiness: (gen_ctx.cliff_nz.get((wposf.div(2048.0)).into_array()) as f32)
.sub(0.15) .sub(0.15)
@ -237,6 +241,19 @@ impl SimChunk {
.mul(1.0 - chaos * 0.85) .mul(1.0 - chaos * 0.85)
.add(0.1) .add(0.1)
.mul(if alt > CONFIG.sea_level + 2.0 { 1.0 } else { 0.0 }), .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, location: None,
} }
} }