Former-commit-id: 1f7bec8da117091b3f2e8f58ce45b9caf1b6c89d
This commit is contained in:
Joshua Barretto
2019-05-21 23:31:38 +01:00
parent 78f9d00604
commit 91ce041c91
9 changed files with 120 additions and 106 deletions

View File

@ -58,9 +58,7 @@ impl ReadVol for Chonk {
if pos.z < self.z_offset { if pos.z < self.z_offset {
// Below the terrain // Below the terrain
Ok(&self.below) Ok(&self.below)
} else if pos.z } else if pos.z >= self.z_offset + SUB_CHUNK_HEIGHT as i32 * self.sub_chunks.len() as i32 {
>= self.z_offset + SUB_CHUNK_HEIGHT as i32 * self.sub_chunks.len() as i32
{
// Above the terrain // Above the terrain
Ok(&self.above) Ok(&self.above)
} else { } else {
@ -74,8 +72,7 @@ impl ReadVol for Chonk {
SubChunk::Heterogeneous(chunk) => { SubChunk::Heterogeneous(chunk) => {
let rpos = pos let rpos = pos
- Vec3::unit_z() - Vec3::unit_z()
* (self.z_offset * (self.z_offset + sub_chunk_idx as i32 * SUB_CHUNK_HEIGHT as i32);
+ sub_chunk_idx as i32 * SUB_CHUNK_HEIGHT as i32);
chunk.get(rpos).map_err(|err| ChonkError::ChunkError(err)) chunk.get(rpos).map_err(|err| ChonkError::ChunkError(err))
} }
} }
@ -96,8 +93,7 @@ impl WriteVol for Chonk {
} }
let rpos = pos let rpos = pos
- Vec3::unit_z() - Vec3::unit_z() * (self.z_offset + sub_chunk_idx as i32 * SUB_CHUNK_HEIGHT as i32);
* (self.z_offset + sub_chunk_idx as i32 * SUB_CHUNK_HEIGHT as i32);
match &mut self.sub_chunks[sub_chunk_idx] { match &mut self.sub_chunks[sub_chunk_idx] {
// Can't fail // Can't fail

View File

@ -23,7 +23,13 @@ use specs::{
join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder, join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder,
Entity as EcsEntity, Entity as EcsEntity,
}; };
use std::{collections::HashSet, i32, net::SocketAddr, sync::{Arc, mpsc}, time::Duration}; use std::{
collections::HashSet,
i32,
net::SocketAddr,
sync::{mpsc, Arc},
time::Duration,
};
use threadpool::ThreadPool; use threadpool::ThreadPool;
use vek::*; use vek::*;
use world::World; use world::World;
@ -68,7 +74,9 @@ impl Server {
let mut state = State::new(); let mut state = State::new();
state.ecs_mut().register::<comp::phys::ForceUpdate>(); state.ecs_mut().register::<comp::phys::ForceUpdate>();
state.ecs_mut().add_resource(SpawnPoint(Vec3::new(16_384.0, 16_384.0, 150.0))); state
.ecs_mut()
.add_resource(SpawnPoint(Vec3::new(16_384.0, 16_384.0, 150.0)));
let mut this = Self { let mut this = Self {
state, state,

View File

@ -1,6 +1,6 @@
use log::info;
use client::{error::Error as ClientError, Client}; use client::{error::Error as ClientError, Client};
use common::comp; use common::comp;
use log::info;
use std::{ use std::{
net::ToSocketAddrs, net::ToSocketAddrs,
sync::mpsc::{channel, Receiver, TryRecvError}, sync::mpsc::{channel, Receiver, TryRecvError},

View File

@ -55,12 +55,21 @@ impl<V: BaseVol<Vox = Block> + ReadVol, S: VolSize + Clone> Meshable for VolMap2
for y in range.min.y + 1..range.max.y - 1 { for y in range.min.y + 1..range.max.y - 1 {
for z in range.min.z..range.max.z { for z in range.min.z..range.max.z {
let pos = Vec3::new(x, y, z); let pos = Vec3::new(x, y, z);
let offs = (pos - range.min * Vec3::new(1, 1, 0)).map(|e| e as f32) - Vec3::new(1.0, 1.0, 0.0); let offs = (pos - range.min * Vec3::new(1, 1, 0)).map(|e| e as f32)
- Vec3::new(1.0, 1.0, 0.0);
if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) { if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) {
let col = col.map(|e| e as f32 / 255.0); let col = col.map(|e| e as f32 / 255.0);
vol::push_vox_verts(&mut mesh, self, pos, offs, col, TerrainVertex::new, false); vol::push_vox_verts(
&mut mesh,
self,
pos,
offs,
col,
TerrainVertex::new,
false,
);
} }
} }
} }

View File

@ -60,13 +60,21 @@ fn create_quad<P: Pipeline, F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>) -> P::Vertex>(
vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao_map[3])), vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao_map[3])),
vcons(origin, norm, Rgb::lerp(dark, col, ao_map[0])), 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_x, norm, Rgb::lerp(dark, col, ao_map[1])),
vcons(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao_map[2])), vcons(
origin + unit_x + unit_y,
norm,
Rgb::lerp(dark, col, ao_map[2]),
),
) )
} else { } else {
Quad::new( Quad::new(
vcons(origin, norm, Rgb::lerp(dark, col, ao_map[0])), 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_x, norm, Rgb::lerp(dark, col, ao_map[1])),
vcons(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao_map[2])), vcons(
origin + unit_x + unit_y,
norm,
Rgb::lerp(dark, col, ao_map[2]),
),
vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao_map[3])), vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao_map[3])),
) )
} }

