Former-commit-id: 1f7bec8da117091b3f2e8f58ce45b9caf1b6c89d
This commit is contained in:
Joshua Barretto 2019-05-21 23:31:38 +01:00
parent a696847f67
commit fc25dc8c7f
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 {
// Below the terrain
Ok(&self.below)
} else if pos.z
>= self.z_offset + SUB_CHUNK_HEIGHT as i32 * self.sub_chunks.len() as i32
{
} else if pos.z >= self.z_offset + SUB_CHUNK_HEIGHT as i32 * self.sub_chunks.len() as i32 {
// Above the terrain
Ok(&self.above)
} else {
@ -74,8 +72,7 @@ impl ReadVol for Chonk {
SubChunk::Heterogeneous(chunk) => {
let rpos = pos
- 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);
chunk.get(rpos).map_err(|err| ChonkError::ChunkError(err))
}
}
@ -96,8 +93,7 @@ impl WriteVol for Chonk {
}
let rpos = pos
- Vec3::unit_z()
* (self.z_offset + sub_chunk_idx as i32 * SUB_CHUNK_HEIGHT as i32);
- Vec3::unit_z() * (self.z_offset + sub_chunk_idx as i32 * SUB_CHUNK_HEIGHT as i32);
match &mut self.sub_chunks[sub_chunk_idx] {
// Can't fail

View File

@ -23,7 +23,13 @@ use specs::{
join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder,
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 vek::*;
use world::World;
@ -68,7 +74,9 @@ impl Server {
let mut state = State::new();
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 {
state,

View File

@ -1,6 +1,6 @@
use log::info;
use client::{error::Error as ClientError, Client};
use common::comp;
use log::info;
use std::{
net::ToSocketAddrs,
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 z in range.min.z..range.max.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()) {
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, norm, Rgb::lerp(dark, col, ao_map[0])),
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 {
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 + 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])),
)
}

View File

