From bf5b1cb4ade6613065023023d2a1813e3b4d73af Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 25 Jun 2019 22:00:26 +0100 Subject: [PATCH 01/40] Calculate delta time properly, fix low fps collision issues by decreasing max dt --- voxygen/src/scene/figure.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index fb35f50999..9409bd9658 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -757,8 +757,8 @@ impl FigureState { dt: f32, ) { // Update interpolate pos - self.pos = Lerp::lerp(self.pos, pos, (0.3f32).powf(1.0 / 60.0).powf(1.0 / dt)); - self.ori = Slerp::slerp(self.ori, ori, (0.15f32).powf(1.0 / 60.0).powf(1.0 / dt)); + self.pos = Lerp::lerp(self.pos, pos, (0.4f32).powf(60.0).powf(dt)); + self.ori = Slerp::slerp(self.ori, ori, (0.2f32).powf(60.0).powf(dt)); let mat = Mat4::::identity() * Mat4::translation_3d(self.pos) From bc7cee18460267a872f9f6eb8d3249c6e56dc18e Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 18 Jun 2019 12:33:18 +0100 Subject: [PATCH 02/40] Lighting fixes --- voxygen/shaders/terrain.frag | 4 +-- voxygen/src/mesh/segment.rs | 7 ++--- voxygen/src/mesh/terrain.rs | 58 ++++++++++++++++++++--------------- voxygen/src/mesh/vol.rs | 59 ++++++++++++++++++++++-------------- world/src/column/mod.rs | 11 ++++--- 5 files changed, 80 insertions(+), 59 deletions(-) diff --git a/voxygen/shaders/terrain.frag b/voxygen/shaders/terrain.frag index 3678ec803d..e3d350f924 100644 --- a/voxygen/shaders/terrain.frag +++ b/voxygen/shaders/terrain.frag @@ -30,11 +30,11 @@ void main() { float glob_ambience = 0.0005; - float sun_ambience = 0.8; + float sun_ambience = 0.3; vec3 sun_dir = normalize(vec3(0.7, 1.3, 2.1)); - float sun_diffuse = dot(sun_dir, f_norm); + float sun_diffuse = max(dot(sun_dir, f_norm), 0.0); float sun_light = sun_ambience + sun_diffuse; float static_light = glob_ambience + min(sun_light, f_light); diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs index ad01b2f054..3ef53159f5 100644 --- a/voxygen/src/mesh/segment.rs +++ b/voxygen/src/mesh/segment.rs @@ -10,10 +10,6 @@ use vek::*; type FigureVertex = ::Vertex; -fn create_vertex(origin: Vec3, norm: Vec3, col: Rgb) -> FigureVertex { - FigureVertex::new(origin, norm, col, 0) -} - impl Meshable for Segment { type Pipeline = FigurePipeline; type Supplement = Vec3; @@ -31,8 +27,9 @@ impl Meshable for Segment { pos, offs + pos.map(|e| e as f32), col, - create_vertex, + |origin, norm, col, light| FigureVertex::new(origin, norm, col * light, 0), true, + &[[[1.0; 3]; 3]; 3], ); } } diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index 868a2d9498..e299f9635f 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -51,19 +51,48 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for for x in range.min.x + 1..range.max.x - 1 { for y in range.min.y + 1..range.max.y - 1 { - let mut neighbour_light = [[(1.0f32, 0.0); 3]; 3]; + let mut neighbour_light = [[[1.0f32; 3]; 3]; 3]; for z in (range.min.z..range.max.z).rev() { let pos = Vec3::new(x, y, z); + // Shift lighting + neighbour_light[2] = neighbour_light[1]; + neighbour_light[1] = neighbour_light[0]; + + // Accumulate shade under opaque blocks + for i in 0..3 { + for j in 0..3 { + neighbour_light[0][i][j] = if let Some(opacity) = self + .get(pos + Vec3::new(i as i32 - 1, j as i32 - 1, -1)) + .ok() + .and_then(|vox| vox.get_opacity()) + { + (neighbour_light[0][i][j] * (1.0 - opacity * 0.2)).max(1.0 - opacity * 1.0) + } else { + (neighbour_light[0][i][j] * 1.035).min(1.0) + }; + } + } + + // Spread light + neighbour_light[0] = [[neighbour_light[0] + .iter() + .map(|col| col.iter()) + .flatten() + .copied() + .fold(0.0, |a, x| a + x) / 9.0; 3]; 3]; + // Create mesh polygons if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) { let avg_light = neighbour_light .iter() + .map(|row| row.iter()) + .flatten() .map(|col| col.iter()) .flatten() - .fold(0.0, |a, (x, _)| a + x) - / 9.0; + .fold(0.0, |a, x| a + x) + / 27.0; let light = avg_light; let col = col.map(|e| e as f32 / 255.0); @@ -77,30 +106,11 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for pos, offs, col, - |pos, norm, col| TerrainVertex::new(pos, norm, col, light), + |pos, norm, col, light| TerrainVertex::new(pos, norm, col, light), false, + &neighbour_light, ); } - - // Accumulate shade under opaque blocks - for i in 0..3 { - for j in 0..3 { - let max_opacity = neighbour_light[i][j].1; - neighbour_light[i][j] = if let Some(opacity) = self - .get(pos + Vec3::new(i as i32 - 1, j as i32 - 1, 0)) - .ok() - .and_then(|vox| vox.get_opacity()) - { - ( - (neighbour_light[i][j].0 * (1.0 - max_opacity * 0.3)) - .max(1.0 - max_opacity * 0.999), - max_opacity.max(opacity), - ) - } else { - ((neighbour_light[i][j].0 * 1.02).min(1.0), max_opacity) - }; - } - } } } } diff --git a/voxygen/src/mesh/vol.rs b/voxygen/src/mesh/vol.rs index 7223a46af7..50d66a9135 100644 --- a/voxygen/src/mesh/vol.rs +++ b/voxygen/src/mesh/vol.rs @@ -10,23 +10,33 @@ use crate::render::{ /// Given volume, position, and cardinal directions, compute each vertex's AO value. /// `dirs` should be a slice of length 5 so that the sliding window of size 2 over the slice /// yields each vertex' adjacent positions. -fn get_ao_quad(vol: &V, pos: Vec3, dirs: &[Vec3]) -> Vec4 { +fn get_ao_quad(vol: &V, pos: Vec3, shift: Vec3, dirs: &[Vec3], corners: &[[usize; 3]; 4], darknesses: &[[[f32; 3]; 3]; 3]) -> Vec4 { dirs.windows(2) - .map(|offs| { + .enumerate() + .map(|(i, offs)| { let (s1, s2) = ( - vol.get(pos + offs[0]) + vol.get(pos + shift + offs[0]) .map(|v| !v.is_empty()) .unwrap_or(false), - vol.get(pos + offs[1]) + vol.get(pos + shift + offs[1]) .map(|v| !v.is_empty()) .unwrap_or(false), ); - if s1 && s2 { + let darkness = darknesses[corners[i][0]][corners[i][1]][corners[i][2]]; + + let darkness = darknesses + .iter() + .map(|x| x.iter().map(|y| y.iter())) + .flatten() + .flatten() + .fold(0.0, |a: f32, x| a.max(*x)); + + darkness * if s1 && s2 { 0.0 } else { let corner = vol - .get(pos + offs[0] + offs[1]) + .get(pos + shift + offs[0] + offs[1]) .map(|v| !v.is_empty()) .unwrap_or(false); // Map both 1 and 2 neighbors to 0.5 occlusion. @@ -41,7 +51,7 @@ fn get_ao_quad(vol: &V, pos: Vec3, dirs: &[Vec3]) -> Vec4< } // Utility function -fn create_quad, Vec3, Rgb) -> P::Vertex>( +fn create_quad, Vec3, Rgb, f32) -> P::Vertex>( origin: Vec3, unit_x: Vec3, unit_y: Vec3, @@ -53,29 +63,31 @@ fn create_quad, Vec3, Rgb) -> P::Vertex>( let ao_scale = 0.95; let dark = col * (1.0 - ao_scale); - let ao_map = ao.map(|e| 0.15 + e.powf(2.0) * 0.85); + let ao_map = ao;//ao.map(|e| 0.2 + e.powf(1.0) * 0.8); if ao[0].min(ao[2]) < ao[1].min(ao[3]) { Quad::new( - vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao_map[3])), - vcons(origin, norm, Rgb::lerp(dark, col, ao_map[0])), - vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao_map[1])), + vcons(origin + unit_y, norm, col, ao_map[3]), + vcons(origin, norm, col, ao_map[0]), + vcons(origin + unit_x, norm, col, ao_map[1]), vcons( origin + unit_x + unit_y, norm, - Rgb::lerp(dark, col, ao_map[2]), + col, + ao_map[2], ), ) } else { Quad::new( - vcons(origin, norm, Rgb::lerp(dark, col, ao_map[0])), - vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao_map[1])), + vcons(origin, norm, col, ao_map[0]), + vcons(origin + unit_x, norm, col, ao_map[1]), vcons( origin + unit_x + unit_y, norm, - Rgb::lerp(dark, col, ao_map[2]), + col, + ao_map[2], ), - vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao_map[3])), + vcons(origin + unit_y, norm, col, ao_map[3]), ) } } @@ -83,7 +95,7 @@ fn create_quad, Vec3, Rgb) -> P::Vertex>( pub fn push_vox_verts< V: ReadVol, P: Pipeline, - F: Fn(Vec3, Vec3, Rgb) -> P::Vertex, + F: Fn(Vec3, Vec3, Rgb, f32) -> P::Vertex, >( mesh: &mut Mesh

, vol: &V, @@ -92,6 +104,7 @@ pub fn push_vox_verts< col: Rgb, vcons: F, error_makes_face: bool, + darknesses: &[[[f32; 3]; 3]; 3], ) { let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()); @@ -107,7 +120,7 @@ pub fn push_vox_verts< Vec3::unit_y(), -Vec3::unit_x(), col, - get_ao_quad(vol, pos - Vec3::unit_x(), &[-z, -y, z, y, -z]), + get_ao_quad(vol, pos, -Vec3::unit_x(), &[-z, -y, z, y, -z], &[[0; 3]; 4], darknesses), &vcons, )); } @@ -123,7 +136,7 @@ pub fn push_vox_verts< Vec3::unit_z(), Vec3::unit_x(), col, - get_ao_quad(vol, pos + Vec3::unit_x(), &[-y, -z, y, z, -y]), + get_ao_quad(vol, pos, Vec3::unit_x(), &[-y, -z, y, z, -y], &[[0; 3]; 4], darknesses), &vcons, )); } @@ -139,7 +152,7 @@ pub fn push_vox_verts< Vec3::unit_z(), -Vec3::unit_y(), col, - get_ao_quad(vol, pos - Vec3::unit_y(), &[-x, -z, x, z, -x]), + get_ao_quad(vol, pos, -Vec3::unit_y(), &[-x, -z, x, z, -x], &[[0; 3]; 4], darknesses), &vcons, )); } @@ -155,7 +168,7 @@ pub fn push_vox_verts< Vec3::unit_x(), Vec3::unit_y(), col, - get_ao_quad(vol, pos + Vec3::unit_y(), &[-z, -x, z, x, -z]), + get_ao_quad(vol, pos, Vec3::unit_y(), &[-z, -x, z, x, -z], &[[0; 3]; 4], darknesses), &vcons, )); } @@ -171,7 +184,7 @@ pub fn push_vox_verts< Vec3::unit_x(), -Vec3::unit_z(), col, - get_ao_quad(vol, pos - Vec3::unit_z(), &[-y, -x, y, x, -y]), + get_ao_quad(vol, pos, -Vec3::unit_z(), &[-y, -x, y, x, -y], &[[0; 3]; 4], darknesses), &vcons, )); } @@ -187,7 +200,7 @@ pub fn push_vox_verts< Vec3::unit_y(), Vec3::unit_z(), col, - get_ao_quad(vol, pos + Vec3::unit_z(), &[-x, -y, x, y, -x]), + get_ao_quad(vol, pos, Vec3::unit_z(), &[-x, -y, x, y, -x], &[[0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]], darknesses), &vcons, )); } diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 0783aa4dd5..551267964c 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -39,9 +39,10 @@ impl<'a> Sampler for ColumnGen<'a> { 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) - * 64.0; + + (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32) + .abs() + .mul(chaos.max(0.2)) + .mul(64.0); let rock = (sim.gen_ctx.small_nz.get( Vec3::new(wposf.x, wposf.y, alt as f64) @@ -62,8 +63,8 @@ impl<'a> Sampler for ColumnGen<'a> { .mul(0.5); // Colours - let cold_grass = Rgb::new(0.0, 0.3, 0.1); - let warm_grass = Rgb::new(0.35, 1.0, 0.05); + let cold_grass = Rgb::new(0.0, 0.3, 0.15); + let warm_grass = Rgb::new(0.2, 0.8, 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); From aa28f0b4278809fee7e4012c332ab56d99881a04 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 18 Jun 2019 12:55:25 +0100 Subject: [PATCH 03/40] Better rock colours --- world/src/block/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index c09efbd5c9..06c9ddc0bd 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -165,7 +165,11 @@ impl<'a> SamplerMut for BlockGen<'a> { // Rocks let block = block.or_else(|| { if (height + 2.5 - wposf.z as f32).div(7.5).abs().powf(2.0) < rock { - Some(warm_stone) + let field0 = RandomField::new(self.world.sim().seed + 0); + let field1 = RandomField::new(self.world.sim().seed + 1); + let field2 = RandomField::new(self.world.sim().seed + 2); + + Some(Block::new(2, stone_col - Rgb::new(field0.get(wpos) as u8 % 32, field1.get(wpos) as u8 % 32, field2.get(wpos) as u8 % 32))) } else { None } From 451bbe9921f0600606010d007a2f6ac66baf8478 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 18 Jun 2019 22:22:31 +0100 Subject: [PATCH 04/40] Basic region generation --- voxygen/src/mesh/vol.rs | 2 +- voxygen/src/session.rs | 2 - world/examples/view.rs | 33 +++++++--- world/src/block/mod.rs | 3 +- world/src/column/mod.rs | 27 +++++--- world/src/lib.rs | 15 +++-- world/src/sim/location.rs | 28 +++++++-- world/src/sim/mod.rs | 127 +++++++++++++++++++++++++++++++++----- 8 files changed, 191 insertions(+), 46 deletions(-) diff --git a/voxygen/src/mesh/vol.rs b/voxygen/src/mesh/vol.rs index 50d66a9135..bb866297a6 100644 --- a/voxygen/src/mesh/vol.rs +++ b/voxygen/src/mesh/vol.rs @@ -41,7 +41,7 @@ fn get_ao_quad(vol: &V, pos: Vec3, shift: Vec3, dirs: &[Ve .unwrap_or(false); // Map both 1 and 2 neighbors to 0.5 occlusion. if s1 || s2 || corner { - 0.5 + 0.3 } else { 1.0 } diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 1c46ddd2a1..c78d8bf874 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -58,12 +58,10 @@ impl SessionState { } // TODO: Get rid of this when we're done with it (we're not yet) - /* match self.client.borrow().current_chunk() { Some(chunk) => println!("Chunk location: {:?}", chunk.meta().name()), None => {} } - */ Ok(()) } diff --git a/world/examples/view.rs b/world/examples/view.rs index e358924625..9fd167e327 100644 --- a/world/examples/view.rs +++ b/world/examples/view.rs @@ -15,35 +15,44 @@ fn main() { let mut focus = Vec2::zero(); let mut gain = 1.0; + let mut scale = 4; while win.is_open() { let mut buf = vec![0; W * H]; for i in 0..W { for j in 0..H { - let pos = focus + Vec2::new(i as i32, j as i32) * 4; + let pos = focus + Vec2::new(i as i32, j as i32) * scale; - let alt = sampler + let (alt, location) = sampler .get(pos) - .map(|sample| sample.alt.sub(64.0).add(gain).mul(0.7).max(0.0).min(255.0) as u8) - .unwrap_or(0); + .map(|sample| ( + sample.alt.sub(64.0).add(gain).mul(0.7).max(0.0).min(255.0) as u8, + sample.location, + )) + .unwrap_or((0, None)); - buf[j * W + i] = u32::from_le_bytes([alt; 4]); + let loc_color = location.map(|l| ( + l.name().bytes().nth(0).unwrap() * 17, + l.name().bytes().nth(1).unwrap() * 17, + )).unwrap_or((0, 0)); + + buf[j * W + i] = u32::from_le_bytes([loc_color.0, loc_color.1, alt, alt]); } } let spd = 32; if win.is_key_down(minifb::Key::W) { - focus.y -= spd; + focus.y -= spd * scale; } if win.is_key_down(minifb::Key::A) { - focus.x -= spd; + focus.x -= spd * scale; } if win.is_key_down(minifb::Key::S) { - focus.y += spd; + focus.y += spd * scale; } if win.is_key_down(minifb::Key::D) { - focus.x += spd; + focus.x += spd * scale; } if win.is_key_down(minifb::Key::Q) { gain += 10.0; @@ -51,6 +60,12 @@ fn main() { if win.is_key_down(minifb::Key::E) { gain -= 10.0; } + if win.is_key_down(minifb::Key::R) { + scale += 1; + } + if win.is_key_down(minifb::Key::F) { + scale -= 1; + } win.update_with_buffer(&buf).unwrap(); } diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 06c9ddc0bd..e4e2025783 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -15,7 +15,7 @@ use vek::*; pub struct BlockGen<'a> { world: &'a World, - column_cache: HashCache, Option>, + column_cache: HashCache, Option>>, column_gen: ColumnGen<'a>, } @@ -53,6 +53,7 @@ impl<'a> SamplerMut for BlockGen<'a> { rock, cliff, temp, + .. } = self.sample_column(Vec2::from(wpos))?; let wposf = wpos.map(|e| e as f64); diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 551267964c..41c9b4809b 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -1,10 +1,19 @@ -use crate::{all::ForestKind, util::Sampler, World, CONFIG}; +use crate::{ + all::ForestKind, + util::Sampler, + sim::Location, + World, + CONFIG, +}; use common::{ terrain::{Block, TerrainChunkSize}, vol::{VolSize, Vox}, }; use noise::NoiseFn; -use std::ops::{Add, Div, Mul, Neg, Sub}; +use std::{ + ops::{Add, Div, Mul, Neg, Sub}, + sync::Arc, +}; use vek::*; pub struct ColumnGen<'a> { @@ -19,12 +28,12 @@ impl<'a> ColumnGen<'a> { impl<'a> Sampler for ColumnGen<'a> { type Index = Vec2; - type Sample = Option; + type Sample = Option>; - fn get(&self, wpos: Vec2) -> Option { + fn get(&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 + e / sz as i32 }); let sim = self.world.sim(); @@ -36,7 +45,7 @@ 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 sim_chunk = sim.get(chunk_pos)?; let alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? + (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32) @@ -140,19 +149,20 @@ impl<'a> Sampler for ColumnGen<'a> { (alt - CONFIG.sea_level - 2.0) / 5.0, ), tree_density, - forest_kind, + forest_kind: sim_chunk.forest_kind, close_trees: sim.gen_ctx.tree_gen.get(wpos), cave_xy, cave_alt, rock, cliff: cliffiness, temp, + location: sim_chunk.location.as_ref(), }) } } #[derive(Clone)] -pub struct ColumnSample { +pub struct ColumnSample<'a> { pub alt: f32, pub chaos: f32, pub surface_color: Rgb, @@ -164,4 +174,5 @@ pub struct ColumnSample { pub rock: f32, pub cliff: f32, pub temp: f32, + pub location: Option<&'a Arc> } diff --git a/world/src/lib.rs b/world/src/lib.rs index e3528616c4..e2a0831fb1 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -4,7 +4,7 @@ mod all; mod block; mod column; pub mod config; -mod sim; +pub mod sim; pub mod util; // Reexports @@ -62,15 +62,20 @@ impl World { let water = Block::new(5, Rgb::new(100, 150, 255)); let chunk_size2d = Vec2::from(TerrainChunkSize::SIZE); - let base_z = match self.sim.get_interpolated( + let (base_z, sim_chunk) = match self.sim.get_interpolated( chunk_pos.map2(chunk_size2d, |e, sz: u32| e * sz as i32 + sz as i32 / 2), |chunk| chunk.get_base_z(), - ) { - Some(base_z) => base_z as i32, + ).and_then(|base_z| self.sim.get(chunk_pos).map(|sim_chunk| (base_z, sim_chunk))) { + Some((base_z, sim_chunk)) => (base_z as i32, sim_chunk), None => return TerrainChunk::new(0, water, air, TerrainChunkMeta::void()), }; - let mut chunk = TerrainChunk::new(base_z - 8, stone, air, TerrainChunkMeta::void()); + let meta = TerrainChunkMeta::new( + sim_chunk.get_name(), + sim_chunk.get_biome(), + ); + + let mut chunk = TerrainChunk::new(base_z - 8, stone, air, meta); let mut sampler = self.sample_blocks(); diff --git a/world/src/sim/location.rs b/world/src/sim/location.rs index 892e8e62a8..34eb7d02a3 100644 --- a/world/src/sim/location.rs +++ b/world/src/sim/location.rs @@ -1,17 +1,37 @@ use rand::Rng; +use vek::*; #[derive(Copy, Clone, Debug)] pub enum LocationKind { Settlement, - Mountain, - Forest, + Wildnerness, } #[derive(Clone, Debug)] pub struct Location { name: String, + center: Vec2, kind: LocationKind, - kingdom: Kingdom, + kingdom: Option, +} + +impl Location { + pub fn generate(center: Vec2, rng: &mut R) -> Self { + Self { + name: generate_name(rng), + center, + kind: LocationKind::Wildnerness, + kingdom: None, + } + } + + pub fn name(&self) -> &str { + &self.name + } + + pub fn kingdom(&self) -> Option<&Kingdom> { + self.kingdom.as_ref() + } } #[derive(Clone, Debug)] @@ -19,7 +39,7 @@ pub struct Kingdom { name: String, } -fn generate_name() -> String { +fn generate_name(rng: &mut R) -> 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", diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 501e95f5dd..6cb1241a97 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -1,14 +1,24 @@ mod location; -use self::location::Location; +// Reexports +pub use self::location::Location; + use crate::{all::ForestKind, util::StructureGen2d, CONFIG}; -use common::{terrain::TerrainChunkSize, vol::VolSize}; +use common::{ + terrain::{BiomeKind, TerrainChunkSize}, + vol::VolSize, +}; use noise::{BasicMulti, HybridMulti, MultiFractal, NoiseFn, RidgedMulti, Seedable, SuperSimplex}; use std::{ ops::{Add, Div, Mul, Neg, Sub}, sync::Arc, }; use vek::*; +use rand::{ + Rng, + SeedableRng, + prng::XorShiftRng, +}; pub const WORLD_SIZE: Vec2 = Vec2 { x: 1024, y: 1024 }; @@ -35,6 +45,7 @@ pub struct WorldSim { pub seed: u32, pub(crate) chunks: Vec, pub(crate) gen_ctx: GenCtx, + pub rng: XorShiftRng, } impl WorldSim { @@ -64,8 +75,8 @@ impl WorldSim { }; let mut chunks = Vec::new(); - for x in 0..WORLD_SIZE.x as u32 { - for y in 0..WORLD_SIZE.y as u32 { + for x in 0..WORLD_SIZE.x as i32 { + for y in 0..WORLD_SIZE.y as i32 { chunks.push(SimChunk::generate(Vec2::new(x, y), &mut gen_ctx)); } } @@ -74,20 +85,70 @@ impl WorldSim { seed, chunks, gen_ctx, + rng: XorShiftRng::from_seed([ + (seed >> 0) as u8, 0, 0, 0, + (seed >> 8) as u8, 0, 0, 0, + (seed >> 16) as u8, 0, 0, 0, + (seed >> 24) as u8, 0, 0, 0, + ]), }; - this.simulate(100); + this.seed_elements(); + this.simulate(200); this } - pub fn simulate(&mut self, cycles: usize) { - // TODO + /// Prepare the world for simulation + pub fn seed_elements(&mut self) { + let mut rng = self.rng.clone(); + + for _ in 0..250 { + let loc_center = Vec2::new( + self.rng.gen::() % WORLD_SIZE.x as i32, + self.rng.gen::() % WORLD_SIZE.y as i32, + ); + + if let Some(chunk) = self.get_mut(loc_center) { + chunk.location = Some(Location::generate(loc_center, &mut rng).into()); + } + } + + self.rng = rng; } - pub fn get(&self, chunk_pos: Vec2) -> Option<&SimChunk> { + pub fn simulate(&mut self, cycles: usize) { + let mut rng = self.rng.clone(); + + for _ in 0..cycles { + for i in 0..WORLD_SIZE.x as i32 { + for j in 0..WORLD_SIZE.y as i32 { + let pos = Vec2::new(i, j); + + let location = self.get(pos).unwrap().location.clone(); + + let rpos = Vec2::new( + rng.gen::(), + rng.gen::(), + ).map(|e| e.abs() % 3 - 1); + + if let Some(other) = &mut self.get_mut(pos + rpos) { + if other.location.is_none() + && rng.gen::() > other.chaos * 1.5 + && other.alt > CONFIG.sea_level { + other.location = location; + } + } + } + } + } + + self.rng = rng; + } + + pub fn get(&self, chunk_pos: Vec2) -> Option<&SimChunk> { if chunk_pos - .map2(WORLD_SIZE, |e, sz| e < sz as u32) + .map2(WORLD_SIZE, |e, sz| e >= 0 && e < sz as i32) .reduce_and() { Some(&self.chunks[chunk_pos.y as usize * WORLD_SIZE.x + chunk_pos.x as usize]) @@ -96,7 +157,18 @@ impl WorldSim { } } - pub fn get_base_z(&self, chunk_pos: Vec2) -> Option { + pub fn get_mut(&mut self, chunk_pos: Vec2) -> Option<&mut SimChunk> { + if chunk_pos + .map2(WORLD_SIZE, |e, sz| e >= 0 && e < sz as i32) + .reduce_and() + { + Some(&mut self.chunks[chunk_pos.y as usize * WORLD_SIZE.x + chunk_pos.x as usize]) + } else { + None + } + } + + pub fn get_base_z(&self, chunk_pos: Vec2) -> Option { self.get(chunk_pos).and_then(|_| { (0..2) .map(|i| (0..2).map(move |j| (i, j))) @@ -135,10 +207,10 @@ impl WorldSim { for (x_idx, j) in (-1..3).enumerate() { let y0 = - f(self.get(pos.map2(Vec2::new(j, -1), |e, q| (e.max(0.0) as i32 + q) as u32))?); - let y1 = f(self.get(pos.map2(Vec2::new(j, 0), |e, q| (e.max(0.0) as i32 + q) as u32))?); - let y2 = f(self.get(pos.map2(Vec2::new(j, 1), |e, q| (e.max(0.0) as i32 + q) as u32))?); - let y3 = f(self.get(pos.map2(Vec2::new(j, 2), |e, q| (e.max(0.0) as i32 + q) as u32))?); + f(self.get(pos.map2(Vec2::new(j, -1), |e, q| e.max(0.0) as i32 + q))?); + let y1 = f(self.get(pos.map2(Vec2::new(j, 0), |e, q| e.max(0.0) as i32 + q))?); + let y2 = f(self.get(pos.map2(Vec2::new(j, 1), |e, q| e.max(0.0) as i32 + q))?); + let y3 = f(self.get(pos.map2(Vec2::new(j, 2), |e, q| e.max(0.0) as i32 + q))?); x[x_idx] = cubic(y0, y1, y2, y3, pos.y.fract() as f32); } @@ -162,8 +234,8 @@ pub struct SimChunk { } impl SimChunk { - fn generate(pos: Vec2, gen_ctx: &mut GenCtx) -> Self { - let wposf = (pos * Vec2::from(TerrainChunkSize::SIZE)).map(|e| e as f64); + fn generate(pos: Vec2, gen_ctx: &mut GenCtx) -> Self { + let wposf = (pos * TerrainChunkSize::SIZE.map(|e| e as i32)).map(|e| e as f64); let hill = (0.0 + gen_ctx @@ -180,6 +252,7 @@ impl SimChunk { let chaos = (gen_ctx.chaos_nz.get((wposf.div(4_000.0)).into_array()) as f32) .add(1.0) .mul(0.5) + .mul((gen_ctx.chaos_nz.get((wposf.div(8_000.0)).into_array()) as f32).powf(2.0).add(0.5).min(1.0)) .powf(1.4) .add(0.1 * hill); @@ -263,4 +336,26 @@ impl SimChunk { pub fn get_max_z(&self) -> f32 { (self.alt + Z_TOLERANCE.1).max(CONFIG.sea_level + 1.0) } + + pub fn get_name(&self) -> Option { + self.location + .as_ref() + .map(|l| l.name().to_string()) + } + + pub fn get_biome(&self) -> BiomeKind { + if self.alt < CONFIG.sea_level { + BiomeKind::Ocean + } else if self.chaos > 0.6 { + BiomeKind::Mountain + } else if self.temp > CONFIG.desert_temp { + BiomeKind::Desert + } else if self.temp < CONFIG.snow_temp { + BiomeKind::Snowlands + } else if self.tree_density > 0.65 { + BiomeKind::Forest + } else { + BiomeKind::Grassland + } + } } From d10ef375289efd0020440d201c4610184ad2ad96 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 18 Jun 2019 22:37:48 +0100 Subject: [PATCH 05/40] Fixed AO lighting issue --- voxygen/src/mesh/segment.rs | 2 +- voxygen/src/mesh/terrain.rs | 2 +- voxygen/src/mesh/vol.rs | 33 +++++++++++++++++++-------------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs index 3ef53159f5..aba4d187cf 100644 --- a/voxygen/src/mesh/segment.rs +++ b/voxygen/src/mesh/segment.rs @@ -27,7 +27,7 @@ impl Meshable for Segment { pos, offs + pos.map(|e| e as f32), col, - |origin, norm, col, light| FigureVertex::new(origin, norm, col * light, 0), + |origin, norm, col, ao, light| FigureVertex::new(origin, norm, col * ao * light, 0), true, &[[[1.0; 3]; 3]; 3], ); diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index e299f9635f..8b4bd913e3 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -106,7 +106,7 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for pos, offs, col, - |pos, norm, col, light| TerrainVertex::new(pos, norm, col, light), + |pos, norm, col, ao, light| TerrainVertex::new(pos, norm, col * ao, light), false, &neighbour_light, ); diff --git a/voxygen/src/mesh/vol.rs b/voxygen/src/mesh/vol.rs index bb866297a6..0effa4f4b9 100644 --- a/voxygen/src/mesh/vol.rs +++ b/voxygen/src/mesh/vol.rs @@ -10,7 +10,7 @@ use crate::render::{ /// Given volume, position, and cardinal directions, compute each vertex's AO value. /// `dirs` should be a slice of length 5 so that the sliding window of size 2 over the slice /// yields each vertex' adjacent positions. -fn get_ao_quad(vol: &V, pos: Vec3, shift: Vec3, dirs: &[Vec3], corners: &[[usize; 3]; 4], darknesses: &[[[f32; 3]; 3]; 3]) -> Vec4 { +fn get_ao_quad(vol: &V, pos: Vec3, shift: Vec3, dirs: &[Vec3], corners: &[[usize; 3]; 4], darknesses: &[[[f32; 3]; 3]; 3]) -> Vec4<(f32, f32)> { dirs.windows(2) .enumerate() .map(|(i, offs)| { @@ -32,7 +32,7 @@ fn get_ao_quad(vol: &V, pos: Vec3, shift: Vec3, dirs: &[Ve .flatten() .fold(0.0, |a: f32, x| a.max(*x)); - darkness * if s1 && s2 { + (darkness, if s1 && s2 { 0.0 } else { let corner = vol @@ -41,53 +41,58 @@ fn get_ao_quad(vol: &V, pos: Vec3, shift: Vec3, dirs: &[Ve .unwrap_or(false); // Map both 1 and 2 neighbors to 0.5 occlusion. if s1 || s2 || corner { - 0.3 + 0.5 } else { 1.0 } - } + }) }) - .collect::>() + .collect::>() } // Utility function -fn create_quad, Vec3, Rgb, f32) -> P::Vertex>( +fn create_quad, Vec3, Rgb, f32, f32) -> P::Vertex>( origin: Vec3, unit_x: Vec3, unit_y: Vec3, norm: Vec3, col: Rgb, - ao: Vec4, + darkness_ao: Vec4<(f32, f32)>, vcons: &F, ) -> Quad

{ let ao_scale = 0.95; let dark = col * (1.0 - ao_scale); + let darkness = darkness_ao.map(|e| e.0); + let ao = darkness_ao.map(|e| e.1); + let ao_map = ao;//ao.map(|e| 0.2 + e.powf(1.0) * 0.8); if ao[0].min(ao[2]) < ao[1].min(ao[3]) { Quad::new( - vcons(origin + unit_y, norm, col, ao_map[3]), - vcons(origin, norm, col, ao_map[0]), - vcons(origin + unit_x, norm, col, ao_map[1]), + vcons(origin + unit_y, norm, col, darkness[3], ao_map[3]), + vcons(origin, norm, col, darkness[0], ao_map[0]), + vcons(origin + unit_x, norm, col, darkness[1], ao_map[1]), vcons( origin + unit_x + unit_y, norm, col, + darkness[2], ao_map[2], ), ) } else { Quad::new( - vcons(origin, norm, col, ao_map[0]), - vcons(origin + unit_x, norm, col, ao_map[1]), + vcons(origin, norm, col, darkness[0], ao_map[0]), + vcons(origin + unit_x, norm, col, darkness[1], ao_map[1]), vcons( origin + unit_x + unit_y, norm, col, + darkness[2], ao_map[2], ), - vcons(origin + unit_y, norm, col, ao_map[3]), + vcons(origin + unit_y, norm, col, darkness[3], ao_map[3]), ) } } @@ -95,7 +100,7 @@ fn create_quad, Vec3, Rgb, f32) -> P::Ver pub fn push_vox_verts< V: ReadVol, P: Pipeline, - F: Fn(Vec3, Vec3, Rgb, f32) -> P::Vertex, + F: Fn(Vec3, Vec3, Rgb, f32, f32) -> P::Vertex, >( mesh: &mut Mesh

, vol: &V, From 5e96e29ff10b36e3ddf13e56de989030869866a0 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Wed, 19 Jun 2019 00:59:40 +0100 Subject: [PATCH 06/40] AO improvements, day/night cycle --- voxygen/shaders/figure.frag | 9 ++--- voxygen/shaders/include/sky.glsl | 62 ++++++++++++++++++++++++-------- voxygen/shaders/terrain.frag | 14 +------- voxygen/src/mesh/terrain.rs | 58 +++++++++++++++--------------- voxygen/src/mesh/vol.rs | 2 +- world/src/sim/location.rs | 10 +++--- 6 files changed, 85 insertions(+), 70 deletions(-) diff --git a/voxygen/shaders/figure.frag b/voxygen/shaders/figure.frag index 36dd375a00..d5b8648ebd 100644 --- a/voxygen/shaders/figure.frag +++ b/voxygen/shaders/figure.frag @@ -32,13 +32,8 @@ void main() { vec4(f_norm, 0.0) ).xyz; - float ambient = 0.5; - - vec3 sun_dir = normalize(vec3(1.3, 1.7, 1.1)); - - float sun_diffuse = dot(sun_dir, world_norm) * 0.5; - - vec3 surf_color = model_col.rgb * f_col * (ambient + sun_diffuse); + float light = get_sun_diffuse(world_norm, time_of_day.x); + vec3 surf_color = model_col.rgb * f_col * 2.0 * light; float fog_level = fog(f_pos.xy, focus_pos.xy); vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x); diff --git a/voxygen/shaders/include/sky.glsl b/voxygen/shaders/include/sky.glsl index 4c917ca47a..96aa7ee38a 100644 --- a/voxygen/shaders/include/sky.glsl +++ b/voxygen/shaders/include/sky.glsl @@ -26,41 +26,73 @@ float noise(vec3 p){ return o4.y * d.y + o4.x * (1.0 - d.y); } +vec3 get_sun_dir(float time_of_day) { + const float TIME_FACTOR = (PI * 2.0) / (3600.0 * 24.0); + + float sun_angle_rad = time_of_day * TIME_FACTOR; + vec3 sun_dir = vec3(sin(sun_angle_rad), 0.0, cos(sun_angle_rad)); + + return sun_dir; +} + +float get_sun_brightness(vec3 sun_dir) { + return max(-sun_dir.z, 0.0); +} + +const float PERSISTENT_AMBIANCE = 0.015; + +float get_sun_diffuse(vec3 norm, float time_of_day) { + const float SUN_AMBIANCE = 0.2; + + vec3 sun_dir = get_sun_dir(time_of_day); + + float sun_light = get_sun_brightness(sun_dir); + + return (SUN_AMBIANCE + max(dot(-norm, sun_dir), 0.0)) * sun_light + PERSISTENT_AMBIANCE; +} + vec3 get_sky_color(vec3 dir, float time_of_day) { bool objects = true; - const float TIME_FACTOR = (PI * 2.0) / (3600.0 * 24.0); - vec2 pos2d = dir.xy / dir.z; const vec3 SKY_TOP = vec3(0.2, 0.3, 0.9); const vec3 SKY_MIDDLE = vec3(0.1, 0.15, 0.7); const vec3 SKY_BOTTOM = vec3(0.025, 0.15, 0.35); - const vec3 SUN_HALO_COLOR = vec3(1.0, 0.7, 0.5) * 0.5; + const vec3 SUN_HALO_COLOR = vec3(1.0, 0.4, 0.3) * 0.5; const vec3 SUN_SURF_COLOR = vec3(1.0, 0.9, 0.35) * 200.0; - float sun_angle_rad = time_of_day * TIME_FACTOR; - vec3 sun_dir = vec3(sin(sun_angle_rad), 0.0, cos(sun_angle_rad)); + vec3 sun_dir = get_sun_dir(time_of_day); + float sky_brightness = get_sun_brightness(sun_dir); - vec3 sun_halo = pow(max(dot(dir, sun_dir), 0.0), 8.0) * SUN_HALO_COLOR; - vec3 sun_surf = pow(max(dot(dir, sun_dir) - 0.0045, 0.0), 1000.0) * SUN_SURF_COLOR; + vec3 sun_halo = pow(max(dot(dir, -sun_dir) + 0.1, 0.0), 8.0) * SUN_HALO_COLOR; + vec3 sun_surf = pow(max(dot(dir, -sun_dir) - 0.0045, 0.0), 1000.0) * SUN_SURF_COLOR; vec3 sun_light = sun_halo + sun_surf; - vec3 sky_top; + float brightess = (sky_brightness + PERSISTENT_AMBIANCE); + + vec3 sky_top = SKY_TOP * brightess; if (objects) { - vec3 p = vec3(pos2d + time_of_day * 0.0002, time_of_day * 0.0001); - sky_top = mix(SKY_TOP, vec3(1), pow(noise(p) * 0.8 + noise(p * 3.0) * 0.2, 2.5) * 3.0); - } else { - sky_top = SKY_TOP; + // Clouds + // vec3 p = vec3(pos2d + time_of_day * 0.0002, time_of_day * 0.00003); + // sky_top = mix(sky_top, vec3(1) * brightess, pow(noise(p) * 0.8 + noise(p * 3.0) * 0.2, 2.5) * 3.0); } - vec3 sky_color = mix(mix(SKY_MIDDLE, sky_top, clamp(dir.z, 0, 1)), SKY_BOTTOM, clamp(-dir.z * 5.0, 0, 1)); - if (objects) { - sky_color += sun_light; + sky_top += sun_light; } + vec3 sky_color = mix( + mix( + SKY_MIDDLE * brightess, + sky_top, + clamp(dir.z * 3.0, 0, 1) + ), + SKY_BOTTOM * brightess, + clamp(-dir.z * 3.0, 0, 1) + ); + return sky_color; } diff --git a/voxygen/shaders/terrain.frag b/voxygen/shaders/terrain.frag index e3d350f924..9620347fe2 100644 --- a/voxygen/shaders/terrain.frag +++ b/voxygen/shaders/terrain.frag @@ -28,19 +28,7 @@ void main() { f_norm = vec3(0.0, 0.0, 1.0) * norm_dir; } - float glob_ambience = 0.0005; - - float sun_ambience = 0.3; - - vec3 sun_dir = normalize(vec3(0.7, 1.3, 2.1)); - - float sun_diffuse = max(dot(sun_dir, f_norm), 0.0); - float sun_light = sun_ambience + sun_diffuse; - - float static_light = glob_ambience + min(sun_light, f_light); - - vec3 light = vec3(static_light); - + float light = get_sun_diffuse(f_norm, time_of_day.x) * f_light; vec3 surf_color = f_col * light; float fog_level = fog(f_pos.xy, focus_pos.xy); diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index 8b4bd913e3..9597aba4eb 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -56,6 +56,35 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for for z in (range.min.z..range.max.z).rev() { let pos = Vec3::new(x, y, z); + // Create mesh polygons + if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) { + let avg_light = neighbour_light + .iter() + .map(|row| row.iter()) + .flatten() + .map(|col| col.iter()) + .flatten() + .fold(0.0, |a, x| a + x) + / 27.0; + let light = avg_light; + + let col = col.map(|e| e as f32 / 255.0); + + let offs = (pos - range.min * Vec3::new(1, 1, 0)).map(|e| e as f32) + - Vec3::new(1.0, 1.0, 0.0); + + vol::push_vox_verts( + &mut mesh, + self, + pos, + offs, + col, + |pos, norm, col, ao, light| TerrainVertex::new(pos, norm, Lerp::lerp(Rgb::zero(), col, ao), light), + false, + &neighbour_light, + ); + } + // Shift lighting neighbour_light[2] = neighbour_light[1]; neighbour_light[1] = neighbour_light[0]; @@ -82,35 +111,6 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for .flatten() .copied() .fold(0.0, |a, x| a + x) / 9.0; 3]; 3]; - - // Create mesh polygons - if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) { - let avg_light = neighbour_light - .iter() - .map(|row| row.iter()) - .flatten() - .map(|col| col.iter()) - .flatten() - .fold(0.0, |a, x| a + x) - / 27.0; - let light = avg_light; - - let col = col.map(|e| e as f32 / 255.0); - - let offs = (pos - range.min * Vec3::new(1, 1, 0)).map(|e| e as f32) - - Vec3::new(1.0, 1.0, 0.0); - - vol::push_vox_verts( - &mut mesh, - self, - pos, - offs, - col, - |pos, norm, col, ao, light| TerrainVertex::new(pos, norm, col * ao, light), - false, - &neighbour_light, - ); - } } } } diff --git a/voxygen/src/mesh/vol.rs b/voxygen/src/mesh/vol.rs index 0effa4f4b9..1b36e05c4e 100644 --- a/voxygen/src/mesh/vol.rs +++ b/voxygen/src/mesh/vol.rs @@ -66,7 +66,7 @@ fn create_quad, Vec3, Rgb, f32, f32) -> P let darkness = darkness_ao.map(|e| e.0); let ao = darkness_ao.map(|e| e.1); - let ao_map = ao;//ao.map(|e| 0.2 + e.powf(1.0) * 0.8); + let ao_map = ao.map(|e| 0.05 + e.powf(1.6) * 0.95); if ao[0].min(ao[2]) < ao[1].min(ao[3]) { Quad::new( diff --git a/world/src/sim/location.rs b/world/src/sim/location.rs index 34eb7d02a3..cea228a4f8 100644 --- a/world/src/sim/location.rs +++ b/world/src/sim/location.rs @@ -55,12 +55,12 @@ fn generate_name(rng: &mut R) -> String { ]; 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(); + for i in 0..rng.gen::() % 2 { + name += rng.choose(&consts).unwrap(); + name += rng.choose(&vowels).unwrap(); } - name += rand::thread_rng().choose(&consts).unwrap(); - name += rand::thread_rng().choose(&tails).unwrap(); + name += rng.choose(&consts).unwrap(); + name += rng.choose(&tails).unwrap(); name } From 04893338cd74efa24ed4c86eaa2d43a11712a96d Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Wed, 19 Jun 2019 01:15:43 +0100 Subject: [PATCH 07/40] Lowered horizon --- voxygen/shaders/include/sky.glsl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/voxygen/shaders/include/sky.glsl b/voxygen/shaders/include/sky.glsl index 96aa7ee38a..c7402333b3 100644 --- a/voxygen/shaders/include/sky.glsl +++ b/voxygen/shaders/include/sky.glsl @@ -73,6 +73,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day) { float brightess = (sky_brightness + PERSISTENT_AMBIANCE); vec3 sky_top = SKY_TOP * brightess; + vec3 sky_middle = SKY_MIDDLE * brightess; if (objects) { // Clouds // vec3 p = vec3(pos2d + time_of_day * 0.0002, time_of_day * 0.00003); @@ -81,13 +82,14 @@ vec3 get_sky_color(vec3 dir, float time_of_day) { if (objects) { sky_top += sun_light; + sky_middle += sun_light; } vec3 sky_color = mix( mix( - SKY_MIDDLE * brightess, + sky_middle, sky_top, - clamp(dir.z * 3.0, 0, 1) + clamp(dir.z * 1.0, 0, 1) ), SKY_BOTTOM * brightess, clamp(-dir.z * 3.0, 0, 1) From 60f8a295305e94b5b2e97c90fe97f66bb1d78323 Mon Sep 17 00:00:00 2001 From: Pfauenauge90 <44173739+Pfauenauge90@users.noreply.github.com> Date: Wed, 19 Jun 2019 11:05:03 +0200 Subject: [PATCH 08/40] Better sylables, changed generation rules --- world/src/sim/location.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/world/src/sim/location.rs b/world/src/sim/location.rs index cea228a4f8..bb520e3361 100644 --- a/world/src/sim/location.rs +++ b/world/src/sim/location.rs @@ -40,26 +40,26 @@ pub struct Kingdom { } fn generate_name(rng: &mut R) -> 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 firstsyl = [ + "Eri", "Val", "Gla", "Wilde", "Cold", "Deep", "Dura", "Ester", "Fay", "Dark", "West", + "East", "North", "South", "Ray", "Eri", "Dal", "Som", "Black", "Iron", "Grey", "Hel", + "Gal", "Mor", "Lo", "Nil", "Mana", "Gar", "Mountain", ]; + let mid = ["o", "oa", "au", "e", "ea", "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", + "mill", "ben", "sel", "dori", "theas", "dar", "bur", "to", "vis", "ten", "stone", "tiva", + "id", "and", "or", "el", "ond", "ia", "eld", "ald", "aft", "ift", "ity", "well", "oll", + "ill", "all", "wyn", "light", "hill", "lin", "mont", "mor", "cliff", "rok", "den", "mi", + "rock", "glenn", "rovi", "lea", "gate", "view", "ley", "wood", "ovia", "cliff", "marsh", + "kor", "light", "ice", "river", "venn", "vale", ]; let mut name = String::new(); - for i in 0..rng.gen::() % 2 { - name += rng.choose(&consts).unwrap(); - name += rng.choose(&vowels).unwrap(); - } - name += rng.choose(&consts).unwrap(); + /*for i in 0..rng.gen::() % 1 { + name += rng.choose(&firstsyl).unwrap(); + }*/ + name += rng.choose(&firstsyl).unwrap(); + //name += rng.choose(&mid).unwrap(); name += rng.choose(&tails).unwrap(); name From ab2c0ad0856b406df85e847ed565713b338a6103 Mon Sep 17 00:00:00 2001 From: Pfauenauge90 <44173739+Pfauenauge90@users.noreply.github.com> Date: Wed, 19 Jun 2019 11:38:20 +0200 Subject: [PATCH 09/40] mid name parts --- voxygen/src/hud/minimap.rs | 2 +- world/src/sim/location.rs | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index d7eee449a5..d9512e124f 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -104,7 +104,7 @@ impl<'a> Widget for MiniMap<'a> { // Title // TODO: Make it display the actual location. - Text::new("Uncanny Valley") + Text::new("Region Name") .mid_top_with_margin_on(state.ids.mmap_frame, 3.0) .font_size(14) .color(TEXT_COLOR) diff --git a/world/src/sim/location.rs b/world/src/sim/location.rs index bb520e3361..597420b737 100644 --- a/world/src/sim/location.rs +++ b/world/src/sim/location.rs @@ -36,7 +36,7 @@ impl Location { #[derive(Clone, Debug)] pub struct Kingdom { - name: String, + region_name: String, } fn generate_name(rng: &mut R) -> String { @@ -45,7 +45,7 @@ fn generate_name(rng: &mut R) -> String { "East", "North", "South", "Ray", "Eri", "Dal", "Som", "Black", "Iron", "Grey", "Hel", "Gal", "Mor", "Lo", "Nil", "Mana", "Gar", "Mountain", ]; - let mid = ["o", "oa", "au", "e", "ea", "u", "a", "i", "ie"]; + let mid = ["ka", "se", "au", "da", "di", "u"]; let tails = [ "mill", "ben", "sel", "dori", "theas", "dar", "bur", "to", "vis", "ten", "stone", "tiva", "id", "and", "or", "el", "ond", "ia", "eld", "ald", "aft", "ift", "ity", "well", "oll", @@ -55,12 +55,14 @@ fn generate_name(rng: &mut R) -> String { ]; let mut name = String::new(); - /*for i in 0..rng.gen::() % 1 { + if rand::random() { name += rng.choose(&firstsyl).unwrap(); - }*/ - name += rng.choose(&firstsyl).unwrap(); - //name += rng.choose(&mid).unwrap(); - name += rng.choose(&tails).unwrap(); - - name + name += rng.choose(&mid).unwrap(); + name += rng.choose(&tails).unwrap(); + name + } else { + name += rng.choose(&firstsyl).unwrap(); + name += rng.choose(&tails).unwrap(); + name + } } From 4644199f1b5217d4f36453d6d12d321055f194b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Korg=C3=B3l?= Date: Wed, 19 Jun 2019 16:55:26 +0200 Subject: [PATCH 10/40] Make minimap title show location names --- voxygen/src/hud/minimap.rs | 26 ++++++--- voxygen/src/hud/mod.rs | 5 +- voxygen/src/mesh/segment.rs | 4 +- voxygen/src/mesh/terrain.rs | 15 ++++- voxygen/src/mesh/vol.rs | 108 ++++++++++++++++++++++++------------ world/examples/view.rs | 22 +++++--- world/src/block/mod.rs | 10 +++- world/src/column/mod.rs | 10 +--- world/src/lib.rs | 17 +++--- world/src/sim/mod.rs | 49 +++++++++------- 10 files changed, 175 insertions(+), 91 deletions(-) diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index d9512e124f..b5af29d57e 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -5,6 +5,9 @@ use conrod_core::{ }; use super::{img_ids::Imgs, Fonts, Show, TEXT_COLOR}; +use client::{self, Client}; + +use std::{cell::RefCell, rc::Rc}; widget_ids! { struct Ids { @@ -19,6 +22,8 @@ widget_ids! { pub struct MiniMap<'a> { show: &'a Show, + client: &'a Client, + imgs: &'a Imgs, fonts: &'a Fonts, @@ -27,9 +32,10 @@ pub struct MiniMap<'a> { } impl<'a> MiniMap<'a> { - pub fn new(show: &'a Show, imgs: &'a Imgs, fonts: &'a Fonts) -> Self { + pub fn new(show: &'a Show, client: &'a Client, imgs: &'a Imgs, fonts: &'a Fonts) -> Self { Self { show, + client, imgs, fonts, common: widget::CommonBuilder::default(), @@ -103,12 +109,18 @@ impl<'a> Widget for MiniMap<'a> { } // Title - // TODO: Make it display the actual location. - Text::new("Region Name") - .mid_top_with_margin_on(state.ids.mmap_frame, 3.0) - .font_size(14) - .color(TEXT_COLOR) - .set(state.ids.mmap_location, ui); + match self.client.current_chunk() { + Some(chunk) => Text::new(chunk.meta().name()) + .mid_top_with_margin_on(state.ids.mmap_frame, 3.0) + .font_size(14) + .color(TEXT_COLOR) + .set(state.ids.mmap_location, ui), + None => Text::new("Wait what") + .mid_top_with_margin_on(state.ids.mmap_frame, 3.0) + .font_size(14) + .color(TEXT_COLOR) + .set(state.ids.mmap_location, ui), + } None } diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 9dfaf90800..0349c4bc6a 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -38,6 +38,7 @@ use conrod_core::{ }; use specs::Join; use std::collections::VecDeque; +use std::{cell::RefCell, rc::Rc}; use vek::*; const XP_COLOR: Color = Color::Rgba(0.59, 0.41, 0.67, 1.0); @@ -522,7 +523,9 @@ impl Hud { } // MiniMap - match MiniMap::new(&self.show, &self.imgs, &self.fonts).set(self.ids.minimap, ui_widgets) { + match MiniMap::new(&self.show, client, &self.imgs, &self.fonts) + .set(self.ids.minimap, ui_widgets) + { Some(minimap::Event::Toggle) => self.show.toggle_mini_map(), None => {} } diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs index aba4d187cf..7ab8555f2c 100644 --- a/voxygen/src/mesh/segment.rs +++ b/voxygen/src/mesh/segment.rs @@ -27,7 +27,9 @@ impl Meshable for Segment { pos, offs + pos.map(|e| e as f32), col, - |origin, norm, col, ao, light| FigureVertex::new(origin, norm, col * ao * light, 0), + |origin, norm, col, ao, light| { + FigureVertex::new(origin, norm, col * ao * light, 0) + }, true, &[[[1.0; 3]; 3]; 3], ); diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index 9597aba4eb..494e368591 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -79,7 +79,14 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for pos, offs, col, - |pos, norm, col, ao, light| TerrainVertex::new(pos, norm, Lerp::lerp(Rgb::zero(), col, ao), light), + |pos, norm, col, ao, light| { + TerrainVertex::new( + pos, + norm, + Lerp::lerp(Rgb::zero(), col, ao), + light, + ) + }, false, &neighbour_light, ); @@ -97,7 +104,8 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for .ok() .and_then(|vox| vox.get_opacity()) { - (neighbour_light[0][i][j] * (1.0 - opacity * 0.2)).max(1.0 - opacity * 1.0) + (neighbour_light[0][i][j] * (1.0 - opacity * 0.2)) + .max(1.0 - opacity * 1.0) } else { (neighbour_light[0][i][j] * 1.035).min(1.0) }; @@ -110,7 +118,8 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for .map(|col| col.iter()) .flatten() .copied() - .fold(0.0, |a, x| a + x) / 9.0; 3]; 3]; + .fold(0.0, |a, x| a + x) + / 9.0; 3]; 3]; } } } diff --git a/voxygen/src/mesh/vol.rs b/voxygen/src/mesh/vol.rs index 1b36e05c4e..563a520e15 100644 --- a/voxygen/src/mesh/vol.rs +++ b/voxygen/src/mesh/vol.rs @@ -10,7 +10,14 @@ use crate::render::{ /// Given volume, position, and cardinal directions, compute each vertex's AO value. /// `dirs` should be a slice of length 5 so that the sliding window of size 2 over the slice /// yields each vertex' adjacent positions. -fn get_ao_quad(vol: &V, pos: Vec3, shift: Vec3, dirs: &[Vec3], corners: &[[usize; 3]; 4], darknesses: &[[[f32; 3]; 3]; 3]) -> Vec4<(f32, f32)> { +fn get_ao_quad( + vol: &V, + pos: Vec3, + shift: Vec3, + dirs: &[Vec3], + corners: &[[usize; 3]; 4], + darknesses: &[[[f32; 3]; 3]; 3], +) -> Vec4<(f32, f32)> { dirs.windows(2) .enumerate() .map(|(i, offs)| { @@ -32,20 +39,23 @@ fn get_ao_quad(vol: &V, pos: Vec3, shift: Vec3, dirs: &[Ve .flatten() .fold(0.0, |a: f32, x| a.max(*x)); - (darkness, if s1 && s2 { - 0.0 - } else { - let corner = vol - .get(pos + shift + offs[0] + offs[1]) - .map(|v| !v.is_empty()) - .unwrap_or(false); - // Map both 1 and 2 neighbors to 0.5 occlusion. - if s1 || s2 || corner { - 0.5 + ( + darkness, + if s1 && s2 { + 0.0 } else { - 1.0 - } - }) + let corner = vol + .get(pos + shift + offs[0] + offs[1]) + .map(|v| !v.is_empty()) + .unwrap_or(false); + // Map both 1 and 2 neighbors to 0.5 occlusion. + if s1 || s2 || corner { + 0.5 + } else { + 1.0 + } + }, + ) }) .collect::>() } @@ -73,25 +83,13 @@ fn create_quad, Vec3, Rgb, f32, f32) -> P vcons(origin + unit_y, norm, col, darkness[3], ao_map[3]), vcons(origin, norm, col, darkness[0], ao_map[0]), vcons(origin + unit_x, norm, col, darkness[1], ao_map[1]), - vcons( - origin + unit_x + unit_y, - norm, - col, - darkness[2], - ao_map[2], - ), + vcons(origin + unit_x + unit_y, norm, col, darkness[2], ao_map[2]), ) } else { Quad::new( vcons(origin, norm, col, darkness[0], ao_map[0]), vcons(origin + unit_x, norm, col, darkness[1], ao_map[1]), - vcons( - origin + unit_x + unit_y, - norm, - col, - darkness[2], - ao_map[2], - ), + vcons(origin + unit_x + unit_y, norm, col, darkness[2], ao_map[2]), vcons(origin + unit_y, norm, col, darkness[3], ao_map[3]), ) } @@ -125,7 +123,14 @@ pub fn push_vox_verts< Vec3::unit_y(), -Vec3::unit_x(), col, - get_ao_quad(vol, pos, -Vec3::unit_x(), &[-z, -y, z, y, -z], &[[0; 3]; 4], darknesses), + get_ao_quad( + vol, + pos, + -Vec3::unit_x(), + &[-z, -y, z, y, -z], + &[[0; 3]; 4], + darknesses, + ), &vcons, )); } @@ -141,7 +146,14 @@ pub fn push_vox_verts< Vec3::unit_z(), Vec3::unit_x(), col, - get_ao_quad(vol, pos, Vec3::unit_x(), &[-y, -z, y, z, -y], &[[0; 3]; 4], darknesses), + get_ao_quad( + vol, + pos, + Vec3::unit_x(), + &[-y, -z, y, z, -y], + &[[0; 3]; 4], + darknesses, + ), &vcons, )); } @@ -157,7 +169,14 @@ pub fn push_vox_verts< Vec3::unit_z(), -Vec3::unit_y(), col, - get_ao_quad(vol, pos, -Vec3::unit_y(), &[-x, -z, x, z, -x], &[[0; 3]; 4], darknesses), + get_ao_quad( + vol, + pos, + -Vec3::unit_y(), + &[-x, -z, x, z, -x], + &[[0; 3]; 4], + darknesses, + ), &vcons, )); } @@ -173,7 +192,14 @@ pub fn push_vox_verts< Vec3::unit_x(), Vec3::unit_y(), col, - get_ao_quad(vol, pos, Vec3::unit_y(), &[-z, -x, z, x, -z], &[[0; 3]; 4], darknesses), + get_ao_quad( + vol, + pos, + Vec3::unit_y(), + &[-z, -x, z, x, -z], + &[[0; 3]; 4], + darknesses, + ), &vcons, )); } @@ -189,7 +215,14 @@ pub fn push_vox_verts< Vec3::unit_x(), -Vec3::unit_z(), col, - get_ao_quad(vol, pos, -Vec3::unit_z(), &[-y, -x, y, x, -y], &[[0; 3]; 4], darknesses), + get_ao_quad( + vol, + pos, + -Vec3::unit_z(), + &[-y, -x, y, x, -y], + &[[0; 3]; 4], + darknesses, + ), &vcons, )); } @@ -205,7 +238,14 @@ pub fn push_vox_verts< Vec3::unit_y(), Vec3::unit_z(), col, - get_ao_quad(vol, pos, Vec3::unit_z(), &[-x, -y, x, y, -x], &[[0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]], darknesses), + get_ao_quad( + vol, + pos, + Vec3::unit_z(), + &[-x, -y, x, y, -x], + &[[0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]], + darknesses, + ), &vcons, )); } diff --git a/world/examples/view.rs b/world/examples/view.rs index 9fd167e327..61b100e140 100644 --- a/world/examples/view.rs +++ b/world/examples/view.rs @@ -26,16 +26,22 @@ fn main() { let (alt, location) = sampler .get(pos) - .map(|sample| ( - sample.alt.sub(64.0).add(gain).mul(0.7).max(0.0).min(255.0) as u8, - sample.location, - )) + .map(|sample| { + ( + sample.alt.sub(64.0).add(gain).mul(0.7).max(0.0).min(255.0) as u8, + sample.location, + ) + }) .unwrap_or((0, None)); - let loc_color = location.map(|l| ( - l.name().bytes().nth(0).unwrap() * 17, - l.name().bytes().nth(1).unwrap() * 17, - )).unwrap_or((0, 0)); + let loc_color = location + .map(|l| { + ( + l.name().bytes().nth(0).unwrap() * 17, + l.name().bytes().nth(1).unwrap() * 17, + ) + }) + .unwrap_or((0, 0)); buf[j * W + i] = u32::from_le_bytes([loc_color.0, loc_color.1, alt, alt]); } diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index e4e2025783..e253ec43b1 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -170,7 +170,15 @@ impl<'a> SamplerMut for BlockGen<'a> { let field1 = RandomField::new(self.world.sim().seed + 1); let field2 = RandomField::new(self.world.sim().seed + 2); - Some(Block::new(2, stone_col - Rgb::new(field0.get(wpos) as u8 % 32, field1.get(wpos) as u8 % 32, field2.get(wpos) as u8 % 32))) + Some(Block::new( + 2, + stone_col + - Rgb::new( + field0.get(wpos) as u8 % 32, + field1.get(wpos) as u8 % 32, + field2.get(wpos) as u8 % 32, + ), + )) } else { None } diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 41c9b4809b..755e57c3b6 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -1,10 +1,4 @@ -use crate::{ - all::ForestKind, - util::Sampler, - sim::Location, - World, - CONFIG, -}; +use crate::{all::ForestKind, sim::Location, util::Sampler, World, CONFIG}; use common::{ terrain::{Block, TerrainChunkSize}, vol::{VolSize, Vox}, @@ -174,5 +168,5 @@ pub struct ColumnSample<'a> { pub rock: f32, pub cliff: f32, pub temp: f32, - pub location: Option<&'a Arc> + pub location: Option<&'a Arc>, } diff --git a/world/src/lib.rs b/world/src/lib.rs index e2a0831fb1..5c4a4b56f5 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -62,18 +62,19 @@ impl World { let water = Block::new(5, Rgb::new(100, 150, 255)); let chunk_size2d = Vec2::from(TerrainChunkSize::SIZE); - let (base_z, sim_chunk) = match self.sim.get_interpolated( - chunk_pos.map2(chunk_size2d, |e, sz: u32| e * sz as i32 + sz as i32 / 2), - |chunk| chunk.get_base_z(), - ).and_then(|base_z| self.sim.get(chunk_pos).map(|sim_chunk| (base_z, sim_chunk))) { + let (base_z, sim_chunk) = match self + .sim + .get_interpolated( + chunk_pos.map2(chunk_size2d, |e, sz: u32| e * sz as i32 + sz as i32 / 2), + |chunk| chunk.get_base_z(), + ) + .and_then(|base_z| self.sim.get(chunk_pos).map(|sim_chunk| (base_z, sim_chunk))) + { Some((base_z, sim_chunk)) => (base_z as i32, sim_chunk), None => return TerrainChunk::new(0, water, air, TerrainChunkMeta::void()), }; - let meta = TerrainChunkMeta::new( - sim_chunk.get_name(), - sim_chunk.get_biome(), - ); + let meta = TerrainChunkMeta::new(sim_chunk.get_name(), sim_chunk.get_biome()); let mut chunk = TerrainChunk::new(base_z - 8, stone, air, meta); diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 6cb1241a97..7624ea4a31 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -9,16 +9,12 @@ use common::{ vol::VolSize, }; use noise::{BasicMulti, HybridMulti, MultiFractal, NoiseFn, RidgedMulti, Seedable, SuperSimplex}; +use rand::{prng::XorShiftRng, Rng, SeedableRng}; use std::{ ops::{Add, Div, Mul, Neg, Sub}, sync::Arc, }; use vek::*; -use rand::{ - Rng, - SeedableRng, - prng::XorShiftRng, -}; pub const WORLD_SIZE: Vec2 = Vec2 { x: 1024, y: 1024 }; @@ -86,10 +82,22 @@ impl WorldSim { chunks, gen_ctx, rng: XorShiftRng::from_seed([ - (seed >> 0) as u8, 0, 0, 0, - (seed >> 8) as u8, 0, 0, 0, - (seed >> 16) as u8, 0, 0, 0, - (seed >> 24) as u8, 0, 0, 0, + (seed >> 0) as u8, + 0, + 0, + 0, + (seed >> 8) as u8, + 0, + 0, + 0, + (seed >> 16) as u8, + 0, + 0, + 0, + (seed >> 24) as u8, + 0, + 0, + 0, ]), }; @@ -127,15 +135,14 @@ impl WorldSim { let location = self.get(pos).unwrap().location.clone(); - let rpos = Vec2::new( - rng.gen::(), - rng.gen::(), - ).map(|e| e.abs() % 3 - 1); + let rpos = + Vec2::new(rng.gen::(), rng.gen::()).map(|e| e.abs() % 3 - 1); if let Some(other) = &mut self.get_mut(pos + rpos) { if other.location.is_none() && rng.gen::() > other.chaos * 1.5 - && other.alt > CONFIG.sea_level { + && other.alt > CONFIG.sea_level + { other.location = location; } } @@ -206,8 +213,7 @@ impl WorldSim { let mut x = [T::default(); 4]; for (x_idx, j) in (-1..3).enumerate() { - let y0 = - f(self.get(pos.map2(Vec2::new(j, -1), |e, q| e.max(0.0) as i32 + q))?); + let y0 = f(self.get(pos.map2(Vec2::new(j, -1), |e, q| e.max(0.0) as i32 + q))?); let y1 = f(self.get(pos.map2(Vec2::new(j, 0), |e, q| e.max(0.0) as i32 + q))?); let y2 = f(self.get(pos.map2(Vec2::new(j, 1), |e, q| e.max(0.0) as i32 + q))?); let y3 = f(self.get(pos.map2(Vec2::new(j, 2), |e, q| e.max(0.0) as i32 + q))?); @@ -252,7 +258,12 @@ impl SimChunk { let chaos = (gen_ctx.chaos_nz.get((wposf.div(4_000.0)).into_array()) as f32) .add(1.0) .mul(0.5) - .mul((gen_ctx.chaos_nz.get((wposf.div(8_000.0)).into_array()) as f32).powf(2.0).add(0.5).min(1.0)) + .mul( + (gen_ctx.chaos_nz.get((wposf.div(8_000.0)).into_array()) as f32) + .powf(2.0) + .add(0.5) + .min(1.0), + ) .powf(1.4) .add(0.1 * hill); @@ -338,9 +349,7 @@ impl SimChunk { } pub fn get_name(&self) -> Option { - self.location - .as_ref() - .map(|l| l.name().to_string()) + self.location.as_ref().map(|l| l.name().to_string()) } pub fn get_biome(&self) -> BiomeKind { From 5f09e755413a691b8b68837cc5f095a8d30c162f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Korg=C3=B3l?= Date: Wed, 19 Jun 2019 17:02:22 +0200 Subject: [PATCH 11/40] Stop printing out chunk location --- voxygen/src/session.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index c78d8bf874..bd80a71f51 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -57,12 +57,6 @@ impl SessionState { } } - // TODO: Get rid of this when we're done with it (we're not yet) - match self.client.borrow().current_chunk() { - Some(chunk) => println!("Chunk location: {:?}", chunk.meta().name()), - None => {} - } - Ok(()) } From 3e56c65e8605c58642bcdd1b3334701f5049f459 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Wed, 19 Jun 2019 14:37:46 +0100 Subject: [PATCH 12/40] Make name generation seed-dependent again --- world/src/sim/location.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/world/src/sim/location.rs b/world/src/sim/location.rs index 597420b737..4995cc0e58 100644 --- a/world/src/sim/location.rs +++ b/world/src/sim/location.rs @@ -55,7 +55,7 @@ fn generate_name(rng: &mut R) -> String { ]; let mut name = String::new(); - if rand::random() { + if rng.gen() { name += rng.choose(&firstsyl).unwrap(); name += rng.choose(&mid).unwrap(); name += rng.choose(&tails).unwrap(); From 704e65cb4180456def540e46c307eb1f22c88c83 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Wed, 19 Jun 2019 17:18:56 +0100 Subject: [PATCH 13/40] Attempted rivers --- world/src/column/mod.rs | 4 +++- world/src/sim/mod.rs | 14 ++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 755e57c3b6..269dc2a3ff 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -35,6 +35,7 @@ impl<'a> Sampler for ColumnGen<'a> { let alt_base = sim.get_interpolated(wpos, |chunk| chunk.alt_base)?; let chaos = sim.get_interpolated(wpos, |chunk| chunk.chaos)?; let temp = sim.get_interpolated(wpos, |chunk| chunk.temp)?; + let dryness = sim.get_interpolated(wpos, |chunk| chunk.dryness)?; let rockiness = sim.get_interpolated(wpos, |chunk| chunk.rockiness)?; let cliffiness = sim.get_interpolated(wpos, |chunk| chunk.cliffiness)?; let tree_density = sim.get_interpolated(wpos, |chunk| chunk.tree_density)?; @@ -45,7 +46,8 @@ impl<'a> Sampler for ColumnGen<'a> { + (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32) .abs() .mul(chaos.max(0.2)) - .mul(64.0); + .mul(64.0) + - dryness.abs().neg().add(0.03).max(0.0).mul(3000.0); let rock = (sim.gen_ctx.small_nz.get( Vec3::new(wposf.x, wposf.y, alt as f64) diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 7624ea4a31..c6d14a6687 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -232,6 +232,7 @@ pub struct SimChunk { pub alt_base: f32, pub alt: f32, pub temp: f32, + pub dryness: f32, pub rockiness: f32, pub cliffiness: f32, pub tree_density: f32, @@ -255,15 +256,15 @@ impl SimChunk { .add(0.3) .max(0.0); + let dryness = (gen_ctx.chaos_nz.get((wposf.div(1_000.0)).into_array()) as f32); + let chaos = (gen_ctx.chaos_nz.get((wposf.div(4_000.0)).into_array()) as f32) .add(1.0) .mul(0.5) - .mul( - (gen_ctx.chaos_nz.get((wposf.div(8_000.0)).into_array()) as f32) - .powf(2.0) - .add(0.5) - .min(1.0), - ) + .mul((gen_ctx.chaos_nz.get((wposf.div(8_000.0)).into_array()) as f32) + .powf(2.0) + .add(0.5) + .min(1.0)) .powf(1.4) .add(0.1 * hill); @@ -299,6 +300,7 @@ impl SimChunk { alt_base, alt, temp, + dryness, rockiness: (gen_ctx.rock_nz.get((wposf.div(1024.0)).into_array()) as f32) .sub(0.1) .mul(1.3) From c86c4d0b2b89cf1681e5a3c0f476673c5f247f3b Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Wed, 19 Jun 2019 17:33:11 +0100 Subject: [PATCH 14/40] fmt --- world/src/sim/mod.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index c6d14a6687..c8c05bc9d2 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -261,10 +261,12 @@ impl SimChunk { let chaos = (gen_ctx.chaos_nz.get((wposf.div(4_000.0)).into_array()) as f32) .add(1.0) .mul(0.5) - .mul((gen_ctx.chaos_nz.get((wposf.div(8_000.0)).into_array()) as f32) - .powf(2.0) - .add(0.5) - .min(1.0)) + .mul( + (gen_ctx.chaos_nz.get((wposf.div(8_000.0)).into_array()) as f32) + .powf(2.0) + .add(0.5) + .min(1.0), + ) .powf(1.4) .add(0.1 * hill); From 1642988615dad23dbc15885c70aa4c6777a23394 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Wed, 19 Jun 2019 20:58:56 +0100 Subject: [PATCH 15/40] First attempt at rivers --- world/src/block/mod.rs | 8 ++++++-- world/src/column/mod.rs | 32 ++++++++++++++++++++++++++++---- world/src/sim/mod.rs | 31 ++++++++++++++++++++++--------- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index e253ec43b1..6ab3d3eb71 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -44,6 +44,8 @@ impl<'a> SamplerMut for BlockGen<'a> { let ColumnSample { alt, chaos, + water_level, + river, surface_color, tree_density, forest_kind, @@ -107,6 +109,7 @@ impl<'a> SamplerMut for BlockGen<'a> { }; let height = alt + warp + cliff; + let water_height = water_level + warp; // Sample blocks @@ -138,7 +141,7 @@ impl<'a> SamplerMut for BlockGen<'a> { ); // Surface Some(Block::new(1, col.map(|e| (e * 255.0) as u8))) - } else if (wposf.z as f32) < CONFIG.sea_level { + } else if (wposf.z as f32) < water_height { // Ocean Some(water) } else { @@ -233,7 +236,8 @@ impl<'a> SamplerMut for BlockGen<'a> { match self.sample_column(Vec2::from(*tree_pos)) { Some(tree_sample) if tree_sample.tree_density - > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 => + > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 + && tree_sample.alt > tree_sample.water_level => { let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, tree_sample.alt as i32); diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 269dc2a3ff..f3c0591bdc 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -5,6 +5,7 @@ use common::{ }; use noise::NoiseFn; use std::{ + f32, ops::{Add, Div, Mul, Neg, Sub}, sync::Arc, }; @@ -42,12 +43,31 @@ impl<'a> Sampler for ColumnGen<'a> { let sim_chunk = sim.get(chunk_pos)?; - let alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? + const RIVER_PROPORTION: f32 = 0.025; + + let river = dryness + .abs() + .neg() + .add(RIVER_PROPORTION) + .div(RIVER_PROPORTION) + .max(0.0) + .mul((1.0 - (chaos - 0.15) * 20.0).max(0.0).min(1.0)); + + let riverless_alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? + (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32) .abs() .mul(chaos.max(0.2)) - .mul(64.0) - - dryness.abs().neg().add(0.03).max(0.0).mul(3000.0); + .mul(64.0); + + let alt = riverless_alt + - (1.0 - river) + .mul(f32::consts::PI) + .cos() + .add(1.0) + .mul(0.5) + .mul(24.0); + + let water_level = (riverless_alt - 4.0 - 5.0 * chaos).max(CONFIG.sea_level); let rock = (sim.gen_ctx.small_nz.get( Vec3::new(wposf.x, wposf.y, alt as f64) @@ -123,6 +143,8 @@ impl<'a> Sampler for ColumnGen<'a> { Some(ColumnSample { alt, chaos, + water_level, + river, surface_color: Rgb::lerp( sand, // Land @@ -142,7 +164,7 @@ impl<'a> Sampler for ColumnGen<'a> { (alt - CONFIG.sea_level - 0.2 * CONFIG.mountain_scale) / 180.0, ), // Beach - (alt - CONFIG.sea_level - 2.0) / 5.0, + ((alt - CONFIG.sea_level - 2.0) / 5.0).min(1.0 - river * 2.0), ), tree_density, forest_kind: sim_chunk.forest_kind, @@ -161,6 +183,8 @@ impl<'a> Sampler for ColumnGen<'a> { pub struct ColumnSample<'a> { pub alt: f32, pub chaos: f32, + pub water_level: f32, + pub river: f32, pub surface_color: Rgb, pub tree_density: f32, pub forest_kind: ForestKind, diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index c8c05bc9d2..60d0abcec2 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -25,6 +25,7 @@ pub(crate) struct GenCtx { pub alt_nz: HybridMulti, pub hill_nz: SuperSimplex, pub temp_nz: SuperSimplex, + pub dry_nz: BasicMulti, pub small_nz: BasicMulti, pub rock_nz: HybridMulti, pub cliff_nz: HybridMulti, @@ -56,16 +57,17 @@ impl WorldSim { .set_persistence(0.1) .set_seed(seed + 4), temp_nz: SuperSimplex::new().set_seed(seed + 5), - small_nz: BasicMulti::new().set_octaves(2).set_seed(seed + 6), - rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 7), - cliff_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 7), - warp_nz: BasicMulti::new().set_octaves(3).set_seed(seed + 8), + dry_nz: BasicMulti::new().set_seed(seed + 6), + small_nz: BasicMulti::new().set_octaves(2).set_seed(seed + 7), + rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 8), + cliff_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 9), + warp_nz: BasicMulti::new().set_octaves(3).set_seed(seed + 10), tree_nz: BasicMulti::new() .set_octaves(12) .set_persistence(0.75) - .set_seed(seed + 9), - cave_0_nz: SuperSimplex::new().set_seed(seed + 10), - cave_1_nz: SuperSimplex::new().set_seed(seed + 11), + .set_seed(seed + 12), + cave_0_nz: SuperSimplex::new().set_seed(seed + 13), + cave_1_nz: SuperSimplex::new().set_seed(seed + 14), tree_gen: StructureGen2d::new(seed, 32, 24), }; @@ -256,7 +258,18 @@ impl SimChunk { .add(0.3) .max(0.0); - let dryness = (gen_ctx.chaos_nz.get((wposf.div(1_000.0)).into_array()) as f32); + let dryness = (gen_ctx.dry_nz.get( + (wposf + .add(Vec2::new( + gen_ctx + .dry_nz + .get((wposf.add(10000.0).div(500.0)).into_array()) + * 150.0, + gen_ctx.dry_nz.get((wposf.add(0.0).div(500.0)).into_array()) * 150.0, + )) + .div(2_000.0)) + .into_array(), + ) as f32); let chaos = (gen_ctx.chaos_nz.get((wposf.div(4_000.0)).into_array()) as f32) .add(1.0) @@ -345,7 +358,7 @@ impl SimChunk { } pub fn get_min_z(&self) -> f32 { - self.alt - Z_TOLERANCE.0 * (self.chaos + 0.3) + self.alt - Z_TOLERANCE.0 * (self.chaos * 1.2 + 0.3) } pub fn get_max_z(&self) -> f32 { From fffef7c7399e2455850fa1be494f56478de815f4 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Fri, 21 Jun 2019 01:53:11 +0100 Subject: [PATCH 16/40] Better rivers, rewrote cliffs --- voxygen/shaders/include/sky.glsl | 2 +- world/src/block/mod.rs | 55 ++++++++++++++++++++++++++------ world/src/column/mod.rs | 18 ++++++++--- world/src/sim/mod.rs | 35 ++++++++++---------- 4 files changed, 78 insertions(+), 32 deletions(-) diff --git a/voxygen/shaders/include/sky.glsl b/voxygen/shaders/include/sky.glsl index c7402333b3..c65fd42544 100644 --- a/voxygen/shaders/include/sky.glsl +++ b/voxygen/shaders/include/sky.glsl @@ -66,7 +66,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day) { vec3 sun_dir = get_sun_dir(time_of_day); float sky_brightness = get_sun_brightness(sun_dir); - vec3 sun_halo = pow(max(dot(dir, -sun_dir) + 0.1, 0.0), 8.0) * SUN_HALO_COLOR; + vec3 sun_halo = pow(max(dot(dir, -sun_dir) + 0.5, 0.0), 8.0) * SUN_HALO_COLOR; vec3 sun_surf = pow(max(dot(dir, -sun_dir) - 0.0045, 0.0), 1000.0) * SUN_SURF_COLOR; vec3 sun_light = sun_halo + sun_surf; diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 6ab3d3eb71..5531676932 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -10,12 +10,15 @@ use common::{ vol::{ReadVol, Vox}, }; use noise::NoiseFn; -use std::ops::{Add, Div, Mul, Neg, Sub}; +use std::{ + cell::RefCell, + ops::{Add, Div, Mul, Neg, Sub}, +}; use vek::*; pub struct BlockGen<'a> { world: &'a World, - column_cache: HashCache, Option>>, + column_cache: RefCell, Option>>>, column_gen: ColumnGen<'a>, } @@ -23,17 +26,38 @@ impl<'a> BlockGen<'a> { pub fn new(world: &'a World, column_gen: ColumnGen<'a>) -> Self { Self { world, - column_cache: HashCache::with_capacity(1024), + column_cache: RefCell::new(HashCache::with_capacity(1024)), column_gen, } } - fn sample_column(&mut self, wpos: Vec2) -> Option { - let column_gen = &mut self.column_gen; + fn sample_column(&self, wpos: Vec2) -> Option { + let column_gen = &self.column_gen; self.column_cache + .borrow_mut() .get(Vec2::from(wpos), |wpos| column_gen.get(wpos)) .clone() } + + fn get_cliff_height(&self, wpos: Vec2, close_cliffs: &[(Vec2, u32); 9], cliff_hill: f32) -> f32 { + close_cliffs + .iter() + .fold(0.0f32, |max_height, (cliff_pos, seed)| { + let cliff_pos3d = Vec3::from(*cliff_pos); + + let height = RandomField::new(seed + 1).get(cliff_pos3d) % 48; + let radius = RandomField::new(seed + 2).get(cliff_pos3d) % 48 + 8; + + match self.sample_column(Vec2::from(*cliff_pos)) { + Some(cliff_sample) => max_height.max(if cliff_sample.cliffs && cliff_pos.distance_squared(wpos) < (radius * radius) as i32 { + cliff_sample.alt + height as f32 * (1.0 - cliff_sample.chaos) + cliff_hill + } else { + 0.0 + }), + None => max_height, + } + }) + } } impl<'a> SamplerMut for BlockGen<'a> { @@ -53,7 +77,9 @@ impl<'a> SamplerMut for BlockGen<'a> { cave_xy, cave_alt, rock, - cliff, + cliffs, + cliff_hill, + close_cliffs, temp, .. } = self.sample_column(Vec2::from(wpos))?; @@ -72,6 +98,15 @@ impl<'a> SamplerMut for BlockGen<'a> { .mul((chaos - 0.1).max(0.0)) .mul(115.0); + let turb = Vec2::new( + self.world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32, + self.world.sim().gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32, + ) * 12.0; + + let wpos_turb = Vec2::from(wpos) + turb.map(|e| e as i32); + let cliff_height = self.get_cliff_height(wpos_turb, &close_cliffs, cliff_hill); + + /* let is_cliff = if cliff > 0.0 { (self .world @@ -107,8 +142,9 @@ impl<'a> SamplerMut for BlockGen<'a> { } else { 0.0 }; + */ - let height = alt + warp + cliff; + let height = (alt + warp).max(cliff_height); let water_height = water_level + warp; // Sample blocks @@ -239,8 +275,9 @@ impl<'a> SamplerMut for BlockGen<'a> { > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 && tree_sample.alt > tree_sample.water_level => { - let tree_pos3d = - Vec3::new(tree_pos.x, tree_pos.y, tree_sample.alt as i32); + let cliff_height = self.get_cliff_height(*tree_pos, &tree_sample.close_cliffs, cliff_hill); + let height = tree_sample.alt.max(cliff_height); + let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, height as i32); let rpos = wpos - tree_pos3d; let trees = tree::kinds(tree_sample.forest_kind); // Choose tree kind diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index f3c0591bdc..06da8687f2 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -38,7 +38,6 @@ impl<'a> Sampler for ColumnGen<'a> { let temp = sim.get_interpolated(wpos, |chunk| chunk.temp)?; let dryness = sim.get_interpolated(wpos, |chunk| chunk.dryness)?; let rockiness = sim.get_interpolated(wpos, |chunk| chunk.rockiness)?; - let cliffiness = sim.get_interpolated(wpos, |chunk| chunk.cliffiness)?; let tree_density = sim.get_interpolated(wpos, |chunk| chunk.tree_density)?; let sim_chunk = sim.get(chunk_pos)?; @@ -53,12 +52,17 @@ impl<'a> Sampler for ColumnGen<'a> { .max(0.0) .mul((1.0 - (chaos - 0.15) * 20.0).max(0.0).min(1.0)); + let cliff_hill = (sim.gen_ctx.small_nz.get((wposf.div(128.0)).into_array()) as f32) + .mul(12.0); + let riverless_alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? + (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32) .abs() .mul(chaos.max(0.2)) .mul(64.0); + let cliffs = sim_chunk.cliffs; + let alt = riverless_alt - (1.0 - river) .mul(f32::consts::PI) @@ -125,7 +129,7 @@ impl<'a> Sampler for ColumnGen<'a> { .mul((1.15 - chaos).min(1.0)) }; let cave_xy = cave_at(wposf); - let cave_alt = alt - 32.0 + let cave_alt = alt - 16.0 + (sim .gen_ctx .cave_1_nz @@ -161,7 +165,7 @@ impl<'a> Sampler for ColumnGen<'a> { - marble * 24.0) / 12.0, ), - (alt - CONFIG.sea_level - 0.2 * CONFIG.mountain_scale) / 180.0, + (alt - CONFIG.sea_level - 0.2 * CONFIG.mountain_scale + marble * 48.0) / 100.0, ), // Beach ((alt - CONFIG.sea_level - 2.0) / 5.0).min(1.0 - river * 2.0), @@ -172,7 +176,9 @@ impl<'a> Sampler for ColumnGen<'a> { cave_xy, cave_alt, rock, - cliff: cliffiness, + cliffs, + cliff_hill, + close_cliffs: sim.gen_ctx.cliff_gen.get(wpos), temp, location: sim_chunk.location.as_ref(), }) @@ -192,7 +198,9 @@ pub struct ColumnSample<'a> { pub cave_xy: f32, pub cave_alt: f32, pub rock: f32, - pub cliff: f32, + pub cliffs: bool, + pub cliff_hill: f32, + pub close_cliffs: [(Vec2, u32); 9], pub temp: f32, pub location: Option<&'a Arc>, } diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 60d0abcec2..8e0ce3fcb0 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -19,8 +19,8 @@ use vek::*; pub const WORLD_SIZE: Vec2 = Vec2 { x: 1024, y: 1024 }; pub(crate) struct GenCtx { - pub turb_x_nz: BasicMulti, - pub turb_y_nz: BasicMulti, + pub turb_x_nz: SuperSimplex, + pub turb_y_nz: SuperSimplex, pub chaos_nz: RidgedMulti, pub alt_nz: HybridMulti, pub hill_nz: SuperSimplex, @@ -36,6 +36,7 @@ pub(crate) struct GenCtx { pub cave_1_nz: SuperSimplex, pub tree_gen: StructureGen2d, + pub cliff_gen: StructureGen2d, } pub struct WorldSim { @@ -48,8 +49,8 @@ pub struct WorldSim { impl WorldSim { pub fn generate(seed: u32) -> Self { let mut gen_ctx = GenCtx { - turb_x_nz: BasicMulti::new().set_seed(seed + 0), - turb_y_nz: BasicMulti::new().set_seed(seed + 1), + turb_x_nz: SuperSimplex::new().set_seed(seed + 0), + turb_y_nz: SuperSimplex::new().set_seed(seed + 1), chaos_nz: RidgedMulti::new().set_octaves(7).set_seed(seed + 2), hill_nz: SuperSimplex::new().set_seed(seed + 3), alt_nz: HybridMulti::new() @@ -70,6 +71,7 @@ impl WorldSim { cave_1_nz: SuperSimplex::new().set_seed(seed + 14), tree_gen: StructureGen2d::new(seed, 32, 24), + cliff_gen: StructureGen2d::new(seed, 80, 64), }; let mut chunks = Vec::new(); @@ -104,7 +106,7 @@ impl WorldSim { }; this.seed_elements(); - this.simulate(200); + this.simulate(0); this } @@ -227,7 +229,7 @@ impl WorldSim { } } -const Z_TOLERANCE: (f32, f32) = (128.0, 96.0); +const Z_TOLERANCE: (f32, f32) = (64.0, 128.0); pub struct SimChunk { pub chaos: f32, @@ -236,7 +238,8 @@ pub struct SimChunk { pub temp: f32, pub dryness: f32, pub rockiness: f32, - pub cliffiness: f32, + pub cliffs: bool, + pub near_cliffs: bool, pub tree_density: f32, pub forest_kind: ForestKind, pub location: Option>, @@ -275,7 +278,7 @@ impl SimChunk { .add(1.0) .mul(0.5) .mul( - (gen_ctx.chaos_nz.get((wposf.div(8_000.0)).into_array()) as f32) + (gen_ctx.chaos_nz.get((wposf.div(6_000.0)).into_array()) as f32) .powf(2.0) .add(0.5) .min(1.0), @@ -291,7 +294,7 @@ impl SimChunk { .add(alt_base.mul(128.0).sin().mul(0.005)) .mul(400.0); - let alt_main = (gen_ctx.alt_nz.get((wposf.div(1_000.0)).into_array()) as f32) + let alt_main = (gen_ctx.alt_nz.get((wposf.div(2_000.0)).into_array()) as f32) .abs() .powf(1.7); @@ -310,6 +313,8 @@ impl SimChunk { let temp = (gen_ctx.temp_nz.get((wposf.div(8192.0)).into_array()) as f32); + let cliff = gen_ctx.cliff_nz.get((wposf.div(2048.0)).into_array()) as f32 + chaos * 0.2; + Self { chaos, alt_base, @@ -320,16 +325,12 @@ impl SimChunk { .sub(0.1) .mul(1.3) .max(0.0), - cliffiness: (gen_ctx.cliff_nz.get((wposf.div(2048.0)).into_array()) as f32) - .sub(0.15) - .mul(3.0) - .mul(1.1 - chaos) - .max(0.0) - .min(1.0), + cliffs: cliff > 0.5, + near_cliffs: cliff > 0.4, tree_density: (gen_ctx.tree_nz.get((wposf.div(1024.0)).into_array()) as f32) .add(1.0) .mul(0.5) - .mul(1.2 - chaos * 0.85) + .mul(1.2 - chaos * 0.95) .add(0.1) .mul(if alt > CONFIG.sea_level + 5.0 { 1.0 @@ -362,7 +363,7 @@ impl SimChunk { } pub fn get_max_z(&self) -> f32 { - (self.alt + Z_TOLERANCE.1).max(CONFIG.sea_level + 1.0) + (self.alt + Z_TOLERANCE.1 * if self.near_cliffs { 1.0 } else { 0.5 }).max(CONFIG.sea_level + 2.0) } pub fn get_name(&self) -> Option { From 693d59cc93e14b38919605af6a2c85ef9cf8d019 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Fri, 21 Jun 2019 01:53:54 +0100 Subject: [PATCH 17/40] Removed old cliff code --- world/src/block/mod.rs | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 5531676932..aff2e6c86e 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -106,44 +106,6 @@ impl<'a> SamplerMut for BlockGen<'a> { let wpos_turb = Vec2::from(wpos) + turb.map(|e| e as i32); let cliff_height = self.get_cliff_height(wpos_turb, &close_cliffs, cliff_hill); - /* - let is_cliff = if cliff > 0.0 { - (self - .world - .sim() - .gen_ctx - .warp_nz - .get((wposf.div(Vec3::new(300.0, 300.0, 1500.0))).into_array()) as f32) - * cliff - > 0.3 - } else { - false - }; - - let cliff = if is_cliff { - (0.0 + (self - .world - .sim() - .gen_ctx - .warp_nz - .get((wposf.div(Vec3::new(350.0, 350.0, 800.0))).into_array()) - as f32) - * 0.8 - + (self - .world - .sim() - .gen_ctx - .warp_nz - .get((wposf.div(Vec3::new(100.0, 100.0, 70.0))).into_array()) - as f32) - * 0.3) - .add(0.4) - .mul(75.0) - } else { - 0.0 - }; - */ - let height = (alt + warp).max(cliff_height); let water_height = water_level + warp; From f3adf6ab5fc29d2552acbf532a5d12dba74814a2 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Fri, 21 Jun 2019 09:08:20 +0100 Subject: [PATCH 18/40] Improved mountain rock transition --- world/src/column/mod.rs | 2 +- world/src/sim/mod.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 06da8687f2..1b633beee7 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -165,7 +165,7 @@ impl<'a> Sampler for ColumnGen<'a> { - marble * 24.0) / 12.0, ), - (alt - CONFIG.sea_level - 0.2 * CONFIG.mountain_scale + marble * 48.0) / 100.0, + (alt - CONFIG.sea_level - 0.3 * CONFIG.mountain_scale + marble * 128.0) / 100.0, ), // Beach ((alt - CONFIG.sea_level - 2.0) / 5.0).min(1.0 - river * 2.0), diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 8e0ce3fcb0..99bdf80c78 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -283,7 +283,7 @@ impl SimChunk { .add(0.5) .min(1.0), ) - .powf(1.4) + .powf(1.5) .add(0.1 * hill); let chaos = chaos + chaos.mul(16.0).sin().mul(0.02); @@ -296,7 +296,7 @@ impl SimChunk { let alt_main = (gen_ctx.alt_nz.get((wposf.div(2_000.0)).into_array()) as f32) .abs() - .powf(1.7); + .powf(1.8); let alt = CONFIG.sea_level + alt_base From 9279611d6dcbf91a7582069920afd0ef33d33d5a Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Fri, 21 Jun 2019 09:42:16 +0100 Subject: [PATCH 19/40] Added longer day/night cycle, /time command --- common/src/state.rs | 4 +-- server/src/cmd.rs | 44 +++++++++++++++++++++++++++----- voxygen/shaders/include/sky.glsl | 2 +- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/common/src/state.rs b/common/src/state.rs index 56d476b4f4..656ff40a51 100644 --- a/common/src/state.rs +++ b/common/src/state.rs @@ -20,11 +20,11 @@ use vek::*; /// How much faster should an in-game day be compared to a real day? // TODO: Don't hard-code this. -const DAY_CYCLE_FACTOR: f64 = 24.0 * 60.0; +const DAY_CYCLE_FACTOR: f64 = 24.0 * 2.0; /// A resource that stores the time of day. #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct TimeOfDay(f64); +pub struct TimeOfDay(pub f64); /// A resource that stores the tick (i.e: physics) time. #[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)] diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 510a171ff9..750bb6ef2d 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -7,6 +7,7 @@ use common::{ comp, msg::ServerMsg, npc::{get_npc_name, NpcKind}, + state::TimeOfDay, }; use specs::{Builder, Entity as EcsEntity, Join}; use vek::*; @@ -59,37 +60,43 @@ lazy_static! { "jump", "{d} {d} {d}", "/jump : Offset your current position", - handle_jump + handle_jump, ), ChatCommand::new( "goto", "{d} {d} {d}", "/goto : Teleport to a position", - handle_goto + handle_goto, ), ChatCommand::new( "alias", "{}", "/alias : Change your alias", - handle_alias + handle_alias, ), ChatCommand::new( "tp", "{}", "/tp : Teleport to another player", - handle_tp + handle_tp, ), ChatCommand::new( "kill", "{}", "/kill : Kill yourself", - handle_kill + handle_kill, + ), + ChatCommand::new( + "time", + "{} {s}", + "/time : Set the time of day", + handle_time, ), ChatCommand::new( "spawn", "{} {} {d}", "/spawn [amount] : Spawn a test entity", - handle_spawn + handle_spawn, ), ChatCommand::new( "help", "", "/help: Display this message", handle_help) @@ -143,6 +150,31 @@ fn handle_kill(server: &mut Server, entity: EcsEntity, _args: String, _action: & .map(|s| s.hp.set_to(0, comp::HealthSource::Suicide)); } +fn handle_time(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { + let time = scan_fmt!(&args, action.arg_fmt, String); + server + .state + .ecs_mut() + .write_resource::() + .0 = match time.as_ref().map(|s| s.as_str()) { + Some("day") => 12.0 * 3600.0, + Some("night") => 24.0 * 3600.0, + Some("dawn") => 5.0 * 3600.0, + Some("dusk") => 17.0 * 3600.0, + Some(n) => match n.parse() { + Ok(n) => n, + Err(_) => { + server.clients.notify(entity, ServerMsg::Chat(format!("'{}' is not a time!", n))); + return; + }, + }, + None => { + server.clients.notify(entity, ServerMsg::Chat("You must specify a time!".to_string())); + return; + }, + }; +} + fn handle_alias(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { let opt_alias = scan_fmt!(&args, action.arg_fmt, String); match opt_alias { diff --git a/voxygen/shaders/include/sky.glsl b/voxygen/shaders/include/sky.glsl index c65fd42544..c7402333b3 100644 --- a/voxygen/shaders/include/sky.glsl +++ b/voxygen/shaders/include/sky.glsl @@ -66,7 +66,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day) { vec3 sun_dir = get_sun_dir(time_of_day); float sky_brightness = get_sun_brightness(sun_dir); - vec3 sun_halo = pow(max(dot(dir, -sun_dir) + 0.5, 0.0), 8.0) * SUN_HALO_COLOR; + vec3 sun_halo = pow(max(dot(dir, -sun_dir) + 0.1, 0.0), 8.0) * SUN_HALO_COLOR; vec3 sun_surf = pow(max(dot(dir, -sun_dir) - 0.0045, 0.0), 1000.0) * SUN_SURF_COLOR; vec3 sun_light = sun_halo + sun_surf; From d0b38e9875f49a2f9cbf0671efe0e78090e5235f Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Fri, 21 Jun 2019 13:32:38 +0100 Subject: [PATCH 20/40] Worldgen performance improvements, better sun --- common/src/terrain/block.rs | 2 +- voxygen/shaders/include/sky.glsl | 2 +- voxygen/src/mesh/terrain.rs | 10 +-- world/src/block/mod.rs | 140 +++++++++++++++++-------------- world/src/column/mod.rs | 10 +-- world/src/sim/mod.rs | 6 +- world/src/util/random.rs | 15 ++-- 7 files changed, 100 insertions(+), 85 deletions(-) diff --git a/common/src/terrain/block.rs b/common/src/terrain/block.rs index ef3b5d2ffb..e9cccfd8bf 100644 --- a/common/src/terrain/block.rs +++ b/common/src/terrain/block.rs @@ -27,7 +27,7 @@ impl Block { pub fn get_opacity(&self) -> Option { match self.kind { 0 => None, - 1 => Some(0.85), + 1 => Some(0.6), _ => Some(1.0), } } diff --git a/voxygen/shaders/include/sky.glsl b/voxygen/shaders/include/sky.glsl index c7402333b3..d03c301a2d 100644 --- a/voxygen/shaders/include/sky.glsl +++ b/voxygen/shaders/include/sky.glsl @@ -36,7 +36,7 @@ vec3 get_sun_dir(float time_of_day) { } float get_sun_brightness(vec3 sun_dir) { - return max(-sun_dir.z, 0.0); + return pow(max(-sun_dir.z + 0.3, 0.0), 0.5); } const float PERSISTENT_AMBIANCE = 0.015; diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index 494e368591..cdfebd7871 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -83,8 +83,8 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for TerrainVertex::new( pos, norm, - Lerp::lerp(Rgb::zero(), col, ao), - light, + Lerp::lerp(Rgb::zero(), col, 1.0), + light * ao, ) }, false, @@ -104,10 +104,10 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for .ok() .and_then(|vox| vox.get_opacity()) { - (neighbour_light[0][i][j] * (1.0 - opacity * 0.2)) - .max(1.0 - opacity * 1.0) + (neighbour_light[0][i][j] * (1.0 - opacity * 0.4)) + .max(1.0 - opacity) } else { - (neighbour_light[0][i][j] * 1.035).min(1.0) + (neighbour_light[0][i][j] * 1.025).min(1.0) }; } } diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index aff2e6c86e..6614df71d0 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -43,18 +43,20 @@ impl<'a> BlockGen<'a> { close_cliffs .iter() .fold(0.0f32, |max_height, (cliff_pos, seed)| { - let cliff_pos3d = Vec3::from(*cliff_pos); - - let height = RandomField::new(seed + 1).get(cliff_pos3d) % 48; - let radius = RandomField::new(seed + 2).get(cliff_pos3d) % 48 + 8; - match self.sample_column(Vec2::from(*cliff_pos)) { - Some(cliff_sample) => max_height.max(if cliff_sample.cliffs && cliff_pos.distance_squared(wpos) < (radius * radius) as i32 { - cliff_sample.alt + height as f32 * (1.0 - cliff_sample.chaos) + cliff_hill - } else { - 0.0 - }), - None => max_height, + Some(cliff_sample) if cliff_sample.cliffs => { + let cliff_pos3d = Vec3::from(*cliff_pos); + + let height = RandomField::new(seed + 1).get(cliff_pos3d) % 48; + let radius = RandomField::new(seed + 2).get(cliff_pos3d) % 48 + 8; + + max_height.max(if cliff_pos.distance_squared(wpos) < (radius * radius) as i32 { + cliff_sample.alt + height as f32 * (1.0 - cliff_sample.chaos) + cliff_hill + } else { + 0.0 + }) + }, + _ => max_height, } }) } @@ -86,28 +88,38 @@ impl<'a> SamplerMut for BlockGen<'a> { let wposf = wpos.map(|e| e as f64); - // Apply warping + let (definitely_underground, height, water_height) = if (wposf.z as f32) < alt - 64.0 * chaos { + // Shortcut warping + (true, alt, water_level) + } else { + // Apply warping + let warp = (self + .world + .sim() + .gen_ctx + .warp_nz + .get((wposf.div(Vec3::new(150.0, 150.0, 150.0))).into_array()) + as f32) + .mul((chaos - 0.1).max(0.0)) + .mul(115.0); - let warp = (self - .world - .sim() - .gen_ctx - .warp_nz - .get((wposf.div(Vec3::new(150.0, 150.0, 150.0))).into_array()) - as f32) - .mul((chaos - 0.1).max(0.0)) - .mul(115.0); + let height = if (wposf.z as f32) < alt + warp - 10.0 { + // Shortcut cliffs + alt + warp + } else { + let turb = Vec2::new( + self.world.sim().gen_ctx.turb_x_nz.get((wposf.div(64.0)).into_array()) as f32, + self.world.sim().gen_ctx.turb_y_nz.get((wposf.div(64.0)).into_array()) as f32, + ) * 16.0; - let turb = Vec2::new( - self.world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32, - self.world.sim().gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32, - ) * 12.0; + let wpos_turb = Vec2::from(wpos) + turb.map(|e| e as i32); + let cliff_height = self.get_cliff_height(wpos_turb, &close_cliffs, cliff_hill); - let wpos_turb = Vec2::from(wpos) + turb.map(|e| e as i32); - let cliff_height = self.get_cliff_height(wpos_turb, &close_cliffs, cliff_hill); + (alt + warp).max(cliff_height) + }; - let height = (alt + warp).max(cliff_height); - let water_height = water_level + warp; + (false, height, water_level + warp) + }; // Sample blocks @@ -172,7 +184,7 @@ impl<'a> SamplerMut for BlockGen<'a> { let field2 = RandomField::new(self.world.sim().seed + 2); Some(Block::new( - 2, + 1, stone_col - Rgb::new( field0.get(wpos) as u8 % 32, @@ -226,40 +238,46 @@ impl<'a> SamplerMut for BlockGen<'a> { } } - let block = match block { - Some(block) => block, - None => (&close_trees) - .iter() - .fold(air, |block, (tree_pos, tree_seed)| { - match self.sample_column(Vec2::from(*tree_pos)) { - Some(tree_sample) - if tree_sample.tree_density - > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 - && tree_sample.alt > tree_sample.water_level => - { - let cliff_height = self.get_cliff_height(*tree_pos, &tree_sample.close_cliffs, cliff_hill); - let height = tree_sample.alt.max(cliff_height); - let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, height as i32); - let rpos = wpos - tree_pos3d; + let block = if definitely_underground { + block.unwrap_or(Block::empty()) + } else { + match block { + Some(block) => block, + None => (&close_trees) + .iter() + .fold(air, |block, (tree_pos, tree_seed)| if !block.is_empty() { + block + } else { + match self.sample_column(Vec2::from(*tree_pos)) { + Some(tree_sample) + if tree_sample.tree_density + > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 + && tree_sample.alt > tree_sample.water_level => + { + let cliff_height = self.get_cliff_height(*tree_pos, &tree_sample.close_cliffs, cliff_hill); + let height = tree_sample.alt.max(cliff_height); + let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, height as i32); + let rpos = wpos - tree_pos3d; - let trees = tree::kinds(tree_sample.forest_kind); // Choose tree kind + 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| { - block_from_structure( - *b, - rpos, - *tree_pos, - *tree_seed, - &tree_sample, - ) - }) - .unwrap_or(Block::empty())) + block.or(trees[*tree_seed as usize % trees.len()] + .get((rpos * 128) / 128) // Scaling + .map(|b| { + block_from_structure( + *b, + rpos, + *tree_pos, + *tree_seed, + &tree_sample, + ) + }) + .unwrap_or(Block::empty())) + } + _ => block, } - _ => block, - } - }), + }), + } }; Some(block) diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 1b633beee7..2ee4660d67 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -53,7 +53,7 @@ impl<'a> Sampler for ColumnGen<'a> { .mul((1.0 - (chaos - 0.15) * 20.0).max(0.0).min(1.0)); let cliff_hill = (sim.gen_ctx.small_nz.get((wposf.div(128.0)).into_array()) as f32) - .mul(12.0); + .mul(16.0); let riverless_alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? + (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32) @@ -129,7 +129,7 @@ impl<'a> Sampler for ColumnGen<'a> { .mul((1.15 - chaos).min(1.0)) }; let cave_xy = cave_at(wposf); - let cave_alt = alt - 16.0 + let cave_alt = alt - 24.0 + (sim .gen_ctx .cave_1_nz @@ -138,11 +138,11 @@ impl<'a> Sampler for ColumnGen<'a> { + (sim .gen_ctx .cave_1_nz - .get(Vec2::new(wposf.x, wposf.y).div(300.0).into_array()) as f32) + .get(Vec2::new(wposf.x, wposf.y).div(500.0).into_array()) as f32) .add(1.0) .mul(0.5) - .powf(8.0) - .mul(256.0); + .powf(15.0) + .mul(150.0); Some(ColumnSample { alt, diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 99bdf80c78..eb90ec37fb 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -71,7 +71,7 @@ impl WorldSim { cave_1_nz: SuperSimplex::new().set_seed(seed + 14), tree_gen: StructureGen2d::new(seed, 32, 24), - cliff_gen: StructureGen2d::new(seed, 80, 64), + cliff_gen: StructureGen2d::new(seed, 80, 56), }; let mut chunks = Vec::new(); @@ -229,7 +229,7 @@ impl WorldSim { } } -const Z_TOLERANCE: (f32, f32) = (64.0, 128.0); +const Z_TOLERANCE: (f32, f32) = (100.0, 128.0); pub struct SimChunk { pub chaos: f32, @@ -325,7 +325,7 @@ impl SimChunk { .sub(0.1) .mul(1.3) .max(0.0), - cliffs: cliff > 0.5, + cliffs: cliff > 0.5 && dryness > 0.05, near_cliffs: cliff > 0.4, tree_density: (gen_ctx.tree_nz.get((wposf.div(1024.0)).into_array()) as f32) .add(1.0) diff --git a/world/src/util/random.rs b/world/src/util/random.rs index f7ec6696c2..b5543f7a3e 100644 --- a/world/src/util/random.rs +++ b/world/src/util/random.rs @@ -20,22 +20,19 @@ impl Sampler for RandomField { let next = self.seed.wrapping_mul(0x168E3D1F).wrapping_add(0xDEADBEAD); let next = next - .rotate_left(13) .wrapping_mul(133227) .wrapping_add(pos.x); - let next = next.rotate_left(13).wrapping_mul(318912) ^ 0x42133742; + let next = next.rotate_left(13).wrapping_add(318912) ^ 0x42133742; let next = next - .rotate_left(13) .wrapping_mul(938219) .wrapping_add(pos.y); - let next = next.rotate_left(13).wrapping_mul(318912) ^ 0x23341753; + let next = next.rotate_left(13).wrapping_add(318912) ^ 0x23341753; let next = next - .rotate_left(13) .wrapping_mul(938219) .wrapping_add(pos.z); - let next = next.rotate_left(13).wrapping_mul(313322) ^ 0xDEADBEEF; - let next = next.rotate_left(13).wrapping_mul(929009) ^ 0xFF329DE3; - let next = next.rotate_left(13).wrapping_mul(422671) ^ 0x42892942; - next + let next = next.wrapping_add(313322) ^ 0xDEADBEEF; + let next = next.wrapping_sub(929009) ^ 0xFF329DE3; + let next = next.wrapping_add(422671) ^ 0x42892942; + next.rotate_left(13) } } From 6f1d77648ab55f0e0df3b3aa466cb9aecac8f34b Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Fri, 21 Jun 2019 18:10:21 +0100 Subject: [PATCH 21/40] Smoother cliffs --- world/src/block/mod.rs | 14 +++++++------- world/src/sim/mod.rs | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 6614df71d0..b075a85639 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -39,7 +39,7 @@ impl<'a> BlockGen<'a> { .clone() } - fn get_cliff_height(&self, wpos: Vec2, close_cliffs: &[(Vec2, u32); 9], cliff_hill: f32) -> f32 { + fn get_cliff_height(&self, wpos: Vec2, close_cliffs: &[(Vec2, u32); 9], cliff_hill: f32) -> f32 { close_cliffs .iter() .fold(0.0f32, |max_height, (cliff_pos, seed)| { @@ -50,7 +50,7 @@ impl<'a> BlockGen<'a> { let height = RandomField::new(seed + 1).get(cliff_pos3d) % 48; let radius = RandomField::new(seed + 2).get(cliff_pos3d) % 48 + 8; - max_height.max(if cliff_pos.distance_squared(wpos) < (radius * radius) as i32 { + max_height.max(if cliff_pos.map(|e| e as f32).distance_squared(wpos) < (radius * radius) as f32 { cliff_sample.alt + height as f32 * (1.0 - cliff_sample.chaos) + cliff_hill } else { 0.0 @@ -108,11 +108,11 @@ impl<'a> SamplerMut for BlockGen<'a> { alt + warp } else { let turb = Vec2::new( - self.world.sim().gen_ctx.turb_x_nz.get((wposf.div(64.0)).into_array()) as f32, - self.world.sim().gen_ctx.turb_y_nz.get((wposf.div(64.0)).into_array()) as f32, - ) * 16.0; + self.world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32, + self.world.sim().gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32, + ) * 12.0; - let wpos_turb = Vec2::from(wpos) + turb.map(|e| e as i32); + let wpos_turb = Vec2::from(wpos).map(|e: i32| e as f32) + turb; let cliff_height = self.get_cliff_height(wpos_turb, &close_cliffs, cliff_hill); (alt + warp).max(cliff_height) @@ -254,7 +254,7 @@ impl<'a> SamplerMut for BlockGen<'a> { > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 && tree_sample.alt > tree_sample.water_level => { - let cliff_height = self.get_cliff_height(*tree_pos, &tree_sample.close_cliffs, cliff_hill); + let cliff_height = self.get_cliff_height(tree_pos.map(|e| e as f32), &tree_sample.close_cliffs, cliff_hill); let height = tree_sample.alt.max(cliff_height); let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, height as i32); let rpos = wpos - tree_pos3d; diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index eb90ec37fb..4fc237f460 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -8,7 +8,7 @@ use common::{ terrain::{BiomeKind, TerrainChunkSize}, vol::VolSize, }; -use noise::{BasicMulti, HybridMulti, MultiFractal, NoiseFn, RidgedMulti, Seedable, SuperSimplex}; +use noise::{BasicMulti, HybridMulti, MultiFractal, NoiseFn, RidgedMulti, Seedable, OpenSimplex, SuperSimplex}; use rand::{prng::XorShiftRng, Rng, SeedableRng}; use std::{ ops::{Add, Div, Mul, Neg, Sub}, From b987bda9ce5757939fc8e1be2b11ec4e4f5f5fea Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 22 Jun 2019 15:46:13 +0100 Subject: [PATCH 22/40] Stronger shadows, fewer cliffs in oceans --- assets/world/structures/human/town_hall.vox | 3 +++ common/src/terrain/block.rs | 2 +- voxygen/shaders/postprocess.frag | 1 + world/src/sim/mod.rs | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 assets/world/structures/human/town_hall.vox diff --git a/assets/world/structures/human/town_hall.vox b/assets/world/structures/human/town_hall.vox new file mode 100644 index 0000000000..1b20a5942f --- /dev/null +++ b/assets/world/structures/human/town_hall.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea521079b8b5fe6028e002b95c560d86bece6b11ef7694373b7f211d9076a213 +size 81932 diff --git a/common/src/terrain/block.rs b/common/src/terrain/block.rs index e9cccfd8bf..ef3b5d2ffb 100644 --- a/common/src/terrain/block.rs +++ b/common/src/terrain/block.rs @@ -27,7 +27,7 @@ impl Block { pub fn get_opacity(&self) -> Option { match self.kind { 0 => None, - 1 => Some(0.6), + 1 => Some(0.85), _ => Some(1.0), } } diff --git a/voxygen/shaders/postprocess.frag b/voxygen/shaders/postprocess.frag index f1f644b4e6..4e1adf4040 100644 --- a/voxygen/shaders/postprocess.frag +++ b/voxygen/shaders/postprocess.frag @@ -164,6 +164,7 @@ void main() { vec2 uv = (f_pos + 1.0) * 0.5; vec4 fxaa_color = fxaa_apply(src_color, uv * screen_res.xy, screen_res.xy); + //vec4 fxaa_color = texture(src_color, uv); vec4 hsva_color = vec4(rgb2hsv(fxaa_color.rgb), fxaa_color.a); hsva_color.y *= 1.3; diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 4fc237f460..0d47ae8e75 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -325,7 +325,7 @@ impl SimChunk { .sub(0.1) .mul(1.3) .max(0.0), - cliffs: cliff > 0.5 && dryness > 0.05, + cliffs: cliff > 0.5 && dryness > 0.05 && alt > CONFIG.sea_level + 5.0 && dryness.abs() > 0.075, near_cliffs: cliff > 0.4, tree_density: (gen_ctx.tree_nz.get((wposf.div(1024.0)).into_array()) as f32) .add(1.0) From 1dfc85a75b9b4d291f8f75869f4c7aa5602b463c Mon Sep 17 00:00:00 2001 From: Pfauenauge Date: Wed, 19 Jun 2019 19:13:27 +0200 Subject: [PATCH 23/40] char selection time freeze to prevent it from being dark --- voxygen/src/menu/char_selection/scene.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/voxygen/src/menu/char_selection/scene.rs b/voxygen/src/menu/char_selection/scene.rs index 9ea9a24756..b415cc5c9a 100644 --- a/voxygen/src/menu/char_selection/scene.rs +++ b/voxygen/src/menu/char_selection/scene.rs @@ -84,7 +84,7 @@ impl Scene { .set_orientation(Vec3::new(client.state().get_time() as f32 * 0.0, 0.0, 0.0)); let (view_mat, proj_mat, cam_pos) = self.camera.compute_dependents(client); - + const CHAR_SELECT_TIME_OF_DAY: f32 = 50000.0; // 12*3600 seconds if let Err(err) = renderer.update_consts( &mut self.globals, &[Globals::new( @@ -92,8 +92,8 @@ impl Scene { proj_mat, cam_pos, self.camera.get_focus_pos(), - 100.0, - client.state().get_time_of_day(), + CHAR_SELECT_TIME_OF_DAY, + 500.0, client.state().get_time(), renderer.get_resolution(), )], From b5d529f82456be40630978a00c94f1813a7d6fd8 Mon Sep 17 00:00:00 2001 From: Pfauenauge90 <44173739+Pfauenauge90@users.noreply.github.com> Date: Sat, 22 Jun 2019 16:30:53 +0200 Subject: [PATCH 24/40] changes restore --- assets/voxygen/voxel/fixture/selection_bg.vox | 4 +-- assets/world/structures/human/mage_tower.vox | 3 ++ voxygen/src/hud/map.rs | 34 ++++++++++++++++--- voxygen/src/hud/minimap.rs | 2 +- voxygen/src/hud/mod.rs | 6 ++-- voxygen/src/menu/char_selection/scene.rs | 6 ++-- voxygen/src/menu/char_selection/ui.rs | 6 ++-- voxygen/src/menu/main/ui.rs | 25 ++++++++------ world/src/sim/location.rs | 14 ++++---- 9 files changed, 66 insertions(+), 34 deletions(-) create mode 100644 assets/world/structures/human/mage_tower.vox diff --git a/assets/voxygen/voxel/fixture/selection_bg.vox b/assets/voxygen/voxel/fixture/selection_bg.vox index 66dc4a639e..0c8ce0e625 100644 --- a/assets/voxygen/voxel/fixture/selection_bg.vox +++ b/assets/voxygen/voxel/fixture/selection_bg.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4d0c91d3e411f26f9fb0675ddbd00f02120d9396cc40c6f6e39cbf2be962d640 -size 594518 +oid sha256:8604501bac76da9bd609a2c1aa0ea8162c6c1b92884017451b8d781d92a4eff9 +size 594480 diff --git a/assets/world/structures/human/mage_tower.vox b/assets/world/structures/human/mage_tower.vox new file mode 100644 index 0000000000..7df09363c0 --- /dev/null +++ b/assets/world/structures/human/mage_tower.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b6ed2f574af13b79f6cb6df5450068cc637372a24a739a892d55d4b1ff4f287b +size 125468 diff --git a/voxygen/src/hud/map.rs b/voxygen/src/hud/map.rs index a21a5f2b7f..f0c851c2e0 100644 --- a/voxygen/src/hud/map.rs +++ b/voxygen/src/hud/map.rs @@ -1,10 +1,13 @@ use conrod_core::{ color, - widget::{self, Button, Image, Rectangle}, - widget_ids, Positionable, Sizeable, Widget, WidgetCommon, + widget::{self, Button, Image, Rectangle, Text}, + widget_ids, Colorable, Positionable, Sizeable, Widget, WidgetCommon, }; -use super::{img_ids::Imgs, Fonts}; +use super::{img_ids::Imgs, Fonts, Show, TEXT_COLOR_2}; +use client::{self, Client}; + +use std::{cell::RefCell, rc::Rc}; widget_ids! { struct Ids { @@ -17,22 +20,28 @@ widget_ids! { map_frame_r, map_frame_bl, map_frame_br, + location_name, } } #[derive(WidgetCommon)] pub struct Map<'a> { + show: &'a Show, + + client: &'a Client, + imgs: &'a Imgs, fonts: &'a Fonts, #[conrod(common_builder)] common: widget::CommonBuilder, } - impl<'a> Map<'a> { - pub fn new(imgs: &'a Imgs, fonts: &'a Fonts) -> Self { + pub fn new(show: &'a Show, client: &'a Client, imgs: &'a Imgs, fonts: &'a Fonts) -> Self { Self { + show, imgs, + client, fonts, common: widget::CommonBuilder::default(), } @@ -108,6 +117,21 @@ impl<'a> Widget for Map<'a> { return Some(Event::Close); } + // Location Name + match self.client.current_chunk() { + Some(chunk) => Text::new(chunk.meta().name()) + .mid_top_with_margin_on(state.ids.map_bg, 40.0) + .font_size(40) + .color(TEXT_COLOR_2) + .parent(state.ids.map_frame_r) + .set(state.ids.location_name, ui), + None => Text::new(" ") + .mid_top_with_margin_on(state.ids.map_bg, 3.0) + .font_size(40) + .color(TEXT_COLOR_2) + .set(state.ids.location_name, ui), + } + None } } diff --git a/voxygen/src/hud/minimap.rs b/voxygen/src/hud/minimap.rs index b5af29d57e..f1a9755562 100644 --- a/voxygen/src/hud/minimap.rs +++ b/voxygen/src/hud/minimap.rs @@ -115,7 +115,7 @@ impl<'a> Widget for MiniMap<'a> { .font_size(14) .color(TEXT_COLOR) .set(state.ids.mmap_location, ui), - None => Text::new("Wait what") + None => Text::new(" ") .mid_top_with_margin_on(state.ids.mmap_frame, 3.0) .font_size(14) .color(TEXT_COLOR) diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 0349c4bc6a..9e9e9c4d8b 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -43,6 +43,7 @@ use vek::*; const XP_COLOR: Color = Color::Rgba(0.59, 0.41, 0.67, 1.0); const TEXT_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0); +const TEXT_COLOR_2: Color = Color::Rgba(0.0, 0.0, 0.0, 1.0); const HP_COLOR: Color = Color::Rgba(0.33, 0.63, 0.0, 1.0); const MANA_COLOR: Color = Color::Rgba(0.42, 0.41, 0.66, 1.0); @@ -641,7 +642,9 @@ impl Hud { // Map if self.show.map { - match Map::new(&self.imgs, &self.fonts).set(self.ids.map, ui_widgets) { + match Map::new(&self.show, client, &self.imgs, &self.fonts) + .set(self.ids.map, ui_widgets) + { Some(map::Event::Close) => { self.show.map(false); self.force_ungrab = true; @@ -650,7 +653,6 @@ impl Hud { } } - // Esc-menu if self.show.esc_menu { match EscMenu::new(&self.imgs, &self.fonts).set(self.ids.esc_menu, ui_widgets) { Some(esc_menu::Event::OpenSettings(tab)) => { diff --git a/voxygen/src/menu/char_selection/scene.rs b/voxygen/src/menu/char_selection/scene.rs index b415cc5c9a..f18c191fc1 100644 --- a/voxygen/src/menu/char_selection/scene.rs +++ b/voxygen/src/menu/char_selection/scene.rs @@ -65,7 +65,7 @@ impl Scene { backdrop_model: renderer .create_model(&FigureModelCache::load_mesh( "fixture/selection_bg.vox", - Vec3::new(-55.0, -50.0, -1.0), + Vec3::new(-55.0, -49.5, -2.0), )) .unwrap(), backdrop_state: FigureState::new(renderer, FixtureSkeleton::new()), @@ -84,7 +84,7 @@ impl Scene { .set_orientation(Vec3::new(client.state().get_time() as f32 * 0.0, 0.0, 0.0)); let (view_mat, proj_mat, cam_pos) = self.camera.compute_dependents(client); - const CHAR_SELECT_TIME_OF_DAY: f32 = 50000.0; // 12*3600 seconds + const CHAR_SELECT_TIME_OF_DAY: f32 = 80000.0; // 12*3600 seconds if let Err(err) = renderer.update_consts( &mut self.globals, &[Globals::new( @@ -93,7 +93,7 @@ impl Scene { cam_pos, self.camera.get_focus_pos(), CHAR_SELECT_TIME_OF_DAY, - 500.0, + 55800.0, client.state().get_time(), renderer.get_resolution(), )], diff --git a/voxygen/src/menu/char_selection/ui.rs b/voxygen/src/menu/char_selection/ui.rs index 23a83f76a5..31ced8fcda 100644 --- a/voxygen/src/menu/char_selection/ui.rs +++ b/voxygen/src/menu/char_selection/ui.rs @@ -141,8 +141,7 @@ widget_ids! { image_ids! { struct Imgs { - - v_logo: "voxygen/element/v_logo.vox", + button: "voxygen/element/buttons/button.vox", button_hover: "voxygen/element/buttons/button_hover.vox", button_press: "voxygen/element/buttons/button_press.vox", @@ -170,8 +169,7 @@ image_ids! { frame_open_press: "voxygen/element/buttons/frame/open_press.png", skin_eyes_window: "voxygen/element/frames/skin_eyes.png", hair_window: "voxygen/element/frames/skin_eyes.png", - accessories_window: "voxygen/element/frames/skin_eyes.png", - color_picker_bg: "voxygen/element/misc_bg/color_picker_blank.png", + accessories_window: "voxygen/element/frames/skin_eyes.png", slider_range: "voxygen/element/slider/track.png", slider_indicator: "voxygen/element/slider/indicator.png", window_frame_2: "voxygen/element/frames/window_2.png", diff --git a/voxygen/src/menu/main/ui.rs b/voxygen/src/menu/main/ui.rs index 380666ac99..99f8b6a7e5 100644 --- a/voxygen/src/menu/main/ui.rs +++ b/voxygen/src/menu/main/ui.rs @@ -70,7 +70,9 @@ image_ids! { bg: "voxygen/background/bg_main.png", error_frame: "voxygen/element/frames/window_2.png", + nothing: "voxygen/element/nothing.png", } + } font_ids! { @@ -137,6 +139,7 @@ impl MainMenuUi { let ref mut ui_widgets = self.ui.set_widgets(); let version = env!("CARGO_PKG_VERSION"); const TEXT_COLOR: Color = Color::Rgba(1.0, 1.0, 1.0, 1.0); + const TEXT_COLOR_2: Color = Color::Rgba(1.0, 1.0, 1.0, 0.2); // Background image, Veloren logo, Alpha-Version Label Image::new(self.imgs.bg) .middle_of(ui_widgets.window) @@ -302,8 +305,8 @@ impl MainMenuUi { } if self.show_servers { Image::new(self.imgs.error_frame) - .top_left_with_margins_on(ui_widgets.window, 3.0, 3.0) - .w_h(400.0, 400.0) + .mid_top_with_margin_on(self.ids.username_bg, -320.0) + .w_h(400.0, 300.0) .set(self.ids.servers_frame, ui_widgets); let net_settings = &global_state.settings.networking; @@ -320,7 +323,7 @@ impl MainMenuUi { while let Some(item) = items.next(ui_widgets) { let mut text = "".to_string(); if &net_settings.servers[item.i] == &self.server_address { - text.push_str("* ") + text.push_str("-> ") } else { text.push_str(" ") } @@ -328,11 +331,11 @@ impl MainMenuUi { if item .set( - Button::image(self.imgs.button) - .w_h(100.0, 53.0) - .mid_bottom_with_margin_on(self.ids.servers_frame, 5.0) - .hover_image(self.imgs.button_hover) - .press_image(self.imgs.button_press) + Button::image(self.imgs.nothing) + .w_h(100.0, 50.0) + .mid_top_with_margin_on(self.ids.servers_frame, 10.0) + //.hover_image(self.imgs.button_hover) + //.press_image(self.imgs.button_press) .label_y(Relative::Scalar(2.0)) .label(&text) .label_font_size(20) @@ -465,10 +468,10 @@ impl MainMenuUi { if Button::image(self.imgs.button) .w_h(190.0, 40.0) .up_from(self.ids.quit_button, 8.0) - .hover_image(self.imgs.button_hover) - .press_image(self.imgs.button_press) + //.hover_image(self.imgs.button_hover) + //.press_image(self.imgs.button_press) .label("Settings") - .label_color(TEXT_COLOR) + .label_color(TEXT_COLOR_2) .label_font_size(20) .label_y(Relative::Scalar(3.0)) .set(self.ids.settings_button, ui_widgets) diff --git a/world/src/sim/location.rs b/world/src/sim/location.rs index 4995cc0e58..49e01632e7 100644 --- a/world/src/sim/location.rs +++ b/world/src/sim/location.rs @@ -42,16 +42,18 @@ pub struct Kingdom { fn generate_name(rng: &mut R) -> String { let firstsyl = [ "Eri", "Val", "Gla", "Wilde", "Cold", "Deep", "Dura", "Ester", "Fay", "Dark", "West", - "East", "North", "South", "Ray", "Eri", "Dal", "Som", "Black", "Iron", "Grey", "Hel", - "Gal", "Mor", "Lo", "Nil", "Mana", "Gar", "Mountain", + "East", "North", "South", "Ray", "Eri", "Dal", "Som", "Sommer", "Black", "Iron", "Grey", + "Hel", "Gal", "Mor", "Lo", "Nil", "Bel", "Lor", "Gold", "Red", "Marble", "Mana", "Gar", + "Mountain", "Red", "Cheo", "Far", "High", ]; - let mid = ["ka", "se", "au", "da", "di", "u"]; + let mid = ["ka", "se", "au", "da", "di"]; let tails = [ - "mill", "ben", "sel", "dori", "theas", "dar", "bur", "to", "vis", "ten", "stone", "tiva", + /*"mill",*/ "ben", "sel", "dori", "theas", "dar", "bur", "to", "vis", "ten", "stone", "tiva", "id", "and", "or", "el", "ond", "ia", "eld", "ald", "aft", "ift", "ity", "well", "oll", - "ill", "all", "wyn", "light", "hill", "lin", "mont", "mor", "cliff", "rok", "den", "mi", + "ill", "all", "wyn", "light", " Hill", "lin", "mont", "mor", "cliff", "rok", "den", "mi", "rock", "glenn", "rovi", "lea", "gate", "view", "ley", "wood", "ovia", "cliff", "marsh", - "kor", "light", "ice", "river", "venn", "vale", + "kor", "ice", /*"river",*/ "acre", "venn", "crest", "field", "vale", "spring", " Vale", + "grasp", "fel", "fall", "grove", "wyn", "edge", ]; let mut name = String::new(); From d75160e2f86d184f580ac5d21e242b07990dd1f2 Mon Sep 17 00:00:00 2001 From: Pfauenauge90 <44173739+Pfauenauge90@users.noreply.github.com> Date: Sat, 22 Jun 2019 17:18:10 +0200 Subject: [PATCH 25/40] oak size changes --- assets/world/tree/oak_green/1.vox | 4 ++-- assets/world/tree/oak_green/2.vox | 4 ++-- assets/world/tree/oak_green/4.vox | 4 ++-- assets/world/tree/oak_green/5.vox | 4 ++-- assets/world/tree/oak_green/6.vox | 4 ++-- assets/world/tree/oak_green/7.vox | 4 ++-- assets/world/tree/oak_green/8.vox | 4 ++-- assets/world/tree/oak_green/9.vox | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/assets/world/tree/oak_green/1.vox b/assets/world/tree/oak_green/1.vox index 7127afa54f..c2227fc623 100644 --- a/assets/world/tree/oak_green/1.vox +++ b/assets/world/tree/oak_green/1.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:92988d46dde3a0c9c7af42a4042b13de2eebf2f904a0b3679e792fc917b24dea -size 80836 +oid sha256:90cb2531d3a7bbf5a856b93abed2b4fa6c99038d2b1c119c01319e9bc6b092bd +size 80540 diff --git a/assets/world/tree/oak_green/2.vox b/assets/world/tree/oak_green/2.vox index 6000db082d..1ab9fe3e60 100644 --- a/assets/world/tree/oak_green/2.vox +++ b/assets/world/tree/oak_green/2.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f7c62ea16914827fc4e6c3030161e0b910ecbdb7d0db3f55bbe8a251e859fb5 -size 89252 +oid sha256:8cbe46a82f64ec25e3dba71606d2215e601b2bc643b7422fb50a8f1d253fb531 +size 88800 diff --git a/assets/world/tree/oak_green/4.vox b/assets/world/tree/oak_green/4.vox index 80872fb4da..7bcd66bd37 100644 --- a/assets/world/tree/oak_green/4.vox +++ b/assets/world/tree/oak_green/4.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3a204b1300be9fe810f56c0f483f2fe3cacc73d35b57d0bf68d93bef5295ef44 -size 89944 +oid sha256:5862b4a6bf51df3a0659e1f007cf408714a4db659fda78370b5fad732c08eaa9 +size 89452 diff --git a/assets/world/tree/oak_green/5.vox b/assets/world/tree/oak_green/5.vox index 149167f780..bb1700709a 100644 --- a/assets/world/tree/oak_green/5.vox +++ b/assets/world/tree/oak_green/5.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db82d0f9c734ca5316be1965676bd49eea6c894e38033144b8f6e6430edac8cd -size 95628 +oid sha256:ee602e8454202dda569c4d03a2b52024f16b0b546c6b363f128d823f107d1e4f +size 95176 diff --git a/assets/world/tree/oak_green/6.vox b/assets/world/tree/oak_green/6.vox index b3875dafee..44a55fa64e 100644 --- a/assets/world/tree/oak_green/6.vox +++ b/assets/world/tree/oak_green/6.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8dba4cac13e74efefdaf60d4e3e4d11caa092f85edb7364cee8ef9a990ae441c -size 114484 +oid sha256:257fbc96e69cf00c6b0dd93df953dea53ee3cf628e296ba04259f887e83d7d1b +size 112496 diff --git a/assets/world/tree/oak_green/7.vox b/assets/world/tree/oak_green/7.vox index 2d77ba69cd..4809311ae6 100644 --- a/assets/world/tree/oak_green/7.vox +++ b/assets/world/tree/oak_green/7.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c662098c6d0dac131d718d4734f2eb6f4fe1ee0934eb193c52dea8015e7c8cd7 -size 124884 +oid sha256:6623f234e6a591a4f73934f192351eec1280a0c92208cd6e227e4c368a7e2e14 +size 123856 diff --git a/assets/world/tree/oak_green/8.vox b/assets/world/tree/oak_green/8.vox index f58e824b3b..76bcb46efc 100644 --- a/assets/world/tree/oak_green/8.vox +++ b/assets/world/tree/oak_green/8.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c7a6925cf4085bfe315fc31052f82d958fd3df33492c98a165722ea794fff484 -size 117340 +oid sha256:c44033a6b7996f42022f79cb18323431f06dae59273713f3b943cad2a4cb6f2e +size 116232 diff --git a/assets/world/tree/oak_green/9.vox b/assets/world/tree/oak_green/9.vox index fb408054fe..159806222c 100644 --- a/assets/world/tree/oak_green/9.vox +++ b/assets/world/tree/oak_green/9.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1cf00092594f397180875ae4ad1f2fc4b220a526ac5782c3158f5c91f1bda08e -size 188286 +oid sha256:bddbc5e61b2f376653af7a567b946a1f8d7ede17c2ae8c3bc7053db5fa9575f8 +size 124118 From b94c0ace8c17ddc403af4bb440b21977eec45b60 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 22 Jun 2019 16:53:21 +0100 Subject: [PATCH 26/40] Removed RefCell from column cache --- assets/world/structures/human/town_hall.vox | 4 +- voxygen/src/mesh/terrain.rs | 2 +- world/src/block/mod.rs | 52 ++++++++++++--------- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/assets/world/structures/human/town_hall.vox b/assets/world/structures/human/town_hall.vox index 1b20a5942f..8befbaa750 100644 --- a/assets/world/structures/human/town_hall.vox +++ b/assets/world/structures/human/town_hall.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea521079b8b5fe6028e002b95c560d86bece6b11ef7694373b7f211d9076a213 -size 81932 +oid sha256:42595711180fbecf049f52b4e4c39a8d34d732d4aae841e7e32bd317a39c49e2 +size 80900 diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index cdfebd7871..839092caa4 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -104,7 +104,7 @@ impl + ReadVol + Debug, S: VolSize + Clone> Meshable for .ok() .and_then(|vox| vox.get_opacity()) { - (neighbour_light[0][i][j] * (1.0 - opacity * 0.4)) + (neighbour_light[0][i][j] * (1.0 - opacity * 0.1)) .max(1.0 - opacity) } else { (neighbour_light[0][i][j] * 1.025).min(1.0) diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index b075a85639..bc9b365660 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -10,15 +10,12 @@ use common::{ vol::{ReadVol, Vox}, }; use noise::NoiseFn; -use std::{ - cell::RefCell, - ops::{Add, Div, Mul, Neg, Sub}, -}; +use std::ops::{Add, Div, Mul, Neg, Sub}; use vek::*; pub struct BlockGen<'a> { world: &'a World, - column_cache: RefCell, Option>>>, + column_cache: HashCache, Option>>, column_gen: ColumnGen<'a>, } @@ -26,24 +23,31 @@ impl<'a> BlockGen<'a> { pub fn new(world: &'a World, column_gen: ColumnGen<'a>) -> Self { Self { world, - column_cache: RefCell::new(HashCache::with_capacity(1024)), + column_cache: HashCache::with_capacity(64), column_gen, } } - fn sample_column(&self, wpos: Vec2) -> Option { - let column_gen = &self.column_gen; - self.column_cache - .borrow_mut() + fn sample_column( + column_gen: &ColumnGen<'a>, + cache: &mut HashCache, Option>>, wpos: Vec2, + ) -> Option> { + cache .get(Vec2::from(wpos), |wpos| column_gen.get(wpos)) .clone() } - fn get_cliff_height(&self, wpos: Vec2, close_cliffs: &[(Vec2, u32); 9], cliff_hill: f32) -> f32 { + fn get_cliff_height( + column_gen: &ColumnGen<'a>, + cache: &mut HashCache, Option>>, + wpos: Vec2, + close_cliffs: &[(Vec2, u32); 9], + cliff_hill: f32, + ) -> f32 { close_cliffs .iter() .fold(0.0f32, |max_height, (cliff_pos, seed)| { - match self.sample_column(Vec2::from(*cliff_pos)) { + match Self::sample_column(column_gen, cache, Vec2::from(*cliff_pos)) { Some(cliff_sample) if cliff_sample.cliffs => { let cliff_pos3d = Vec3::from(*cliff_pos); @@ -67,6 +71,12 @@ impl<'a> SamplerMut for BlockGen<'a> { type Sample = Option; fn get(&mut self, wpos: Vec3) -> Option { + let BlockGen { + world, + column_cache, + column_gen, + } = self; + let ColumnSample { alt, chaos, @@ -84,7 +94,7 @@ impl<'a> SamplerMut for BlockGen<'a> { close_cliffs, temp, .. - } = self.sample_column(Vec2::from(wpos))?; + } = Self::sample_column(column_gen, column_cache, Vec2::from(wpos))?; let wposf = wpos.map(|e| e as f64); @@ -108,12 +118,12 @@ impl<'a> SamplerMut for BlockGen<'a> { alt + warp } else { let turb = Vec2::new( - self.world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32, - self.world.sim().gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32, + world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32, + world.sim().gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32, ) * 12.0; let wpos_turb = Vec2::from(wpos).map(|e: i32| e as f32) + turb; - let cliff_height = self.get_cliff_height(wpos_turb, &close_cliffs, cliff_hill); + let cliff_height = Self::get_cliff_height(column_gen, column_cache, wpos_turb, &close_cliffs, cliff_hill); (alt + warp).max(cliff_height) }; @@ -179,9 +189,9 @@ impl<'a> SamplerMut for BlockGen<'a> { // Rocks let block = block.or_else(|| { if (height + 2.5 - wposf.z as f32).div(7.5).abs().powf(2.0) < rock { - let field0 = RandomField::new(self.world.sim().seed + 0); - let field1 = RandomField::new(self.world.sim().seed + 1); - let field2 = RandomField::new(self.world.sim().seed + 2); + let field0 = RandomField::new(world.sim().seed + 0); + let field1 = RandomField::new(world.sim().seed + 1); + let field2 = RandomField::new(world.sim().seed + 2); Some(Block::new( 1, @@ -248,13 +258,13 @@ impl<'a> SamplerMut for BlockGen<'a> { .fold(air, |block, (tree_pos, tree_seed)| if !block.is_empty() { block } else { - match self.sample_column(Vec2::from(*tree_pos)) { + match Self::sample_column(column_gen, column_cache, Vec2::from(*tree_pos)) { Some(tree_sample) if tree_sample.tree_density > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 && tree_sample.alt > tree_sample.water_level => { - let cliff_height = self.get_cliff_height(tree_pos.map(|e| e as f32), &tree_sample.close_cliffs, cliff_hill); + let cliff_height = Self::get_cliff_height(column_gen, column_cache, tree_pos.map(|e| e as f32), &tree_sample.close_cliffs, cliff_hill); let height = tree_sample.alt.max(cliff_height); let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, height as i32); let rpos = wpos - tree_pos3d; From 86f13af8cb578d3c125a763969708f82a3973032 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 22 Jun 2019 18:37:48 +0100 Subject: [PATCH 27/40] Improved hash RNG function instability and speed --- world/src/util/random.rs | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/world/src/util/random.rs b/world/src/util/random.rs index b5543f7a3e..6e30b635bb 100644 --- a/world/src/util/random.rs +++ b/world/src/util/random.rs @@ -18,21 +18,20 @@ impl Sampler for RandomField { fn get(&self, pos: Self::Index) -> Self::Sample { let pos = pos.map(|e| (e * 13 + (1 << 31)) as u32); - let next = self.seed.wrapping_mul(0x168E3D1F).wrapping_add(0xDEADBEAD); - let next = next - .wrapping_mul(133227) - .wrapping_add(pos.x); - let next = next.rotate_left(13).wrapping_add(318912) ^ 0x42133742; - let next = next - .wrapping_mul(938219) - .wrapping_add(pos.y); - let next = next.rotate_left(13).wrapping_add(318912) ^ 0x23341753; - let next = next - .wrapping_mul(938219) - .wrapping_add(pos.z); - let next = next.wrapping_add(313322) ^ 0xDEADBEEF; - let next = next.wrapping_sub(929009) ^ 0xFF329DE3; - let next = next.wrapping_add(422671) ^ 0x42892942; - next.rotate_left(13) + let mut a = self.seed; + a = (a ^ 61) ^ (a >> 16); + a = a + (a << 3); + a = a ^ pos.x; + a = a ^ (a >> 4); + a = a * 0x27d4eb2d; + a = a ^ (a >> 15); + a = a ^ pos.y; + a = (a ^ 61) ^ (a >> 16); + a = a + (a << 3); + a = a ^ (a >> 4); + a = a ^ pos.z; + a = a * 0x27d4eb2d; + a = a ^ (a >> 15); + a } } From 216c2583fb75b766779b733493a1fd99857ff997 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 22 Jun 2019 22:44:27 +0100 Subject: [PATCH 28/40] Paths and smoother region borders --- world/examples/view.rs | 8 ++-- world/src/block/mod.rs | 3 +- world/src/column/mod.rs | 34 ++++++++++++- world/src/lib.rs | 2 +- world/src/sim/mod.rs | 104 ++++++++++++++++++++++++++++++++++++---- 5 files changed, 132 insertions(+), 19 deletions(-) diff --git a/world/examples/view.rs b/world/examples/view.rs index 61b100e140..2fa077389e 100644 --- a/world/examples/view.rs +++ b/world/examples/view.rs @@ -37,8 +37,8 @@ fn main() { let loc_color = location .map(|l| { ( - l.name().bytes().nth(0).unwrap() * 17, - l.name().bytes().nth(1).unwrap() * 17, + l.loc.name().bytes().nth(0).unwrap() * 17, + l.loc.name().bytes().nth(1).unwrap() * 17, ) }) .unwrap_or((0, 0)); @@ -67,10 +67,10 @@ fn main() { gain -= 10.0; } if win.is_key_down(minifb::Key::R) { - scale += 1; + scale += 6; } if win.is_key_down(minifb::Key::F) { - scale -= 1; + scale -= 6; } win.update_with_buffer(&buf).unwrap(); diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index bc9b365660..52a417a92d 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -103,8 +103,7 @@ impl<'a> SamplerMut for BlockGen<'a> { (true, alt, water_level) } else { // Apply warping - let warp = (self - .world + let warp = (world .sim() .gen_ctx .warp_nz diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 2ee4660d67..20027229ab 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -1,4 +1,10 @@ -use crate::{all::ForestKind, sim::Location, util::Sampler, World, CONFIG}; +use crate::{ + all::ForestKind, + sim::{Location, LocationInfo}, + util::Sampler, + World, + CONFIG, +}; use common::{ terrain::{Block, TerrainChunkSize}, vol::{VolSize, Vox}, @@ -116,6 +122,30 @@ impl<'a> Sampler for ColumnGen<'a> { temp.sub(CONFIG.desert_temp).mul(32.0), ); + // Work out if we're on a path + let near_0 = sim_chunk.location.as_ref().map(|l| l.near[0].block_pos).unwrap_or(Vec2::zero()).map(|e| e as f32); + let near_1 = sim_chunk.location.as_ref().map(|l| l.near[1].block_pos).unwrap_or(Vec2::zero()).map(|e| e as f32); + + let dist_to_path = (0.0 + + (near_1.y - near_0.y) * wposf.x as f32 + - (near_1.x - near_0.x) * wposf.y as f32 + + near_1.x * near_0.y + - near_0.x * near_1.y) + .abs() + .div(near_0.distance(near_1)); + + let alt = if dist_to_path < 15.0 { + alt - 100.0 + } else { + alt + }; + + let ground = if dist_to_path < 5.0 { + Rgb::new(0.0, 0.0, 0.0) + } else { + ground + }; + // Caves let cave_at = |wposf: Vec2| { (sim.gen_ctx.cave_0_nz.get( @@ -202,5 +232,5 @@ pub struct ColumnSample<'a> { pub cliff_hill: f32, pub close_cliffs: [(Vec2, u32); 9], pub temp: f32, - pub location: Option<&'a Arc>, + pub location: Option<&'a LocationInfo>, } diff --git a/world/src/lib.rs b/world/src/lib.rs index 5c4a4b56f5..36af8e2536 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(euclidean_division, bind_by_move_pattern_guards)] +#![feature(euclidean_division, bind_by_move_pattern_guards, option_flattening)] mod all; mod block; diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 0d47ae8e75..0f57feb2db 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -3,7 +3,11 @@ mod location; // Reexports pub use self::location::Location; -use crate::{all::ForestKind, util::StructureGen2d, CONFIG}; +use crate::{ + all::ForestKind, + util::{StructureGen2d, Sampler}, + CONFIG, +}; use common::{ terrain::{BiomeKind, TerrainChunkSize}, vol::VolSize, @@ -115,14 +119,80 @@ impl WorldSim { pub fn seed_elements(&mut self) { let mut rng = self.rng.clone(); - for _ in 0..250 { - let loc_center = Vec2::new( - self.rng.gen::() % WORLD_SIZE.x as i32, - self.rng.gen::() % WORLD_SIZE.y as i32, - ); + let cell_size = 32; + let grid_size = WORLD_SIZE / cell_size; + let loc_count = 250; - if let Some(chunk) = self.get_mut(loc_center) { - chunk.location = Some(Location::generate(loc_center, &mut rng).into()); + let mut locations = vec![None; grid_size.product()]; + + // Seed the world with some locations + for _ in 0..loc_count { + let cell_pos = Vec2::new( + self.rng.gen::() % grid_size.x, + self.rng.gen::() % grid_size.y, + ); + let wpos = (cell_pos * cell_size) + .map2( + Vec2::from(TerrainChunkSize::SIZE), + |e, sz: u32| e as i32 * sz as i32, + ); + + locations[cell_pos.y * grid_size.x + cell_pos.x] = Some(Arc::new(Location::generate(wpos, &mut rng))); + } + + // Simulate invasion! + let invasion_cycles = 25; + for _ in 0..invasion_cycles { + for i in 0..grid_size.x { + for j in 0..grid_size.y { + if locations[j * grid_size.x + i].is_none() { + const R_COORDS: [i32; 5] = [-1, 0, 1, 0, -1]; + let idx = self.rng.gen::() % 4; + let loc = Vec2::new( + i as i32 + R_COORDS[idx], + j as i32 + R_COORDS[idx + 1], + ).map(|e| e as usize); + + locations[j * grid_size.x + i] = locations + .get(loc.y * grid_size.x + loc.x) + .cloned() + .flatten(); + } + } + } + } + + // Place the locations onto the world + let gen = StructureGen2d::new(self.seed, cell_size as u32, cell_size as u32 / 2); + for i in 0..WORLD_SIZE.x { + for j in 0..WORLD_SIZE.y { + let chunk_pos = Vec2::new(i as i32, j as i32); + let cell_pos = Vec2::new(i / cell_size, j / cell_size); + + // Find the distance to each region + let near = gen.get(chunk_pos); + let mut near = near + .iter() + .map(|(pos, seed)| RegionInfo { + chunk_pos: *pos, + block_pos: pos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| e * sz as i32), + dist: (pos - chunk_pos).map(|e| e as f32).magnitude(), + seed: *seed, + }) + .collect::>(); + + // Sort regions based on distance + near.sort_by(|a, b| a.dist.partial_cmp(&b.dist).unwrap()); + + let nearest_cell_pos = near[0].chunk_pos.map(|e| e as usize) / cell_size; + self.get_mut(chunk_pos).unwrap().location = locations + .get(nearest_cell_pos.y * grid_size.x + nearest_cell_pos.x) + .cloned() + .unwrap_or(None) + .map(|loc| LocationInfo { + loc, + near, + }); } } @@ -242,7 +312,21 @@ pub struct SimChunk { pub near_cliffs: bool, pub tree_density: f32, pub forest_kind: ForestKind, - pub location: Option>, + pub location: Option, +} + +#[derive(Copy, Clone)] +pub struct RegionInfo { + pub chunk_pos: Vec2, + pub block_pos: Vec2, + pub dist: f32, + pub seed: u32, +} + +#[derive(Clone)] +pub struct LocationInfo { + pub loc: Arc, + pub near: Vec, } impl SimChunk { @@ -367,7 +451,7 @@ impl SimChunk { } pub fn get_name(&self) -> Option { - self.location.as_ref().map(|l| l.name().to_string()) + self.location.as_ref().map(|l| l.loc.name().to_string()) } pub fn get_biome(&self) -> BiomeKind { From 53d5cada93a8c06a764c701962b7473f01b2895c Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 22 Jun 2019 23:40:41 +0100 Subject: [PATCH 29/40] Better paths --- world/src/column/mod.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 20027229ab..8e52c2e231 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -134,16 +134,10 @@ impl<'a> Sampler for ColumnGen<'a> { .abs() .div(near_0.distance(near_1)); - let alt = if dist_to_path < 15.0 { - alt - 100.0 + let (alt, ground) = if dist_to_path < 5.0 { + (alt - 1.5, Rgb::new(0.4, 0.25, 0.0)) } else { - alt - }; - - let ground = if dist_to_path < 5.0 { - Rgb::new(0.0, 0.0, 0.0) - } else { - ground + (alt, ground) }; // Caves From ba4b425e99a949c7fac2ff3764a41cba5b329b2c Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Jun 2019 00:08:21 +0100 Subject: [PATCH 30/40] Wavy paths --- world/src/column/mod.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 8e52c2e231..9fc77b8410 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -39,6 +39,12 @@ impl<'a> Sampler for ColumnGen<'a> { let sim = self.world.sim(); + let turb = Vec2::new( + world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32, + world.sim().gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32, + ) * 12.0; + let wposf_turb = wposf + turb; + let alt_base = sim.get_interpolated(wpos, |chunk| chunk.alt_base)?; let chaos = sim.get_interpolated(wpos, |chunk| chunk.chaos)?; let temp = sim.get_interpolated(wpos, |chunk| chunk.temp)?; @@ -127,8 +133,8 @@ impl<'a> Sampler for ColumnGen<'a> { let near_1 = sim_chunk.location.as_ref().map(|l| l.near[1].block_pos).unwrap_or(Vec2::zero()).map(|e| e as f32); let dist_to_path = (0.0 - + (near_1.y - near_0.y) * wposf.x as f32 - - (near_1.x - near_0.x) * wposf.y as f32 + + (near_1.y - near_0.y) * wposf_turb.x as f32 + - (near_1.x - near_0.x) * wposf_turb.y as f32 + near_1.x * near_0.y - near_0.x * near_1.y) .abs() From 41f647e862080fafeaa843fa0295e4822ac93e71 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Jun 2019 00:13:59 +0100 Subject: [PATCH 31/40] Added path colouring --- world/src/column/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 9fc77b8410..3be71ba02d 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -40,10 +40,10 @@ impl<'a> Sampler for ColumnGen<'a> { let sim = self.world.sim(); let turb = Vec2::new( - world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32, - world.sim().gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32, + 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; - let wposf_turb = wposf + turb; + let wposf_turb = wposf + turb.map(|e| e as f64); let alt_base = sim.get_interpolated(wpos, |chunk| chunk.alt_base)?; let chaos = sim.get_interpolated(wpos, |chunk| chunk.chaos)?; @@ -141,7 +141,11 @@ impl<'a> Sampler for ColumnGen<'a> { .div(near_0.distance(near_1)); let (alt, ground) = if dist_to_path < 5.0 { - (alt - 1.5, Rgb::new(0.4, 0.25, 0.0)) + (alt - 1.5, Lerp::lerp( + Rgb::new(0.25, 0.15, 0.05), + Rgb::new(0.4, 0.25, 0.0), + marble, + )) } else { (alt, ground) }; From 46fce696a2292a1f1c840874cf14b33783e47681 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Jun 2019 00:56:42 +0100 Subject: [PATCH 32/40] Better path noise, better shadows --- common/src/terrain/block.rs | 2 +- world/src/column/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/terrain/block.rs b/common/src/terrain/block.rs index ef3b5d2ffb..fce23c4a57 100644 --- a/common/src/terrain/block.rs +++ b/common/src/terrain/block.rs @@ -28,7 +28,7 @@ impl Block { match self.kind { 0 => None, 1 => Some(0.85), - _ => Some(1.0), + _ => Some(3.0), } } } diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 3be71ba02d..43e5acf019 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -142,7 +142,7 @@ impl<'a> Sampler for ColumnGen<'a> { let (alt, ground) = if dist_to_path < 5.0 { (alt - 1.5, Lerp::lerp( - Rgb::new(0.25, 0.15, 0.05), + Rgb::new(0.15, 0.075, 0.05), Rgb::new(0.4, 0.25, 0.0), marble, )) From 0734529ef67c1175b3b8624c29d4e007606cc04f Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Jun 2019 11:53:44 +0100 Subject: [PATCH 33/40] Made postprocessing brighter --- assets/world/structures/human/town_hall_spire.vox | 3 +++ voxygen/shaders/postprocess.frag | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 assets/world/structures/human/town_hall_spire.vox diff --git a/assets/world/structures/human/town_hall_spire.vox b/assets/world/structures/human/town_hall_spire.vox new file mode 100644 index 0000000000..f23eb7e8dc --- /dev/null +++ b/assets/world/structures/human/town_hall_spire.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81bed37162a2179b1e3cc9cf2b1a78fe2498acc9bbbbbca521884c87f0babe85 +size 81773 diff --git a/voxygen/shaders/postprocess.frag b/voxygen/shaders/postprocess.frag index 4e1adf4040..6eafa19dd6 100644 --- a/voxygen/shaders/postprocess.frag +++ b/voxygen/shaders/postprocess.frag @@ -167,7 +167,7 @@ void main() { //vec4 fxaa_color = texture(src_color, uv); vec4 hsva_color = vec4(rgb2hsv(fxaa_color.rgb), fxaa_color.a); - hsva_color.y *= 1.3; + hsva_color.y *= 1.4; hsva_color.x -= 0.015; hsva_color.z *= 0.85; //hsva_color.z = 1.0 - 1.0 / (1.0 * hsva_color.z + 1.0); From 325fa41d7ea7ea4321ca7e07b072687e54e62782 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Jun 2019 14:55:54 +0100 Subject: [PATCH 34/40] Grass improvements --- voxygen/shaders/postprocess.frag | 2 +- world/src/block/mod.rs | 14 +++++++---- world/src/column/mod.rs | 40 ++++++++++++++++++++------------ 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/voxygen/shaders/postprocess.frag b/voxygen/shaders/postprocess.frag index 6eafa19dd6..4e1adf4040 100644 --- a/voxygen/shaders/postprocess.frag +++ b/voxygen/shaders/postprocess.frag @@ -167,7 +167,7 @@ void main() { //vec4 fxaa_color = texture(src_color, uv); vec4 hsva_color = vec4(rgb2hsv(fxaa_color.rgb), fxaa_color.a); - hsva_color.y *= 1.4; + 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); diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 52a417a92d..dc0e748d47 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -83,6 +83,7 @@ impl<'a> SamplerMut for BlockGen<'a> { water_level, river, surface_color, + sub_surface_color, tree_density, forest_kind, close_trees, @@ -143,8 +144,13 @@ impl<'a> SamplerMut for BlockGen<'a> { let water = Block::new(1, Rgb::new(100, 150, 255)); let warm_stone = Block::new(1, Rgb::new(165, 165, 130)); - let block = if (wposf.z as f32) < height - 3.0 { - let col = Lerp::lerp(dirt_col, stone_col, (height - 4.0 - wposf.z as f32) * 0.15); + let grass_depth = 2.0; + let block = if (wposf.z as f32) < height - grass_depth { + let col = Lerp::lerp( + sub_surface_color.map(|e| (e * 255.0) as u8), + stone_col, + (height - grass_depth - wposf.z as f32) * 0.15, + ); // Underground if (wposf.z as f32) > alt - 32.0 * chaos { @@ -154,9 +160,9 @@ impl<'a> SamplerMut for BlockGen<'a> { } } else if (wposf.z as f32) < height { let col = Lerp::lerp( - dirt_col.map(|e| e as f32 / 255.0), + sub_surface_color, surface_color, - (wposf.z as f32 - (height - 4.0)) * 0.25, + (wposf.z as f32 - (height - grass_depth)).div(grass_depth).powf(0.5), ); // Surface Some(Block::new(1, col.map(|e| (e * 255.0) as u8))) diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 43e5acf019..d5dfb90831 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -97,15 +97,17 @@ impl<'a> Sampler for ColumnGen<'a> { let wposf3d = Vec3::new(wposf.x, wposf.y, alt as f64); - let marble = (0.0 - + (sim.gen_ctx.hill_nz.get((wposf3d.div(48.0)).into_array()) as f32).mul(0.75) - + (sim.gen_ctx.hill_nz.get((wposf3d.div(3.0)).into_array()) as f32).mul(0.25)) - .add(1.0) - .mul(0.5); + let marble_small = (sim.gen_ctx.hill_nz.get((wposf3d.div(3.0)).into_array()) as f32) + .add(1.0) + .mul(0.5); + let marble = (sim.gen_ctx.hill_nz.get((wposf3d.div(48.0)).into_array()) as f32).mul(0.75) + .add(1.0) + .mul(0.5) + .add(marble_small.mul(0.25)); // Colours - let cold_grass = Rgb::new(0.0, 0.3, 0.15); - let warm_grass = Rgb::new(0.2, 0.8, 0.05); + let cold_grass = Rgb::new(0.05, 0.2, 0.1); + let warm_grass = Rgb::new(0.15, 0.65, 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); @@ -116,10 +118,18 @@ impl<'a> Sampler for ColumnGen<'a> { let sand = Rgb::lerp(beach_sand, desert_sand, marble); let cliff = Rgb::lerp(cold_stone, warm_stone, marble); + let dirt = Lerp::lerp( + Rgb::new(0.2, 0.1, 0.05), + Rgb::new(0.4, 0.25, 0.0), + marble_small, + ); + + let turf = grass; + let ground = Rgb::lerp( Rgb::lerp( snow, - grass, + turf, temp.sub(CONFIG.snow_temp) .sub((marble - 0.5) * 0.05) .mul(256.0), @@ -128,7 +138,7 @@ impl<'a> Sampler for ColumnGen<'a> { temp.sub(CONFIG.desert_temp).mul(32.0), ); - // Work out if we're on a path + // Work out if we're on a path or near a town let near_0 = sim_chunk.location.as_ref().map(|l| l.near[0].block_pos).unwrap_or(Vec2::zero()).map(|e| e as f32); let near_1 = sim_chunk.location.as_ref().map(|l| l.near[1].block_pos).unwrap_or(Vec2::zero()).map(|e| e as f32); @@ -140,12 +150,10 @@ impl<'a> Sampler for ColumnGen<'a> { .abs() .div(near_0.distance(near_1)); - let (alt, ground) = if dist_to_path < 5.0 { - (alt - 1.5, Lerp::lerp( - Rgb::new(0.15, 0.075, 0.05), - Rgb::new(0.4, 0.25, 0.0), - marble, - )) + let on_path = dist_to_path < 5.0 || near_0.distance(wposf_turb.map(|e| e as f32)) < 150.0; + + let (alt, ground) = if on_path { + (alt - 1.0, dirt) } else { (alt, ground) }; @@ -204,6 +212,7 @@ impl<'a> Sampler for ColumnGen<'a> { // Beach ((alt - CONFIG.sea_level - 2.0) / 5.0).min(1.0 - river * 2.0), ), + sub_surface_color: dirt, tree_density, forest_kind: sim_chunk.forest_kind, close_trees: sim.gen_ctx.tree_gen.get(wpos), @@ -226,6 +235,7 @@ pub struct ColumnSample<'a> { pub water_level: f32, pub river: f32, pub surface_color: Rgb, + pub sub_surface_color: Rgb, pub tree_density: f32, pub forest_kind: ForestKind, pub close_trees: [(Vec2, u32); 9], From ad2bc635f80ceb402357b9bcd6e8375e2174318f Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Jun 2019 18:46:04 +0100 Subject: [PATCH 35/40] Rewrote sky shaders, added stars --- voxygen/shaders/include/sky.glsl | 106 ++++++++++++++++++++++++++++++- world/src/column/mod.rs | 4 +- 2 files changed, 107 insertions(+), 3 deletions(-) diff --git a/voxygen/shaders/include/sky.glsl b/voxygen/shaders/include/sky.glsl index d03c301a2d..a6eca08282 100644 --- a/voxygen/shaders/include/sky.glsl +++ b/voxygen/shaders/include/sky.glsl @@ -36,7 +36,7 @@ vec3 get_sun_dir(float time_of_day) { } float get_sun_brightness(vec3 sun_dir) { - return pow(max(-sun_dir.z + 0.3, 0.0), 0.5); + return max(-sun_dir.z + 0.6, 0.0) * 0.8; } const float PERSISTENT_AMBIANCE = 0.015; @@ -51,7 +51,110 @@ float get_sun_diffuse(vec3 norm, float time_of_day) { return (SUN_AMBIANCE + max(dot(-norm, sun_dir), 0.0)) * sun_light + PERSISTENT_AMBIANCE; } +vec3 rand_offs(vec3 pos) { + return sin(pos * vec3(1473.7 * pos.z, 8891.1 * pos.x, 3813.3 * pos.y)); +} + vec3 get_sky_color(vec3 dir, float time_of_day) { + + // Stars + float star_scale = 60.0; + float dist = 1000.0; + for (int i = 0; i < 2; i ++) { + for (int j = 0; j < 2; j ++) { + for (int k = 0; k < 2; k ++) { + vec3 pos = (floor(dir * star_scale) + vec3(i, j, k) - vec3(0.5)) / star_scale; + pos += rand_offs(pos) * 0.2; + dist = min(dist, length(normalize(pos) - dir)); + } + } + } + float star; + if (dist < 0.0015) { + star = 1.0; + } else { + star = 0.0; + } + + // Sky color + + const vec3 SKY_DAY_TOP = vec3(0.2, 0.3, 0.9); + const vec3 SKY_DAY_MID = vec3(0.1, 0.15, 0.7); + const vec3 SKY_DAY_BOT = vec3(0.025, 0.15, 0.35); + + const vec3 SKY_DUSK_TOP = vec3(0.1, 0.15, 0.3); + const vec3 SKY_DUSK_MID = vec3(0.9, 0.3, 0.2); + const vec3 SKY_DUSK_BOT = vec3(0.01, 0.05, 0.15); + + const vec3 SKY_NIGHT_TOP = vec3(0.002, 0.002, 0.005); + const vec3 SKY_NIGHT_MID = vec3(0.002, 0.01, 0.03); + const vec3 SKY_NIGHT_BOT = vec3(0.002, 0.002, 0.005); + + vec3 sun_dir = get_sun_dir(time_of_day); + + vec3 sky_top = mix( + mix( + SKY_DUSK_TOP, + SKY_NIGHT_TOP, + clamp(sun_dir.z, 0, 1) + ) + star, + SKY_DAY_TOP, + clamp(-sun_dir.z, 0, 1) + ); + + vec3 sky_mid = mix( + mix( + SKY_DUSK_MID, + SKY_NIGHT_MID, + clamp(sun_dir.z, 0, 1) + ), + SKY_DAY_MID, + clamp(-sun_dir.z, 0, 1) + ); + + vec3 sky_bot = mix( + mix( + SKY_DUSK_BOT, + SKY_NIGHT_BOT, + clamp(sun_dir.z, 0, 1) + ), + SKY_DAY_MID, + clamp(-sun_dir.z, 0, 1) + ); + + vec3 sky_color = mix( + mix( + sky_mid, + sky_bot, + pow(clamp(-dir.z, 0, 1), 0.4) + ), + sky_top, + pow(clamp(dir.z, 0, 1), 1.0) + ); + + // Sun + + const vec3 SUN_HALO_COLOR = vec3(1.0, 0.35, 0.1) * 0.3; + const vec3 SUN_SURF_COLOR = vec3(1.0, 0.9, 0.35) * 200.0; + + vec3 sun_halo = pow(max(dot(dir, -sun_dir) + 0.1, 0.0), 8.0) * SUN_HALO_COLOR; + vec3 sun_surf = pow(max(dot(dir, -sun_dir) - 0.0045, 0.0), 1000.0) * SUN_SURF_COLOR; + vec3 sun_light = (sun_halo + sun_surf) * clamp(dir.z * 10.0, 0, 1); + + return sky_color + sun_light; + + + + + + + + + + + + + /* bool objects = true; vec2 pos2d = dir.xy / dir.z; @@ -96,6 +199,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day) { ); return sky_color; + */ } float fog(vec2 f_pos, vec2 focus_pos) { diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index d5dfb90831..be1232d271 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -121,7 +121,7 @@ impl<'a> Sampler for ColumnGen<'a> { let dirt = Lerp::lerp( Rgb::new(0.2, 0.1, 0.05), Rgb::new(0.4, 0.25, 0.0), - marble_small, + marble, ); let turf = grass; @@ -150,7 +150,7 @@ impl<'a> Sampler for ColumnGen<'a> { .abs() .div(near_0.distance(near_1)); - let on_path = dist_to_path < 5.0 || near_0.distance(wposf_turb.map(|e| e as f32)) < 150.0; + let on_path = dist_to_path < 5.0;// || near_0.distance(wposf_turb.map(|e| e as f32)) < 150.0; let (alt, ground) = if on_path { (alt - 1.0, dirt) From 397c909bd412fe6131cf0f96f7444e7423f1f7e2 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Jun 2019 20:18:29 +0100 Subject: [PATCH 36/40] Denser stars --- voxygen/shaders/include/sky.glsl | 26 +++++++++++++++----------- voxygen/shaders/skybox.vert | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/voxygen/shaders/include/sky.glsl b/voxygen/shaders/include/sky.glsl index a6eca08282..9ae84af4b7 100644 --- a/voxygen/shaders/include/sky.glsl +++ b/voxygen/shaders/include/sky.glsl @@ -52,29 +52,33 @@ float get_sun_diffuse(vec3 norm, float time_of_day) { } vec3 rand_offs(vec3 pos) { - return sin(pos * vec3(1473.7 * pos.z, 8891.1 * pos.x, 3813.3 * pos.y)); + return sin(pos * vec3(1473.7 * pos.z + 472.3, 8891.1 * pos.x + 723.1, 3813.3 * pos.y + 982.5)); } vec3 get_sky_color(vec3 dir, float time_of_day) { // Stars - float star_scale = 60.0; - float dist = 1000.0; + float star_scale = 30.0; + float star = 0.0; for (int i = 0; i < 2; i ++) { for (int j = 0; j < 2; j ++) { for (int k = 0; k < 2; k ++) { + // Star positions vec3 pos = (floor(dir * star_scale) + vec3(i, j, k) - vec3(0.5)) / star_scale; - pos += rand_offs(pos) * 0.2; - dist = min(dist, length(normalize(pos) - dir)); + + // Noisy offsets + pos += 3.0 * rand_offs(pos) / star_scale; + + // Find distance to fragment + float dist = length(normalize(pos) - dir); + + // Star threshold + if (dist < 0.0015) { + star = 1.0; + } } } } - float star; - if (dist < 0.0015) { - star = 1.0; - } else { - star = 0.0; - } // Sky color diff --git a/voxygen/shaders/skybox.vert b/voxygen/shaders/skybox.vert index 4c7322fb3f..c1816d4127 100644 --- a/voxygen/shaders/skybox.vert +++ b/voxygen/shaders/skybox.vert @@ -14,6 +14,7 @@ out vec3 f_pos; void main() { f_pos = v_pos; + // TODO: Make this position-independent to avoid rounding error jittering gl_Position = proj_mat * view_mat * From f781aca8e926a2a4b51a3326278c9a97d19dcb3e Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Jun 2019 20:43:02 +0100 Subject: [PATCH 37/40] fmt --- server/src/cmd.rs | 42 +++--- voxygen/src/menu/char_selection/ui.rs | 4 +- world/src/block/mod.rs | 180 ++++++++++++++++---------- world/src/column/mod.rs | 39 +++--- world/src/sim/location.rs | 12 +- world/src/sim/mod.rs | 40 +++--- 6 files changed, 184 insertions(+), 133 deletions(-) diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 750bb6ef2d..262c6a3bba 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -152,27 +152,29 @@ fn handle_kill(server: &mut Server, entity: EcsEntity, _args: String, _action: & fn handle_time(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { let time = scan_fmt!(&args, action.arg_fmt, String); - server - .state - .ecs_mut() - .write_resource::() - .0 = match time.as_ref().map(|s| s.as_str()) { - Some("day") => 12.0 * 3600.0, - Some("night") => 24.0 * 3600.0, - Some("dawn") => 5.0 * 3600.0, - Some("dusk") => 17.0 * 3600.0, - Some(n) => match n.parse() { - Ok(n) => n, - Err(_) => { - server.clients.notify(entity, ServerMsg::Chat(format!("'{}' is not a time!", n))); - return; - }, - }, - None => { - server.clients.notify(entity, ServerMsg::Chat("You must specify a time!".to_string())); + server.state.ecs_mut().write_resource::().0 = match time.as_ref().map(|s| s.as_str()) + { + Some("day") => 12.0 * 3600.0, + Some("night") => 24.0 * 3600.0, + Some("dawn") => 5.0 * 3600.0, + Some("dusk") => 17.0 * 3600.0, + Some(n) => match n.parse() { + Ok(n) => n, + Err(_) => { + server + .clients + .notify(entity, ServerMsg::Chat(format!("'{}' is not a time!", n))); return; - }, - }; + } + }, + None => { + server.clients.notify( + entity, + ServerMsg::Chat("You must specify a time!".to_string()), + ); + return; + } + }; } fn handle_alias(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) { diff --git a/voxygen/src/menu/char_selection/ui.rs b/voxygen/src/menu/char_selection/ui.rs index 31ced8fcda..3c0bdbe6e8 100644 --- a/voxygen/src/menu/char_selection/ui.rs +++ b/voxygen/src/menu/char_selection/ui.rs @@ -141,7 +141,7 @@ widget_ids! { image_ids! { struct Imgs { - + button: "voxygen/element/buttons/button.vox", button_hover: "voxygen/element/buttons/button_hover.vox", button_press: "voxygen/element/buttons/button_press.vox", @@ -169,7 +169,7 @@ image_ids! { frame_open_press: "voxygen/element/buttons/frame/open_press.png", skin_eyes_window: "voxygen/element/frames/skin_eyes.png", hair_window: "voxygen/element/frames/skin_eyes.png", - accessories_window: "voxygen/element/frames/skin_eyes.png", + accessories_window: "voxygen/element/frames/skin_eyes.png", slider_range: "voxygen/element/slider/track.png", slider_indicator: "voxygen/element/slider/indicator.png", window_frame_2: "voxygen/element/frames/window_2.png", diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index dc0e748d47..f48ed9f5db 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -30,7 +30,8 @@ impl<'a> BlockGen<'a> { fn sample_column( column_gen: &ColumnGen<'a>, - cache: &mut HashCache, Option>>, wpos: Vec2, + cache: &mut HashCache, Option>>, + wpos: Vec2, ) -> Option> { cache .get(Vec2::from(wpos), |wpos| column_gen.get(wpos)) @@ -44,25 +45,34 @@ impl<'a> BlockGen<'a> { close_cliffs: &[(Vec2, u32); 9], cliff_hill: f32, ) -> f32 { - close_cliffs - .iter() - .fold(0.0f32, |max_height, (cliff_pos, seed)| { - match Self::sample_column(column_gen, cache, Vec2::from(*cliff_pos)) { - Some(cliff_sample) if cliff_sample.cliffs => { - let cliff_pos3d = Vec3::from(*cliff_pos); + close_cliffs.iter().fold( + 0.0f32, + |max_height, (cliff_pos, seed)| match Self::sample_column( + column_gen, + cache, + Vec2::from(*cliff_pos), + ) { + Some(cliff_sample) if cliff_sample.cliffs => { + let cliff_pos3d = Vec3::from(*cliff_pos); - let height = RandomField::new(seed + 1).get(cliff_pos3d) % 48; - let radius = RandomField::new(seed + 2).get(cliff_pos3d) % 48 + 8; + let height = RandomField::new(seed + 1).get(cliff_pos3d) % 48; + let radius = RandomField::new(seed + 2).get(cliff_pos3d) % 48 + 8; - max_height.max(if cliff_pos.map(|e| e as f32).distance_squared(wpos) < (radius * radius) as f32 { - cliff_sample.alt + height as f32 * (1.0 - cliff_sample.chaos) + cliff_hill + max_height.max( + if cliff_pos.map(|e| e as f32).distance_squared(wpos) + < (radius * radius) as f32 + { + cliff_sample.alt + + height as f32 * (1.0 - cliff_sample.chaos) + + cliff_hill } else { 0.0 - }) - }, - _ => max_height, + }, + ) } - }) + _ => max_height, + }, + ) } } @@ -99,38 +109,53 @@ impl<'a> SamplerMut for BlockGen<'a> { let wposf = wpos.map(|e| e as f64); - let (definitely_underground, height, water_height) = if (wposf.z as f32) < alt - 64.0 * chaos { - // Shortcut warping - (true, alt, water_level) - } else { - // Apply warping - let warp = (world - .sim() - .gen_ctx - .warp_nz - .get((wposf.div(Vec3::new(150.0, 150.0, 150.0))).into_array()) - as f32) - .mul((chaos - 0.1).max(0.0)) - .mul(115.0); - - let height = if (wposf.z as f32) < alt + warp - 10.0 { - // Shortcut cliffs - alt + warp + let (definitely_underground, height, water_height) = + if (wposf.z as f32) < alt - 64.0 * chaos { + // Shortcut warping + (true, alt, water_level) } else { - let turb = Vec2::new( - world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32, - world.sim().gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32, - ) * 12.0; + // Apply warping + let warp = (world + .sim() + .gen_ctx + .warp_nz + .get((wposf.div(Vec3::new(150.0, 150.0, 150.0))).into_array()) + as f32) + .mul((chaos - 0.1).max(0.0)) + .mul(115.0); - let wpos_turb = Vec2::from(wpos).map(|e: i32| e as f32) + turb; - let cliff_height = Self::get_cliff_height(column_gen, column_cache, wpos_turb, &close_cliffs, cliff_hill); + let height = if (wposf.z as f32) < alt + warp - 10.0 { + // Shortcut cliffs + alt + warp + } else { + let turb = Vec2::new( + world + .sim() + .gen_ctx + .turb_x_nz + .get((wposf.div(48.0)).into_array()) as f32, + world + .sim() + .gen_ctx + .turb_y_nz + .get((wposf.div(48.0)).into_array()) as f32, + ) * 12.0; - (alt + warp).max(cliff_height) + let wpos_turb = Vec2::from(wpos).map(|e: i32| e as f32) + turb; + let cliff_height = Self::get_cliff_height( + column_gen, + column_cache, + wpos_turb, + &close_cliffs, + cliff_hill, + ); + + (alt + warp).max(cliff_height) + }; + + (false, height, water_level + warp) }; - (false, height, water_level + warp) - }; - // Sample blocks let stone_col = Rgb::new(200, 220, 255); @@ -162,7 +187,9 @@ impl<'a> SamplerMut for BlockGen<'a> { let col = Lerp::lerp( sub_surface_color, surface_color, - (wposf.z as f32 - (height - grass_depth)).div(grass_depth).powf(0.5), + (wposf.z as f32 - (height - grass_depth)) + .div(grass_depth) + .powf(0.5), ); // Surface Some(Block::new(1, col.map(|e| (e * 255.0) as u8))) @@ -260,36 +287,49 @@ impl<'a> SamplerMut for BlockGen<'a> { Some(block) => block, None => (&close_trees) .iter() - .fold(air, |block, (tree_pos, tree_seed)| if !block.is_empty() { - block - } else { - match Self::sample_column(column_gen, column_cache, Vec2::from(*tree_pos)) { - Some(tree_sample) - if tree_sample.tree_density - > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 - && tree_sample.alt > tree_sample.water_level => - { - let cliff_height = Self::get_cliff_height(column_gen, column_cache, tree_pos.map(|e| e as f32), &tree_sample.close_cliffs, cliff_hill); - let height = tree_sample.alt.max(cliff_height); - let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, height as i32); - let rpos = wpos - tree_pos3d; + .fold(air, |block, (tree_pos, tree_seed)| { + if !block.is_empty() { + block + } else { + match Self::sample_column( + column_gen, + column_cache, + Vec2::from(*tree_pos), + ) { + Some(tree_sample) + if tree_sample.tree_density + > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 + && tree_sample.alt > tree_sample.water_level => + { + let cliff_height = Self::get_cliff_height( + column_gen, + column_cache, + tree_pos.map(|e| e as f32), + &tree_sample.close_cliffs, + cliff_hill, + ); + let height = tree_sample.alt.max(cliff_height); + let tree_pos3d = + Vec3::new(tree_pos.x, tree_pos.y, height as i32); + let rpos = wpos - tree_pos3d; - let trees = tree::kinds(tree_sample.forest_kind); // Choose tree kind + 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| { - block_from_structure( - *b, - rpos, - *tree_pos, - *tree_seed, - &tree_sample, - ) - }) - .unwrap_or(Block::empty())) + block.or(trees[*tree_seed as usize % trees.len()] + .get((rpos * 128) / 128) // Scaling + .map(|b| { + block_from_structure( + *b, + rpos, + *tree_pos, + *tree_seed, + &tree_sample, + ) + }) + .unwrap_or(Block::empty())) + } + _ => block, } - _ => block, } }), } diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index be1232d271..f2cf975529 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -2,8 +2,7 @@ use crate::{ all::ForestKind, sim::{Location, LocationInfo}, util::Sampler, - World, - CONFIG, + World, CONFIG, }; use common::{ terrain::{Block, TerrainChunkSize}, @@ -64,8 +63,8 @@ impl<'a> Sampler for ColumnGen<'a> { .max(0.0) .mul((1.0 - (chaos - 0.15) * 20.0).max(0.0).min(1.0)); - let cliff_hill = (sim.gen_ctx.small_nz.get((wposf.div(128.0)).into_array()) as f32) - .mul(16.0); + let cliff_hill = + (sim.gen_ctx.small_nz.get((wposf.div(128.0)).into_array()) as f32).mul(16.0); let riverless_alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? + (sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32) @@ -100,7 +99,8 @@ impl<'a> Sampler for ColumnGen<'a> { let marble_small = (sim.gen_ctx.hill_nz.get((wposf3d.div(3.0)).into_array()) as f32) .add(1.0) .mul(0.5); - let marble = (sim.gen_ctx.hill_nz.get((wposf3d.div(48.0)).into_array()) as f32).mul(0.75) + let marble = (sim.gen_ctx.hill_nz.get((wposf3d.div(48.0)).into_array()) as f32) + .mul(0.75) .add(1.0) .mul(0.5) .add(marble_small.mul(0.25)); @@ -118,11 +118,7 @@ impl<'a> Sampler for ColumnGen<'a> { let sand = Rgb::lerp(beach_sand, desert_sand, marble); let cliff = Rgb::lerp(cold_stone, warm_stone, marble); - let dirt = Lerp::lerp( - Rgb::new(0.2, 0.1, 0.05), - Rgb::new(0.4, 0.25, 0.0), - marble, - ); + let dirt = Lerp::lerp(Rgb::new(0.2, 0.1, 0.05), Rgb::new(0.4, 0.25, 0.0), marble); let turf = grass; @@ -139,18 +135,27 @@ impl<'a> Sampler for ColumnGen<'a> { ); // Work out if we're on a path or near a town - let near_0 = sim_chunk.location.as_ref().map(|l| l.near[0].block_pos).unwrap_or(Vec2::zero()).map(|e| e as f32); - let near_1 = sim_chunk.location.as_ref().map(|l| l.near[1].block_pos).unwrap_or(Vec2::zero()).map(|e| e as f32); + let near_0 = sim_chunk + .location + .as_ref() + .map(|l| l.near[0].block_pos) + .unwrap_or(Vec2::zero()) + .map(|e| e as f32); + let near_1 = sim_chunk + .location + .as_ref() + .map(|l| l.near[1].block_pos) + .unwrap_or(Vec2::zero()) + .map(|e| e as f32); - let dist_to_path = (0.0 - + (near_1.y - near_0.y) * wposf_turb.x as f32 + let dist_to_path = (0.0 + (near_1.y - near_0.y) * wposf_turb.x as f32 - (near_1.x - near_0.x) * wposf_turb.y as f32 + near_1.x * near_0.y - near_0.x * near_1.y) - .abs() - .div(near_0.distance(near_1)); + .abs() + .div(near_0.distance(near_1)); - let on_path = dist_to_path < 5.0;// || near_0.distance(wposf_turb.map(|e| e as f32)) < 150.0; + let on_path = dist_to_path < 5.0; // || near_0.distance(wposf_turb.map(|e| e as f32)) < 150.0; let (alt, ground) = if on_path { (alt - 1.0, dirt) diff --git a/world/src/sim/location.rs b/world/src/sim/location.rs index 49e01632e7..1acd7d45c3 100644 --- a/world/src/sim/location.rs +++ b/world/src/sim/location.rs @@ -48,12 +48,12 @@ fn generate_name(rng: &mut R) -> String { ]; let mid = ["ka", "se", "au", "da", "di"]; let tails = [ - /*"mill",*/ "ben", "sel", "dori", "theas", "dar", "bur", "to", "vis", "ten", "stone", "tiva", - "id", "and", "or", "el", "ond", "ia", "eld", "ald", "aft", "ift", "ity", "well", "oll", - "ill", "all", "wyn", "light", " Hill", "lin", "mont", "mor", "cliff", "rok", "den", "mi", - "rock", "glenn", "rovi", "lea", "gate", "view", "ley", "wood", "ovia", "cliff", "marsh", - "kor", "ice", /*"river",*/ "acre", "venn", "crest", "field", "vale", "spring", " Vale", - "grasp", "fel", "fall", "grove", "wyn", "edge", + /*"mill",*/ "ben", "sel", "dori", "theas", "dar", "bur", "to", "vis", "ten", "stone", + "tiva", "id", "and", "or", "el", "ond", "ia", "eld", "ald", "aft", "ift", "ity", "well", + "oll", "ill", "all", "wyn", "light", " Hill", "lin", "mont", "mor", "cliff", "rok", "den", + "mi", "rock", "glenn", "rovi", "lea", "gate", "view", "ley", "wood", "ovia", "cliff", + "marsh", "kor", "ice", /*"river",*/ "acre", "venn", "crest", "field", "vale", + "spring", " Vale", "grasp", "fel", "fall", "grove", "wyn", "edge", ]; let mut name = String::new(); diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 0f57feb2db..2dbd759815 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -5,14 +5,17 @@ pub use self::location::Location; use crate::{ all::ForestKind, - util::{StructureGen2d, Sampler}, + util::{Sampler, StructureGen2d}, CONFIG, }; use common::{ terrain::{BiomeKind, TerrainChunkSize}, vol::VolSize, }; -use noise::{BasicMulti, HybridMulti, MultiFractal, NoiseFn, RidgedMulti, Seedable, OpenSimplex, SuperSimplex}; +use noise::{ + BasicMulti, HybridMulti, MultiFractal, NoiseFn, OpenSimplex, RidgedMulti, Seedable, + SuperSimplex, +}; use rand::{prng::XorShiftRng, Rng, SeedableRng}; use std::{ ops::{Add, Div, Mul, Neg, Sub}, @@ -132,12 +135,12 @@ impl WorldSim { self.rng.gen::() % grid_size.y, ); let wpos = (cell_pos * cell_size) - .map2( - Vec2::from(TerrainChunkSize::SIZE), - |e, sz: u32| e as i32 * sz as i32, - ); + .map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| { + e as i32 * sz as i32 + }); - locations[cell_pos.y * grid_size.x + cell_pos.x] = Some(Arc::new(Location::generate(wpos, &mut rng))); + locations[cell_pos.y * grid_size.x + cell_pos.x] = + Some(Arc::new(Location::generate(wpos, &mut rng))); } // Simulate invasion! @@ -148,10 +151,8 @@ impl WorldSim { if locations[j * grid_size.x + i].is_none() { const R_COORDS: [i32; 5] = [-1, 0, 1, 0, -1]; let idx = self.rng.gen::() % 4; - let loc = Vec2::new( - i as i32 + R_COORDS[idx], - j as i32 + R_COORDS[idx + 1], - ).map(|e| e as usize); + let loc = Vec2::new(i as i32 + R_COORDS[idx], j as i32 + R_COORDS[idx + 1]) + .map(|e| e as usize); locations[j * grid_size.x + i] = locations .get(loc.y * grid_size.x + loc.x) @@ -175,7 +176,9 @@ impl WorldSim { .iter() .map(|(pos, seed)| RegionInfo { chunk_pos: *pos, - block_pos: pos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| e * sz as i32), + block_pos: pos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| { + e * sz as i32 + }), dist: (pos - chunk_pos).map(|e| e as f32).magnitude(), seed: *seed, }) @@ -189,10 +192,7 @@ impl WorldSim { .get(nearest_cell_pos.y * grid_size.x + nearest_cell_pos.x) .cloned() .unwrap_or(None) - .map(|loc| LocationInfo { - loc, - near, - }); + .map(|loc| LocationInfo { loc, near }); } } @@ -409,7 +409,10 @@ impl SimChunk { .sub(0.1) .mul(1.3) .max(0.0), - cliffs: cliff > 0.5 && dryness > 0.05 && alt > CONFIG.sea_level + 5.0 && dryness.abs() > 0.075, + cliffs: cliff > 0.5 + && dryness > 0.05 + && alt > CONFIG.sea_level + 5.0 + && dryness.abs() > 0.075, near_cliffs: cliff > 0.4, tree_density: (gen_ctx.tree_nz.get((wposf.div(1024.0)).into_array()) as f32) .add(1.0) @@ -447,7 +450,8 @@ impl SimChunk { } pub fn get_max_z(&self) -> f32 { - (self.alt + Z_TOLERANCE.1 * if self.near_cliffs { 1.0 } else { 0.5 }).max(CONFIG.sea_level + 2.0) + (self.alt + Z_TOLERANCE.1 * if self.near_cliffs { 1.0 } else { 0.5 }) + .max(CONFIG.sea_level + 2.0) } pub fn get_name(&self) -> Option { From b40d19ad0eb9e77845865fb0bb5413e9ebcd766f Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 25 Jun 2019 16:59:09 +0100 Subject: [PATCH 38/40] Added settlement generation --- world/examples/city.rs | 30 +++++++++++ world/examples/turb.rs | 47 ++++++++++++++++++ world/examples/view.rs | 7 +-- world/src/block/mod.rs | 5 +- world/src/column/mod.rs | 63 ++++++++++++++++------- world/src/lib.rs | 2 +- world/src/sim/location.rs | 22 ++++----- world/src/sim/mod.rs | 99 ++++++++++++++++++++++--------------- world/src/sim/settlement.rs | 95 +++++++++++++++++++++++++++++++++++ 9 files changed, 292 insertions(+), 78 deletions(-) create mode 100644 world/examples/city.rs create mode 100644 world/examples/turb.rs create mode 100644 world/src/sim/settlement.rs diff --git a/world/examples/city.rs b/world/examples/city.rs new file mode 100644 index 0000000000..6bd9af95af --- /dev/null +++ b/world/examples/city.rs @@ -0,0 +1,30 @@ +use std::ops::{Add, Mul, Sub}; +use vek::*; +use veloren_world::sim::Settlement; +use rand::thread_rng; + +const W: usize = 640; +const H: usize = 480; + +fn main() { + let mut win = + minifb::Window::new("City Viewer", W, H, minifb::WindowOptions::default()).unwrap(); + + let settlement = Settlement::generate(&mut thread_rng()); + + while win.is_open() { + let mut buf = vec![0; W * H]; + + for i in 0..W { + for j in 0..H { + let pos = Vec2::new(i as f32, j as f32) * 0.002; + + let seed = settlement.get_at(pos).map(|b| b.seed).unwrap_or(0); + + buf[j * W + i] = u32::from_le_bytes([(seed >> 0) as u8, (seed >> 8) as u8, (seed >> 16) as u8, (seed >> 24) as u8]); + } + } + + win.update_with_buffer(&buf).unwrap(); + } +} diff --git a/world/examples/turb.rs b/world/examples/turb.rs new file mode 100644 index 0000000000..419d70756e --- /dev/null +++ b/world/examples/turb.rs @@ -0,0 +1,47 @@ +use std::ops::{Add, Mul, Sub}; +use vek::*; +use veloren_world::sim::Settlement; +use rand::thread_rng; +use noise::{Seedable, NoiseFn, SuperSimplex}; + +const W: usize = 640; +const H: usize = 640; + +fn main() { + let mut win = + minifb::Window::new("Turb", W, H, minifb::WindowOptions::default()).unwrap(); + + let nz_x = SuperSimplex::new().set_seed(0); + let nz_y = SuperSimplex::new().set_seed(1); + + let mut time = 0.0f64; + while win.is_open() { + let mut buf = vec![0; W * H]; + + for i in 0..W { + for j in 0..H { + let pos = Vec2::new(i as f64 / W as f64, j as f64 / H as f64) * 0.5 - 0.25; + + let pos = pos * 10.0; + + let pos = (0..10) + .fold(pos, |pos, _| pos.map(|e| e.powf(3.0) - 1.0)); + + let val = if pos + .map(|e| e.abs() < 0.5) + .reduce_and() + { + 1.0f32 + } else { + 0.0 + }; + + buf[j * W + i] = u32::from_le_bytes([(val.max(0.0).min(1.0) * 255.0) as u8; 4]); + } + } + + win.update_with_buffer(&buf).unwrap(); + + time += 1.0 / 60.0; + } +} diff --git a/world/examples/view.rs b/world/examples/view.rs index 2fa077389e..c1f52ec8e6 100644 --- a/world/examples/view.rs +++ b/world/examples/view.rs @@ -35,12 +35,7 @@ fn main() { .unwrap_or((0, None)); let loc_color = location - .map(|l| { - ( - l.loc.name().bytes().nth(0).unwrap() * 17, - l.loc.name().bytes().nth(1).unwrap() * 17, - ) - }) + .map(|l| (l.loc_idx as u8 * 17, l.loc_idx as u8 * 13)) .unwrap_or((0, 0)); buf[j * W + i] = u32::from_le_bytes([loc_color.0, loc_color.1, alt, alt]); diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index f48ed9f5db..02e12d5ff5 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -52,7 +52,7 @@ impl<'a> BlockGen<'a> { cache, Vec2::from(*cliff_pos), ) { - Some(cliff_sample) if cliff_sample.cliffs => { + Some(cliff_sample) if cliff_sample.cliffs && cliff_sample.spawn_rate > 0.5 => { let cliff_pos3d = Vec3::from(*cliff_pos); let height = RandomField::new(seed + 1).get(cliff_pos3d) % 48; @@ -299,7 +299,8 @@ impl<'a> SamplerMut for BlockGen<'a> { Some(tree_sample) if tree_sample.tree_density > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 - && tree_sample.alt > tree_sample.water_level => + && tree_sample.alt > tree_sample.water_level + && tree_sample.spawn_rate > 0.5 => { let cliff_height = Self::get_cliff_height( column_gen, diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index f2cf975529..82d59dbb4e 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -50,6 +50,7 @@ impl<'a> Sampler for ColumnGen<'a> { let dryness = sim.get_interpolated(wpos, |chunk| chunk.dryness)?; let rockiness = sim.get_interpolated(wpos, |chunk| chunk.rockiness)?; let tree_density = sim.get_interpolated(wpos, |chunk| chunk.tree_density)?; + let spawn_rate = sim.get_interpolated(wpos, |chunk| chunk.spawn_rate)?; let sim_chunk = sim.get(chunk_pos)?; @@ -135,25 +136,32 @@ impl<'a> Sampler for ColumnGen<'a> { ); // Work out if we're on a path or near a town - let near_0 = sim_chunk - .location - .as_ref() - .map(|l| l.near[0].block_pos) - .unwrap_or(Vec2::zero()) - .map(|e| e as f32); - let near_1 = sim_chunk - .location - .as_ref() - .map(|l| l.near[1].block_pos) - .unwrap_or(Vec2::zero()) - .map(|e| e as f32); + let dist_to_path = match &sim_chunk.location { + Some(loc) => { + let this_loc = &sim.locations[loc.loc_idx]; + this_loc.neighbours + .iter() + .map(|j| { + let other_loc = &sim.locations[*j]; - let dist_to_path = (0.0 + (near_1.y - near_0.y) * wposf_turb.x as f32 - - (near_1.x - near_0.x) * wposf_turb.y as f32 - + near_1.x * near_0.y - - near_0.x * near_1.y) - .abs() - .div(near_0.distance(near_1)); + // Find the two location centers + let near_0 = this_loc.center.map(|e| e as f32); + let near_1 = other_loc.center.map(|e| e as f32); + + // Calculate distance to path between them + (0.0 + (near_1.y - near_0.y) * wposf_turb.x as f32 + - (near_1.x - near_0.x) * wposf_turb.y as f32 + + near_1.x * near_0.y + - near_0.x * near_1.y) + .abs() + .div(near_0.distance(near_1)) + }) + .filter(|x| x.is_finite()) + .min_by(|a, b| a.partial_cmp(b).unwrap()) + .unwrap_or(f32::INFINITY) + }, + None => f32::INFINITY, + }; let on_path = dist_to_path < 5.0; // || near_0.distance(wposf_turb.map(|e| e as f32)) < 150.0; @@ -163,6 +171,23 @@ impl<'a> Sampler for ColumnGen<'a> { (alt, ground) }; + // Cities + let building = match &sim_chunk.location { + Some(loc) => { + let loc = &sim.locations[loc.loc_idx]; + let rpos = wposf.map2(loc.center, |a, b| a as f32 - b as f32) / 256.0 + 0.5; + + if rpos.map(|e| e >= 0.0 && e < 1.0).reduce_and() { + (loc.settlement.get_at(rpos).map(|b| b.seed % 20 + 10).unwrap_or(0)) as f32 + } else { + 0.0 + } + }, + None => 0.0, + }; + + let alt = alt + building; + // Caves let cave_at = |wposf: Vec2| { (sim.gen_ctx.cave_0_nz.get( @@ -228,6 +253,7 @@ impl<'a> Sampler for ColumnGen<'a> { cliff_hill, close_cliffs: sim.gen_ctx.cliff_gen.get(wpos), temp, + spawn_rate, location: sim_chunk.location.as_ref(), }) } @@ -251,5 +277,6 @@ pub struct ColumnSample<'a> { pub cliff_hill: f32, pub close_cliffs: [(Vec2, u32); 9], pub temp: f32, + pub spawn_rate: f32, pub location: Option<&'a LocationInfo>, } diff --git a/world/src/lib.rs b/world/src/lib.rs index 36af8e2536..515ffd13da 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -74,7 +74,7 @@ impl World { None => return TerrainChunk::new(0, water, air, TerrainChunkMeta::void()), }; - let meta = TerrainChunkMeta::new(sim_chunk.get_name(), sim_chunk.get_biome()); + let meta = TerrainChunkMeta::new(sim_chunk.get_name(&self.sim), sim_chunk.get_biome()); let mut chunk = TerrainChunk::new(base_z - 8, stone, air, meta); diff --git a/world/src/sim/location.rs b/world/src/sim/location.rs index 1acd7d45c3..916ffba554 100644 --- a/world/src/sim/location.rs +++ b/world/src/sim/location.rs @@ -1,27 +1,25 @@ use rand::Rng; use vek::*; - -#[derive(Copy, Clone, Debug)] -pub enum LocationKind { - Settlement, - Wildnerness, -} +use fxhash::FxHashSet; +use super::Settlement; #[derive(Clone, Debug)] pub struct Location { - name: String, - center: Vec2, - kind: LocationKind, - kingdom: Option, + pub(crate) name: String, + pub(crate) center: Vec2, + pub(crate) kingdom: Option, + pub(crate) neighbours: FxHashSet, + pub(crate) settlement: Settlement, } impl Location { - pub fn generate(center: Vec2, rng: &mut R) -> Self { + pub fn generate(center: Vec2, rng: &mut impl Rng) -> Self { Self { name: generate_name(rng), center, - kind: LocationKind::Wildnerness, kingdom: None, + neighbours: FxHashSet::default(), + settlement: Settlement::generate(rng), } } diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 2dbd759815..5a237c6460 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -1,7 +1,9 @@ mod location; +mod settlement; // Reexports pub use self::location::Location; +pub use self::settlement::Settlement; use crate::{ all::ForestKind, @@ -49,6 +51,8 @@ pub(crate) struct GenCtx { pub struct WorldSim { pub seed: u32, pub(crate) chunks: Vec, + pub(crate) locations: Vec, + pub(crate) gen_ctx: GenCtx, pub rng: XorShiftRng, } @@ -91,6 +95,7 @@ impl WorldSim { let mut this = Self { seed, chunks, + locations: Vec::new(), gen_ctx, rng: XorShiftRng::from_seed([ (seed >> 0) as u8, @@ -113,7 +118,6 @@ impl WorldSim { }; this.seed_elements(); - this.simulate(0); this } @@ -126,7 +130,8 @@ impl WorldSim { let grid_size = WORLD_SIZE / cell_size; let loc_count = 250; - let mut locations = vec![None; grid_size.product()]; + let mut loc_grid = vec![None; grid_size.product()]; + let mut locations = Vec::new(); // Seed the world with some locations for _ in 0..loc_count { @@ -134,13 +139,35 @@ impl WorldSim { self.rng.gen::() % grid_size.x, self.rng.gen::() % grid_size.y, ); - let wpos = (cell_pos * cell_size) + let wpos = (cell_pos * cell_size + cell_size / 2) .map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| { - e as i32 * sz as i32 + e as i32 * sz as i32 + sz as i32 / 2 }); - locations[cell_pos.y * grid_size.x + cell_pos.x] = - Some(Arc::new(Location::generate(wpos, &mut rng))); + locations.push(Location::generate(wpos, &mut rng)); + + loc_grid[cell_pos.y * grid_size.x + cell_pos.x] = Some(locations.len() - 1); + } + + // Find neighbours + let mut loc_clone = locations + .iter() + .map(|l| l.center) + .enumerate() + .collect::>(); + for i in 0..locations.len() { + let pos = locations[i].center; + + loc_clone.sort_by_key(|(_, l)| l.distance_squared(pos)); + + loc_clone + .iter() + .skip(1) + .take(2) + .for_each(|(j, _)| { + locations[i].neighbours.insert(*j); + locations[*j].neighbours.insert(i); + }); } // Simulate invasion! @@ -148,13 +175,13 @@ impl WorldSim { for _ in 0..invasion_cycles { for i in 0..grid_size.x { for j in 0..grid_size.y { - if locations[j * grid_size.x + i].is_none() { + if loc_grid[j * grid_size.x + i].is_none() { const R_COORDS: [i32; 5] = [-1, 0, 1, 0, -1]; let idx = self.rng.gen::() % 4; let loc = Vec2::new(i as i32 + R_COORDS[idx], j as i32 + R_COORDS[idx + 1]) .map(|e| e as usize); - locations[j * grid_size.x + i] = locations + loc_grid[j * grid_size.x + i] = loc_grid .get(loc.y * grid_size.x + loc.x) .cloned() .flatten(); @@ -168,6 +195,7 @@ impl WorldSim { for i in 0..WORLD_SIZE.x { for j in 0..WORLD_SIZE.y { let chunk_pos = Vec2::new(i as i32, j as i32); + let block_pos = Vec2::new(chunk_pos.x * TerrainChunkSize::SIZE.x as i32, chunk_pos.y * TerrainChunkSize::SIZE.y as i32); let cell_pos = Vec2::new(i / cell_size, j / cell_size); // Find the distance to each region @@ -188,43 +216,28 @@ impl WorldSim { near.sort_by(|a, b| a.dist.partial_cmp(&b.dist).unwrap()); let nearest_cell_pos = near[0].chunk_pos.map(|e| e as usize) / cell_size; - self.get_mut(chunk_pos).unwrap().location = locations + self.get_mut(chunk_pos).unwrap().location = loc_grid .get(nearest_cell_pos.y * grid_size.x + nearest_cell_pos.x) .cloned() .unwrap_or(None) - .map(|loc| LocationInfo { loc, near }); - } - } + .map(|loc_idx| LocationInfo { loc_idx, near }); - self.rng = rng; - } - - pub fn simulate(&mut self, cycles: usize) { - let mut rng = self.rng.clone(); - - for _ in 0..cycles { - for i in 0..WORLD_SIZE.x as i32 { - for j in 0..WORLD_SIZE.y as i32 { - let pos = Vec2::new(i, j); - - let location = self.get(pos).unwrap().location.clone(); - - let rpos = - Vec2::new(rng.gen::(), rng.gen::()).map(|e| e.abs() % 3 - 1); - - if let Some(other) = &mut self.get_mut(pos + rpos) { - if other.location.is_none() - && rng.gen::() > other.chaos * 1.5 - && other.alt > CONFIG.sea_level - { - other.location = location; - } - } + let town_size = 200; + let in_town = self + .get(chunk_pos) + .unwrap() + .location + .as_ref() + .map(|l| locations[l.loc_idx].center.distance_squared(block_pos) < town_size * town_size) + .unwrap_or(false); + if in_town { + self.get_mut(chunk_pos).unwrap().spawn_rate = 0.0; } } } self.rng = rng; + self.locations = locations; } pub fn get(&self, chunk_pos: Vec2) -> Option<&SimChunk> { @@ -312,6 +325,7 @@ pub struct SimChunk { pub near_cliffs: bool, pub tree_density: f32, pub forest_kind: ForestKind, + pub spawn_rate: f32, pub location: Option, } @@ -325,7 +339,7 @@ pub struct RegionInfo { #[derive(Clone)] pub struct LocationInfo { - pub loc: Arc, + pub loc_idx: usize, pub near: Vec, } @@ -437,6 +451,7 @@ impl SimChunk { ForestKind::SnowPine } }, + spawn_rate: 1.0, location: None, } } @@ -454,8 +469,14 @@ impl SimChunk { .max(CONFIG.sea_level + 2.0) } - pub fn get_name(&self) -> Option { - self.location.as_ref().map(|l| l.loc.name().to_string()) + pub fn get_name(&self, world: &WorldSim) -> Option { + if let Some(loc) = &self.location { + Some(world.locations[loc.loc_idx] + .name() + .to_string()) + } else { + None + } } pub fn get_biome(&self) -> BiomeKind { diff --git a/world/src/sim/settlement.rs b/world/src/sim/settlement.rs new file mode 100644 index 0000000000..946193aef8 --- /dev/null +++ b/world/src/sim/settlement.rs @@ -0,0 +1,95 @@ +use rand::Rng; +use vek::*; + +#[derive(Clone, Debug)] +pub struct Settlement { + lot: Lot, +} + +impl Settlement { + pub fn generate(rng: &mut impl Rng) -> Self { + Self { + lot: Lot::generate(0, 32.0, 1.0, rng), + } + } + + pub fn get_at(&self, pos: Vec2) -> Option<&Building> { + self.lot.get_at(pos) + } +} + +#[derive(Clone, Debug)] +pub struct Building { + pub seed: u32, +} + +#[derive(Clone, Debug)] +enum Lot { + None, + One(Building), + Many { + split_x: bool, + lots: Vec, + }, +} + +impl Lot { + pub fn generate(deep: usize, depth: f32, aspect: f32, rng: &mut impl Rng) -> Self { + let depth = if deep < 3 { + 8.0 + } else { + depth + }; + + if (depth < 1.0 || deep > 6) && !(deep < 3 || deep % 2 == 1) { + if rng.gen::() < 0.5 { + Lot::One(Building { + seed: rng.gen(), + }) + } else { + Lot::None + } + } else { + Lot::Many { + split_x: aspect > 1.0, + lots: { + let pow2 = 1 + rng.gen::() % 1; + let n = 1 << pow2; + + let new_aspect = if aspect > 1.0 { + aspect / n as f32 + } else { + aspect * n as f32 + }; + + let vari = (rng.gen::() - 0.35) * 2.8; + let new_depth = depth * 0.5 * (1.0 + vari); + + (0..n) + .map(|_| Lot::generate(deep + 1, new_depth, new_aspect, rng)) + .collect() + }, + } + } + } + + pub fn get_at(&self, pos: Vec2) -> Option<&Building> { + match self { + Lot::None => None, + Lot::One(building) => if pos.map(|e| e > 0.1 && e < 0.9).reduce_and() { + Some(building) + } else { + None + }, + Lot::Many { split_x, lots } => { + let split_dim = if *split_x { pos.x } else { pos.y }; + let idx = (split_dim * lots.len() as f32).floor() as usize; + lots[idx.min(lots.len() - 1)].get_at(if *split_x { + Vec2::new((pos.x * lots.len() as f32).fract(), pos.y) + } else { + Vec2::new(pos.x, (pos.y * lots.len() as f32).fract()) + }) + }, + } + } +} From e414b82d2fb8b8dc76ed9ccc56f884fcec330e95 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Wed, 26 Jun 2019 01:27:41 +0100 Subject: [PATCH 39/40] fmt --- world/examples/city.rs | 9 +++++++-- world/examples/turb.rs | 15 +++++---------- world/src/column/mod.rs | 12 ++++++++---- world/src/sim/location.rs | 4 ++-- world/src/sim/mod.rs | 32 +++++++++++++++----------------- world/src/sim/settlement.rs | 29 +++++++++++------------------ 6 files changed, 48 insertions(+), 53 deletions(-) diff --git a/world/examples/city.rs b/world/examples/city.rs index 6bd9af95af..8774b3daf9 100644 --- a/world/examples/city.rs +++ b/world/examples/city.rs @@ -1,7 +1,7 @@ +use rand::thread_rng; use std::ops::{Add, Mul, Sub}; use vek::*; use veloren_world::sim::Settlement; -use rand::thread_rng; const W: usize = 640; const H: usize = 480; @@ -21,7 +21,12 @@ fn main() { let seed = settlement.get_at(pos).map(|b| b.seed).unwrap_or(0); - buf[j * W + i] = u32::from_le_bytes([(seed >> 0) as u8, (seed >> 8) as u8, (seed >> 16) as u8, (seed >> 24) as u8]); + buf[j * W + i] = u32::from_le_bytes([ + (seed >> 0) as u8, + (seed >> 8) as u8, + (seed >> 16) as u8, + (seed >> 24) as u8, + ]); } } diff --git a/world/examples/turb.rs b/world/examples/turb.rs index 419d70756e..6fa2f94a4b 100644 --- a/world/examples/turb.rs +++ b/world/examples/turb.rs @@ -1,15 +1,14 @@ +use noise::{NoiseFn, Seedable, SuperSimplex}; +use rand::thread_rng; use std::ops::{Add, Mul, Sub}; use vek::*; use veloren_world::sim::Settlement; -use rand::thread_rng; -use noise::{Seedable, NoiseFn, SuperSimplex}; const W: usize = 640; const H: usize = 640; fn main() { - let mut win = - minifb::Window::new("Turb", W, H, minifb::WindowOptions::default()).unwrap(); + let mut win = minifb::Window::new("Turb", W, H, minifb::WindowOptions::default()).unwrap(); let nz_x = SuperSimplex::new().set_seed(0); let nz_y = SuperSimplex::new().set_seed(1); @@ -24,13 +23,9 @@ fn main() { let pos = pos * 10.0; - let pos = (0..10) - .fold(pos, |pos, _| pos.map(|e| e.powf(3.0) - 1.0)); + let pos = (0..10).fold(pos, |pos, _| pos.map(|e| e.powf(3.0) - 1.0)); - let val = if pos - .map(|e| e.abs() < 0.5) - .reduce_and() - { + let val = if pos.map(|e| e.abs() < 0.5).reduce_and() { 1.0f32 } else { 0.0 diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 82d59dbb4e..8baff7863a 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -139,7 +139,8 @@ impl<'a> Sampler for ColumnGen<'a> { let dist_to_path = match &sim_chunk.location { Some(loc) => { let this_loc = &sim.locations[loc.loc_idx]; - this_loc.neighbours + this_loc + .neighbours .iter() .map(|j| { let other_loc = &sim.locations[*j]; @@ -159,7 +160,7 @@ impl<'a> Sampler for ColumnGen<'a> { .filter(|x| x.is_finite()) .min_by(|a, b| a.partial_cmp(b).unwrap()) .unwrap_or(f32::INFINITY) - }, + } None => f32::INFINITY, }; @@ -178,11 +179,14 @@ impl<'a> Sampler for ColumnGen<'a> { let rpos = wposf.map2(loc.center, |a, b| a as f32 - b as f32) / 256.0 + 0.5; if rpos.map(|e| e >= 0.0 && e < 1.0).reduce_and() { - (loc.settlement.get_at(rpos).map(|b| b.seed % 20 + 10).unwrap_or(0)) as f32 + (loc.settlement + .get_at(rpos) + .map(|b| b.seed % 20 + 10) + .unwrap_or(0)) as f32 } else { 0.0 } - }, + } None => 0.0, }; diff --git a/world/src/sim/location.rs b/world/src/sim/location.rs index 916ffba554..240ddd03bf 100644 --- a/world/src/sim/location.rs +++ b/world/src/sim/location.rs @@ -1,7 +1,7 @@ +use super::Settlement; +use fxhash::FxHashSet; use rand::Rng; use vek::*; -use fxhash::FxHashSet; -use super::Settlement; #[derive(Clone, Debug)] pub struct Location { diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 5a237c6460..158a2d6aa8 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -160,14 +160,10 @@ impl WorldSim { loc_clone.sort_by_key(|(_, l)| l.distance_squared(pos)); - loc_clone - .iter() - .skip(1) - .take(2) - .for_each(|(j, _)| { - locations[i].neighbours.insert(*j); - locations[*j].neighbours.insert(i); - }); + loc_clone.iter().skip(1).take(2).for_each(|(j, _)| { + locations[i].neighbours.insert(*j); + locations[*j].neighbours.insert(i); + }); } // Simulate invasion! @@ -181,10 +177,8 @@ impl WorldSim { let loc = Vec2::new(i as i32 + R_COORDS[idx], j as i32 + R_COORDS[idx + 1]) .map(|e| e as usize); - loc_grid[j * grid_size.x + i] = loc_grid - .get(loc.y * grid_size.x + loc.x) - .cloned() - .flatten(); + loc_grid[j * grid_size.x + i] = + loc_grid.get(loc.y * grid_size.x + loc.x).cloned().flatten(); } } } @@ -195,7 +189,10 @@ impl WorldSim { for i in 0..WORLD_SIZE.x { for j in 0..WORLD_SIZE.y { let chunk_pos = Vec2::new(i as i32, j as i32); - let block_pos = Vec2::new(chunk_pos.x * TerrainChunkSize::SIZE.x as i32, chunk_pos.y * TerrainChunkSize::SIZE.y as i32); + let block_pos = Vec2::new( + chunk_pos.x * TerrainChunkSize::SIZE.x as i32, + chunk_pos.y * TerrainChunkSize::SIZE.y as i32, + ); let cell_pos = Vec2::new(i / cell_size, j / cell_size); // Find the distance to each region @@ -228,7 +225,10 @@ impl WorldSim { .unwrap() .location .as_ref() - .map(|l| locations[l.loc_idx].center.distance_squared(block_pos) < town_size * town_size) + .map(|l| { + locations[l.loc_idx].center.distance_squared(block_pos) + < town_size * town_size + }) .unwrap_or(false); if in_town { self.get_mut(chunk_pos).unwrap().spawn_rate = 0.0; @@ -471,9 +471,7 @@ impl SimChunk { pub fn get_name(&self, world: &WorldSim) -> Option { if let Some(loc) = &self.location { - Some(world.locations[loc.loc_idx] - .name() - .to_string()) + Some(world.locations[loc.loc_idx].name().to_string()) } else { None } diff --git a/world/src/sim/settlement.rs b/world/src/sim/settlement.rs index 946193aef8..aadae70693 100644 --- a/world/src/sim/settlement.rs +++ b/world/src/sim/settlement.rs @@ -27,25 +27,16 @@ pub struct Building { enum Lot { None, One(Building), - Many { - split_x: bool, - lots: Vec, - }, + Many { split_x: bool, lots: Vec }, } impl Lot { pub fn generate(deep: usize, depth: f32, aspect: f32, rng: &mut impl Rng) -> Self { - let depth = if deep < 3 { - 8.0 - } else { - depth - }; + let depth = if deep < 3 { 8.0 } else { depth }; if (depth < 1.0 || deep > 6) && !(deep < 3 || deep % 2 == 1) { if rng.gen::() < 0.5 { - Lot::One(Building { - seed: rng.gen(), - }) + Lot::One(Building { seed: rng.gen() }) } else { Lot::None } @@ -76,11 +67,13 @@ impl Lot { pub fn get_at(&self, pos: Vec2) -> Option<&Building> { match self { Lot::None => None, - Lot::One(building) => if pos.map(|e| e > 0.1 && e < 0.9).reduce_and() { - Some(building) - } else { - None - }, + Lot::One(building) => { + if pos.map(|e| e > 0.1 && e < 0.9).reduce_and() { + Some(building) + } else { + None + } + } Lot::Many { split_x, lots } => { let split_dim = if *split_x { pos.x } else { pos.y }; let idx = (split_dim * lots.len() as f32).floor() as usize; @@ -89,7 +82,7 @@ impl Lot { } else { Vec2::new(pos.x, (pos.y * lots.len() as f32).fract()) }) - }, + } } } } From 5839990a28c6fad3982fa9cabde5e22720511512 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Wed, 26 Jun 2019 19:32:26 +0100 Subject: [PATCH 40/40] Disabled cities until a later MR --- world/src/column/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index 8baff7863a..05a27e6534 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -164,7 +164,7 @@ impl<'a> Sampler for ColumnGen<'a> { None => f32::INFINITY, }; - let on_path = dist_to_path < 5.0; // || near_0.distance(wposf_turb.map(|e| e as f32)) < 150.0; + let on_path = dist_to_path < 5.0 && !sim_chunk.near_cliffs; // || near_0.distance(wposf_turb.map(|e| e as f32)) < 150.0; let (alt, ground) = if on_path { (alt - 1.0, dirt) @@ -173,6 +173,8 @@ impl<'a> Sampler for ColumnGen<'a> { }; // Cities + // TODO: In a later MR + /* let building = match &sim_chunk.location { Some(loc) => { let loc = &sim.locations[loc.loc_idx]; @@ -191,6 +193,7 @@ impl<'a> Sampler for ColumnGen<'a> { }; let alt = alt + building; + */ // Caves let cave_at = |wposf: Vec2| {