View File

@ -4,7 +4,7 @@ use crate::{
}; };
use client::Client; use client::Client;
use common::{terrain::TerrainMap, vol::SampleVol, volumes::vol_map_2d::VolMap2dErr}; use common::{terrain::TerrainMap, vol::SampleVol, volumes::vol_map_2d::VolMap2dErr};
use std::{collections::HashMap, sync::mpsc, time::Duration, i32}; use std::{collections::HashMap, i32, sync::mpsc, time::Duration};
use vek::*; use vek::*;
struct TerrainChunk { struct TerrainChunk {

View File

@ -1,4 +1,4 @@
use std::ops::{Add, Sub, Mul}; use std::ops::{Add, Mul, Sub};
use vek::*; use vek::*;
use veloren_world::World; use veloren_world::World;
@ -8,11 +8,8 @@ const H: usize = 480;
fn main() { fn main() {
let world = World::generate(0); let world = World::generate(0);
let mut win = minifb::Window::new( let mut win =
"World Viewer", minifb::Window::new("World Viewer", W, H, minifb::WindowOptions::default()).unwrap();
W, H,
minifb::WindowOptions::default(),
).unwrap();
let mut focus = Vec2::zero(); let mut focus = Vec2::zero();
let mut gain = 1.0; let mut gain = 1.0;
@ -27,13 +24,7 @@ fn main() {
let alt = world let alt = world
.sim() .sim()
.sample(pos) .sample(pos)
.map(|sample| sample .map(|sample| sample.alt.sub(64.0).add(gain).mul(0.7).max(0.0).min(255.0) as u8)
.alt
.sub(64.0)
.add(gain)
.mul(0.7)
.max(0.0)
.min(255.0) as u8)
.unwrap_or(0); .unwrap_or(0);
buf[j * W + i] = u32::from_le_bytes([alt; 4]); buf[j * W + i] = u32::from_le_bytes([alt; 4]);

View File

@ -1,15 +1,15 @@
mod sim; mod sim;
use std::{
ops::{Add, Sub, Mul, Div, Neg},
time::Duration,
};
use noise::{NoiseFn, BasicMulti, Perlin, Seedable, MultiFractal};
use vek::*;
use common::{ use common::{
terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize}, terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
vol::{SizedVol, VolSize, Vox, WriteVol}, vol::{SizedVol, VolSize, Vox, WriteVol},
}; };
use noise::{BasicMulti, MultiFractal, NoiseFn, Perlin, Seedable};
use std::{
ops::{Add, Div, Mul, Neg, Sub},
time::Duration,
};
use vek::*;
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
@ -22,7 +22,9 @@ pub struct World {
impl World { impl World {
pub fn generate(seed: u32) -> Self { pub fn generate(seed: u32) -> Self {
Self { sim: sim::WorldSim::generate(seed) } Self {
sim: sim::WorldSim::generate(seed),
}
} }
pub fn sim(&self) -> &sim::WorldSim { pub fn sim(&self) -> &sim::WorldSim {
@ -43,9 +45,7 @@ impl World {
let sand = Block::new(4, Rgb::new(180, 150, 50)); let sand = Block::new(4, Rgb::new(180, 150, 50));
let water = Block::new(5, Rgb::new(100, 150, 255)); let water = Block::new(5, Rgb::new(100, 150, 255));
let warp_nz = BasicMulti::new() let warp_nz = BasicMulti::new().set_octaves(3).set_seed(self.sim.seed + 0);
.set_octaves(3)
.set_seed(self.sim.seed + 0);
let base_z = match self.sim.get_base_z(chunk_pos.map(|e| e as u32)) { let base_z = match self.sim.get_base_z(chunk_pos.map(|e| e as u32)) {
Some(base_z) => base_z as i32, Some(base_z) => base_z as i32,
@ -56,30 +56,34 @@ impl World {
for x in 0..TerrainChunkSize::SIZE.x as i32 { for x in 0..TerrainChunkSize::SIZE.x as i32 {
for y in 0..TerrainChunkSize::SIZE.y as i32 { for y in 0..TerrainChunkSize::SIZE.y as i32 {
let wpos2d = Vec2::new(x, y) + Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32); let wpos2d = Vec2::new(x, y)
+ Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32);
let wposf2d = wpos2d.map(|e| e as f64); let wposf2d = wpos2d.map(|e| e as f64);
let sim::Sample { let sim::Sample {
alt, alt,
chaos, chaos,
surface_color surface_color,
} = if let Some(sample) = self.sim.sample(wpos2d) { } = if let Some(sample) = self.sim.sample(wpos2d) {
sample sample
} else { } else {
continue continue;
}; };
let max_z = self.sim let max_z = self
.sim
.get_interpolated(wpos2d, |chunk| chunk.get_max_z()) .get_interpolated(wpos2d, |chunk| chunk.get_max_z())
.unwrap_or(0.0) as i32; .unwrap_or(0.0) as i32;
for z in base_z..max_z { for z in base_z..max_z {
let lpos = Vec3::new(x, y, z); let lpos = Vec3::new(x, y, z);
let wpos = lpos let wpos =
+ Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32); lpos + Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32);
let wposf = wpos.map(|e| e as f64); let wposf = wpos.map(|e| e as f64);
let warp = (warp_nz.get((wposf.div(Vec3::new(120.0, 120.0, 150.0))).into_array()) as f32) let warp = (warp_nz
.get((wposf.div(Vec3::new(120.0, 120.0, 150.0))).into_array())
as f32)
.mul((chaos - 0.1).max(0.0)) .mul((chaos - 0.1).max(0.0))
.mul(90.0); .mul(90.0);

View File

@ -1,13 +1,13 @@
use common::{terrain::TerrainChunkSize, vol::VolSize};
use noise::{
BasicMulti, HybridMulti, MultiFractal, NoiseFn, OpenSimplex, RidgedMulti, Seedable,
SuperSimplex,
};
use std::{ use std::{
ops::{Add, Sub, Mul, Div, Neg},
f32, f32,
ops::{Add, Div, Mul, Neg, Sub},
}; };
use noise::{NoiseFn, BasicMulti, HybridMulti, RidgedMulti, SuperSimplex, OpenSimplex, Seedable, MultiFractal};
use vek::*; use vek::*;
use common::{
terrain::TerrainChunkSize,
vol::VolSize,
};
pub const WORLD_SIZE: Vec2<usize> = Vec2 { x: 1024, y: 1024 }; pub const WORLD_SIZE: Vec2<usize> = Vec2 { x: 1024, y: 1024 };
@ -20,27 +20,17 @@ pub struct WorldSim {
impl WorldSim { impl WorldSim {
pub fn generate(seed: u32) -> Self { pub fn generate(seed: u32) -> Self {
let mut gen_ctx = GenCtx { let mut gen_ctx = GenCtx {
turb_x_nz: BasicMulti::new() turb_x_nz: BasicMulti::new().set_seed(seed + 0),
.set_seed(seed + 0), turb_y_nz: BasicMulti::new().set_seed(seed + 1),
turb_y_nz: BasicMulti::new() chaos_nz: RidgedMulti::new().set_octaves(7).set_seed(seed + 2),
.set_seed(seed + 1), hill_nz: SuperSimplex::new().set_seed(seed + 3),
chaos_nz: RidgedMulti::new()
.set_octaves(7)
.set_seed(seed + 2),
hill_nz: SuperSimplex::new()
.set_seed(seed + 3),
alt_nz: HybridMulti::new() alt_nz: HybridMulti::new()
.set_octaves(7) .set_octaves(7)
.set_persistence(0.1) .set_persistence(0.1)
.set_seed(seed + 4), .set_seed(seed + 4),
temp_nz: SuperSimplex::new() temp_nz: SuperSimplex::new().set_seed(seed + 5),
.set_seed(seed + 5), small_nz: BasicMulti::new().set_octaves(2).set_seed(seed + 6),
small_nz: BasicMulti::new() rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 7),
.set_octaves(2)
.set_seed(seed + 6),
rock_nz: HybridMulti::new()
.set_persistence(0.3)
.set_seed(seed + 7),
}; };
let mut chunks = Vec::new(); let mut chunks = Vec::new();
@ -58,7 +48,10 @@ impl WorldSim {
} }
pub fn get(&self, chunk_pos: Vec2<u32>) -> Option<&SimChunk> { pub fn get(&self, chunk_pos: Vec2<u32>) -> Option<&SimChunk> {
if chunk_pos.map2(WORLD_SIZE, |e, sz| e < sz as u32).reduce_and() { if chunk_pos
.map2(WORLD_SIZE, |e, sz| e < sz as u32)
.reduce_and()
{
Some(&self.chunks[chunk_pos.y as usize * WORLD_SIZE.x + chunk_pos.x as usize]) Some(&self.chunks[chunk_pos.y as usize * WORLD_SIZE.x + chunk_pos.x as usize])
} else { } else {
None None
@ -66,25 +59,27 @@ impl WorldSim {
} }
pub fn get_base_z(&self, chunk_pos: Vec2<u32>) -> Option<f32> { pub fn get_base_z(&self, chunk_pos: Vec2<u32>) -> Option<f32> {
self self.get(chunk_pos).and_then(|_| {
.get(chunk_pos) (0..2)
.and_then(|_| (0..2) .map(|i| (0..2).map(move |j| (i, j)))
.map(|i| (0..2)
.map(move |j| (i, j)))
.flatten() .flatten()
.map(|(i, j)| self .map(|(i, j)| {
.get(chunk_pos + Vec2::new(i, j)) self.get(chunk_pos + Vec2::new(i, j))
.map(|c| c.get_base_z())) .map(|c| c.get_base_z())
})
.flatten() .flatten()
.fold(None, |a: Option<f32>, x| a.map(|a| a.min(x)).or(Some(x)))) .fold(None, |a: Option<f32>, x| a.map(|a| a.min(x)).or(Some(x)))
})
} }
pub fn get_interpolated<T, F>(&self, pos: Vec2<i32>, mut f: F) -> Option<T> pub fn get_interpolated<T, F>(&self, pos: Vec2<i32>, mut f: F) -> Option<T>
where where
T: Copy + Default + Add<Output=T> + Mul<f32, Output=T>, T: Copy + Default + Add<Output = T> + Mul<f32, Output = T>,
F: FnMut(&SimChunk) -> T, F: FnMut(&SimChunk) -> T,
{ {
let pos = pos.map2(TerrainChunkSize::SIZE.into(), |e, sz: u32| e as f64 / sz as f64); let pos = pos.map2(TerrainChunkSize::SIZE.into(), |e, sz: u32| {
e as f64 / sz as f64
});
let cubic = |a: T, b: T, c: T, d: T, x: f32| -> T { let cubic = |a: T, b: T, c: T, d: T, x: f32| -> T {
let x2 = x * x; let x2 = x * x;
@ -101,10 +96,11 @@ impl WorldSim {
let mut y = [T::default(); 4]; let mut y = [T::default(); 4];
for (y_idx, j) in (-1..3).enumerate() { for (y_idx, j) in (-1..3).enumerate() {
let x0 = f(self.get(pos.map2(Vec2::new(-1, j), |e, q| (e.max(0.0) as i32 + q) as u32))?); let x0 =
let x1 = f(self.get(pos.map2(Vec2::new( 0, j), |e, q| (e.max(0.0) as i32 + q) as u32))?); f(self.get(pos.map2(Vec2::new(-1, j), |e, q| (e.max(0.0) as i32 + q) as u32))?);
let x2 = f(self.get(pos.map2(Vec2::new( 1, j), |e, q| (e.max(0.0) as i32 + q) as u32))?); let x1 = f(self.get(pos.map2(Vec2::new(0, j), |e, q| (e.max(0.0) as i32 + q) as u32))?);
let x3 = f(self.get(pos.map2(Vec2::new( 2, j), |e, q| (e.max(0.0) as i32 + q) as u32))?); let x2 = f(self.get(pos.map2(Vec2::new(1, j), |e, q| (e.max(0.0) as i32 + q) as u32))?);
let x3 = f(self.get(pos.map2(Vec2::new(2, j), |e, q| (e.max(0.0) as i32 + q) as u32))?);
y[y_idx] = cubic(x0, x1, x2, x3, pos.x.fract() as f32); y[y_idx] = cubic(x0, x1, x2, x3, pos.x.fract() as f32);
} }
@ -131,7 +127,9 @@ impl WorldSim {
.mul(2.0); .mul(2.0);
let alt = self.get_interpolated(pos, |chunk| chunk.alt)? let alt = self.get_interpolated(pos, |chunk| chunk.alt)?
+ self.gen_ctx.small_nz.get((wposf.div(128.0)).into_array()) as f32 * chaos.max(0.15) * 32.0 + self.gen_ctx.small_nz.get((wposf.div(128.0)).into_array()) as f32
* chaos.max(0.15)
* 32.0
+ rock * 15.0; + rock * 15.0;
// Colours // Colours
@ -151,11 +149,7 @@ impl WorldSim {
surface_color: Rgb::lerp( surface_color: Rgb::lerp(
sand, sand,
// Land // Land
Rgb::lerp( Rgb::lerp(ground, cliff, (alt - SEA_LEVEL - 100.0) / 150.0),
ground,
cliff,
(alt - SEA_LEVEL - 100.0) / 150.0
),
// Beach // Beach
(alt - SEA_LEVEL - 2.0) / 5.0, (alt - SEA_LEVEL - 2.0) / 5.0,
), ),
@ -194,13 +188,11 @@ impl SimChunk {
fn generate(pos: Vec2<u32>, gen_ctx: &mut GenCtx) -> Self { fn generate(pos: Vec2<u32>, gen_ctx: &mut GenCtx) -> Self {
let wposf = (pos * Vec2::from(TerrainChunkSize::SIZE)).map(|e| e as f64); let wposf = (pos * Vec2::from(TerrainChunkSize::SIZE)).map(|e| e as f64);
let hill = (gen_ctx.hill_nz let hill = (gen_ctx.hill_nz.get((wposf.div(3500.0)).into_array()) as f32).max(0.0);
.get((wposf.div(3500.0)).into_array()) as f32)
.max(0.0);
let chaos = (gen_ctx.chaos_nz let chaos = (gen_ctx.chaos_nz.get((wposf.div(3500.0)).into_array()) as f32)
.get((wposf.div(3500.0)).into_array()) as f32) .add(1.0)
.add(1.0).mul(0.5) .mul(0.5)
.powf(1.9) .powf(1.9)
.add(0.25 * hill); .add(0.25 * hill);
@ -212,15 +204,21 @@ impl SimChunk {
Self { Self {
chaos, chaos,
alt: SEA_LEVEL + (0.0 alt: SEA_LEVEL
+ alt_main + (0.0
+ gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32 * alt_main.max(0.05) * chaos * 1.3) + alt_main
.add(1.0).mul(0.5) + gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32
.mul(chaos) * alt_main.max(0.05)
.add(alt_base) * chaos
.mul(750.0), * 1.3)
.add(1.0)
.mul(0.5)
.mul(chaos)
.add(alt_base)
.mul(750.0),
temp: (gen_ctx.temp_nz.get((wposf.div(48.0)).into_array()) as f32) temp: (gen_ctx.temp_nz.get((wposf.div(48.0)).into_array()) as f32)
.add(1.0).mul(0.5), .add(1.0)
.mul(0.5),
rockiness: (gen_ctx.rock_nz.get((wposf.div(1024.0)).into_array()) as f32) rockiness: (gen_ctx.rock_nz.get((wposf.div(1024.0)).into_array()) as f32)
.sub(0.1) .sub(0.1)
.mul(1.2) .mul(1.2)