@ -4,7 +4,7 @@ use crate::{
};
use client::Client;
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::*;
struct TerrainChunk {

View File

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

View File

@ -1,15 +1,15 @@
mod sim;
use std::{
ops::{Add, Sub, Mul, Div, Neg},
time::Duration,
};
use noise::{NoiseFn, BasicMulti, Perlin, Seedable, MultiFractal};
use vek::*;
use common::{
terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
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)]
pub enum Error {
@ -22,7 +22,9 @@ pub struct World {
impl World {
pub fn generate(seed: u32) -> Self {
Self { sim: sim::WorldSim::generate(seed) }
Self {
sim: sim::WorldSim::generate(seed),
}
}
pub fn sim(&self) -> &sim::WorldSim {
@ -43,9 +45,7 @@ impl World {
let sand = Block::new(4, Rgb::new(180, 150, 50));
let water = Block::new(5, Rgb::new(100, 150, 255));
let warp_nz = BasicMulti::new()
.set_octaves(3)
.set_seed(self.sim.seed + 0);
let warp_nz = BasicMulti::new().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)) {
Some(base_z) => base_z as i32,
@ -56,30 +56,34 @@ impl World {
for x in 0..TerrainChunkSize::SIZE.x 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 sim::Sample {
alt,
chaos,
surface_color
surface_color,
} = if let Some(sample) = self.sim.sample(wpos2d) {
sample
} else {
continue
continue;
};
let max_z = self.sim
let max_z = self
.sim
.get_interpolated(wpos2d, |chunk| chunk.get_max_z())
.unwrap_or(0.0) as i32;
for z in base_z..max_z {
let lpos = Vec3::new(x, y, z);
let wpos = lpos
+ Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32);
let wpos =
lpos + Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32);
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(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::{
ops::{Add, Sub, Mul, Div, Neg},
f32,
ops::{Add, Div, Mul, Neg, Sub},
};
use noise::{NoiseFn, BasicMulti, HybridMulti, RidgedMulti, SuperSimplex, OpenSimplex, Seedable, MultiFractal};
use vek::*;
use common::{
terrain::TerrainChunkSize,
vol::VolSize,
};
pub const WORLD_SIZE: Vec2<usize> = Vec2 { x: 1024, y: 1024 };
@ -20,27 +20,17 @@ 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),
chaos_nz: RidgedMulti::new()
.set_octaves(7)
.set_seed(seed + 2),
hill_nz: SuperSimplex::new()
.set_seed(seed + 3),
turb_x_nz: BasicMulti::new().set_seed(seed + 0),
turb_y_nz: BasicMulti::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()
.set_octaves(7)
.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),
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),
};
let mut chunks = Vec::new();
@ -58,7 +48,10 @@ impl WorldSim {
}
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])
} else {
None
@ -66,25 +59,27 @@ impl WorldSim {
}
pub fn get_base_z(&self, chunk_pos: Vec2<u32>) -> Option<f32> {
self
.get(chunk_pos)
.and_then(|_| (0..2)
.map(|i| (0..2)
.map(move |j| (i, j)))
self.get(chunk_pos).and_then(|_| {
(0..2)
.map(|i| (0..2).map(move |j| (i, j)))
.flatten()
.map(|(i, j)| self
.get(chunk_pos + Vec2::new(i, j))
.map(|c| c.get_base_z()))
.map(|(i, j)| {
self.get(chunk_pos + Vec2::new(i, j))
.map(|c| c.get_base_z())
})
.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>
where
T: Copy + Default + Add<Output=T> + Mul<f32, Output=T>,
F: FnMut(&SimChunk) -> T,
where
T: Copy + Default + Add<Output = T> + Mul<f32, Output = 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 x2 = x * x;
@ -101,10 +96,11 @@ impl WorldSim {
let mut y = [T::default(); 4];
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 x1 = f(self.get(pos.map2(Vec2::new( 0, 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))?);
let x0 =
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 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);
}
@ -131,7 +127,9 @@ impl WorldSim {
.mul(2.0);
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;
// Colours
@ -151,11 +149,7 @@ impl WorldSim {
surface_color: Rgb::lerp(
sand,
// Land
Rgb::lerp(
ground,
cliff,
(alt - SEA_LEVEL - 100.0) / 150.0
),
Rgb::lerp(ground, cliff, (alt - SEA_LEVEL - 100.0) / 150.0),
// Beach
(alt - SEA_LEVEL - 2.0) / 5.0,
),
@ -194,13 +188,11 @@ impl SimChunk {
fn generate(pos: Vec2<u32>, gen_ctx: &mut GenCtx) -> Self {
let wposf = (pos * Vec2::from(TerrainChunkSize::SIZE)).map(|e| e as f64);
let hill = (gen_ctx.hill_nz
.get((wposf.div(3500.0)).into_array()) as f32)
.max(0.0);
let hill = (gen_ctx.hill_nz.get((wposf.div(3500.0)).into_array()) as f32).max(0.0);
let chaos = (gen_ctx.chaos_nz
.get((wposf.div(3500.0)).into_array()) as f32)
.add(1.0).mul(0.5)
let chaos = (gen_ctx.chaos_nz.get((wposf.div(3500.0)).into_array()) as f32)
.add(1.0)
.mul(0.5)
.powf(1.9)
.add(0.25 * hill);
@ -212,15 +204,21 @@ impl SimChunk {
Self {
chaos,
alt: SEA_LEVEL + (0.0
+ alt_main
+ gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32 * alt_main.max(0.05) * chaos * 1.3)
.add(1.0).mul(0.5)
.mul(chaos)
.add(alt_base)
.mul(750.0),
alt: SEA_LEVEL
+ (0.0
+ alt_main
+ gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32
* alt_main.max(0.05)
* chaos
* 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)
.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)
.sub(0.1)
.mul(1.2)