Former-commit-id: 689464ed1009ebfd74769fa113fc7b433ea62bbd
This commit is contained in:
Joshua Barretto
2019-05-25 06:54:47 +01:00
parent 6ded009f5a
commit 6ac6b7fd86
8 changed files with 137 additions and 86 deletions

View File

@ -36,7 +36,10 @@ lazy_static! {
RwLock::new(HashMap::new()); RwLock::new(HashMap::new());
} }
pub fn load_map<A: Asset + 'static, F: FnOnce(A) -> A>(specifier: &str, f: F) -> Result<Arc<A>, Error> { pub fn load_map<A: Asset + 'static, F: FnOnce(A) -> A>(
specifier: &str,
f: F,
) -> Result<Arc<A>, Error> {
Ok(ASSETS Ok(ASSETS
.write() .write()
.unwrap() .unwrap()

View File

@ -4,8 +4,8 @@ use crate::{
volumes::chunk::{Chunk, ChunkErr}, volumes::chunk::{Chunk, ChunkErr},
}; };
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use vek::*;
use std::collections::HashMap; use std::collections::HashMap;
use vek::*;
#[derive(Debug)] #[derive(Debug)]
pub enum ChonkError { pub enum ChonkError {
@ -76,7 +76,7 @@ impl ReadVol for Chonk {
* (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);
Ok(map.get(&rpos).unwrap_or(cblock)) Ok(map.get(&rpos).unwrap_or(cblock))
}, }
SubChunk::Heterogeneous(chunk) => { SubChunk::Heterogeneous(chunk) => {
let rpos = pos let rpos = pos
- Vec3::unit_z() - Vec3::unit_z()
@ -113,11 +113,11 @@ impl WriteVol for Chonk {
self.sub_chunks[sub_chunk_idx] = SubChunk::Hash(*cblock, map); self.sub_chunks[sub_chunk_idx] = SubChunk::Hash(*cblock, map);
Ok(()) Ok(())
}, }
SubChunk::Hash(cblock, map) if map.len() < 1024 => { SubChunk::Hash(cblock, map) if map.len() < 1024 => {
map.insert(rpos, block); map.insert(rpos, block);
Ok(()) Ok(())
}, }
SubChunk::Hash(cblock, map) => { SubChunk::Hash(cblock, map) => {
let mut new_chunk = Chunk::filled(*cblock, ()); let mut new_chunk = Chunk::filled(*cblock, ());
new_chunk.set(rpos, block).unwrap(); // Can't fail (I hope) new_chunk.set(rpos, block).unwrap(); // Can't fail (I hope)

View File

@ -4,11 +4,7 @@ pub mod chonk;
pub mod structure; pub mod structure;
// Reexports // Reexports
pub use self::{ pub use self::{biome::BiomeKind, block::Block, structure::Structure};
biome::BiomeKind,
block::Block,
structure::Structure,
};
use crate::{ use crate::{
vol::VolSize, vol::VolSize,

View File

@ -1,11 +1,11 @@
use super::Block;
use crate::{
assets::{self, load_from_path, Asset},
vol::{BaseVol, ReadVol, Vox, WriteVol},
volumes::dyna::{Dyna, DynaErr},
};
use dot_vox::DotVoxData; use dot_vox::DotVoxData;
use vek::*; use vek::*;
use crate::{
assets::{self, Asset, load_from_path},
volumes::dyna::{Dyna, DynaErr},
vol::{Vox, BaseVol, ReadVol, WriteVol},
};
use super::Block;
#[derive(Debug)] #[derive(Debug)]
pub enum StructureError {} pub enum StructureError {}
@ -50,11 +50,11 @@ impl Asset for Structure {
.map(|col| Rgba::from(col.to_ne_bytes()).into()) .map(|col| Rgba::from(col.to_ne_bytes()).into())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let mut vol = Dyna::filled(Vec3::new( let mut vol = Dyna::filled(
model.size.x, Vec3::new(model.size.x, model.size.y, model.size.z),
model.size.y, Block::empty(),
model.size.z, (),
), Block::empty(), ()); );
for voxel in &model.voxels { for voxel in &model.voxels {
if let Some(&color) = palette.get(voxel.i as usize) { if let Some(&color) = palette.get(voxel.i as usize) {

View File

@ -1,6 +1,6 @@
// Library // Library
use vek::*;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use vek::*;
// Local // Local
use crate::vol::{BaseVol, ReadVol, SizedVol, Vox, WriteVol}; use crate::vol::{BaseVol, ReadVol, SizedVol, Vox, WriteVol};

View File

@ -7,6 +7,7 @@ use common::{
terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize}, terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
vol::{SizedVol, VolSize, Vox, WriteVol}, vol::{SizedVol, VolSize, Vox, WriteVol},
}; };
use fxhash::FxHashMap;
use noise::{BasicMulti, MultiFractal, NoiseFn, Perlin, Seedable}; use noise::{BasicMulti, MultiFractal, NoiseFn, Perlin, Seedable};
use std::{ use std::{
hash::Hash, hash::Hash,
@ -14,7 +15,6 @@ use std::{
time::Duration, time::Duration,
}; };
use vek::*; use vek::*;
use fxhash::FxHashMap;
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
@ -74,11 +74,12 @@ impl World {
let wpos = let wpos =
lpos + Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32); lpos + Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32);
let sim::Sample3d { block } = if let Some(sample) = world_sampler.sample_3d(wpos) { let sim::Sample3d { block } =
sample if let Some(sample) = world_sampler.sample_3d(wpos) {
} else { sample
continue } else {
}; continue;
};
let _ = chunk.set(lpos, block); let _ = chunk.set(lpos, block);
} }
@ -111,11 +112,13 @@ impl<K: Hash + Eq + Copy, V> Cache<K, V> {
pub fn get<F: FnOnce(K) -> V>(&mut self, k: K, f: F) -> &V { pub fn get<F: FnOnce(K) -> V>(&mut self, k: K, f: F) -> &V {
let mut counter = &mut self.counter; let mut counter = &mut self.counter;
&self.map &self
.map
.entry(k) .entry(k)
.or_insert_with(|| { .or_insert_with(|| {
*counter += 1; *counter += 1;
(*counter, f(k)) (*counter, f(k))
}).1 })
.1
} }
} }

View File

@ -1,17 +1,14 @@
use crate::{ use crate::{structure::StructureGen2d, Cache};
structure::StructureGen2d,
Cache,
};
use common::{ use common::{
assets, assets,
terrain::{Block, TerrainChunkSize, Structure}, terrain::{Block, Structure, TerrainChunkSize},
vol::{Vox, VolSize, ReadVol}, vol::{ReadVol, VolSize, Vox},
}; };
use lazy_static::lazy_static;
use noise::{ use noise::{
BasicMulti, HybridMulti, MultiFractal, NoiseFn, OpenSimplex, RidgedMulti, Seedable, BasicMulti, HybridMulti, MultiFractal, NoiseFn, OpenSimplex, RidgedMulti, Seedable,
SuperSimplex, SuperSimplex,
}; };
use lazy_static::lazy_static;
use std::{ use std::{
f32, f32,
ops::{Add, Div, Mul, Neg, Sub}, ops::{Add, Div, Mul, Neg, Sub},
@ -110,10 +107,11 @@ impl WorldSim {
let mut x = [T::default(); 4]; let mut x = [T::default(); 4];
for (x_idx, j) in (-1..3).enumerate() { 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 y0 =
let y1 = f(self.get(pos.map2(Vec2::new(j, 0), |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) 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 y1 = f(self.get(pos.map2(Vec2::new(j, 0), |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))?); 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))?);
x[x_idx] = cubic(y0, y1, y2, y3, pos.y.fract() as f32); x[x_idx] = cubic(y0, y1, y2, y3, pos.y.fract() as f32);
} }
@ -160,7 +158,8 @@ impl<'a> Sampler<'a> {
let marble = (sim.gen_ctx.hill_nz.get((wposf3d.div(64.0)).into_array()) as f32) let marble = (sim.gen_ctx.hill_nz.get((wposf3d.div(64.0)).into_array()) as f32)
.mul(0.5) .mul(0.5)
.add(1.0).mul(0.5); .add(1.0)
.mul(0.5);
// Colours // Colours
let cold_grass = Rgb::new(0.05, 0.5, 0.3); let cold_grass = Rgb::new(0.05, 0.5, 0.3);
@ -188,7 +187,7 @@ impl<'a> Sampler<'a> {
snow, snow,
(alt - SEA_LEVEL - 350.0 - alt_base - temp * 48.0) / 12.0, (alt - SEA_LEVEL - 350.0 - alt_base - temp * 48.0) / 12.0,
), ),
(alt - SEA_LEVEL - 150.0) / 180.0 (alt - SEA_LEVEL - 150.0) / 180.0,
), ),
// Beach // Beach
(alt - SEA_LEVEL - 2.0) / 5.0, (alt - SEA_LEVEL - 2.0) / 5.0,
@ -200,7 +199,9 @@ impl<'a> Sampler<'a> {
pub fn sample_2d(&mut self, wpos2d: Vec2<i32>) -> Option<&Sample2d> { pub fn sample_2d(&mut self, wpos2d: Vec2<i32>) -> Option<&Sample2d> {
let sim = &self.sim; let sim = &self.sim;
self.sample2d_cache.get(wpos2d, |wpos2d| Self::sample_2d_impl(sim, wpos2d)).as_ref() self.sample2d_cache
.get(wpos2d, |wpos2d| Self::sample_2d_impl(sim, wpos2d))
.as_ref()
} }
pub fn sample_3d(&mut self, wpos: Vec3<i32>) -> Option<Sample3d> { pub fn sample_3d(&mut self, wpos: Vec3<i32>) -> Option<Sample3d> {
@ -219,7 +220,10 @@ impl<'a> Sampler<'a> {
// Apply warping // Apply warping
let warp = (self.sim.gen_ctx.warp_nz let warp = (self
.sim
.gen_ctx
.warp_nz
.get((wposf.div(Vec3::new(120.0, 120.0, 150.0))).into_array()) .get((wposf.div(Vec3::new(120.0, 120.0, 150.0))).into_array())
as f32) as f32)
.mul((chaos - 0.1).max(0.0)) .mul((chaos - 0.1).max(0.0))
@ -237,19 +241,22 @@ impl<'a> Sampler<'a> {
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 above_ground = (&close_trees) let above_ground =
.iter() (&close_trees)
.fold(air, |block, (tree_pos, tree_seed)| { .iter()
match self.sample_2d(*tree_pos) { .fold(air, |block, (tree_pos, tree_seed)| {
Some(tree_sample) if tree_sample.tree_density > 0.5 => { match self.sample_2d(*tree_pos) {
let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, tree_sample.alt as i32); Some(tree_sample) if tree_sample.tree_density > 0.5 => {
block.or(TREES[*tree_seed as usize % TREES.len()].get(wpos - tree_pos3d) let tree_pos3d =
.map(|b| b.clone()) Vec3::new(tree_pos.x, tree_pos.y, tree_sample.alt as i32);
.unwrap_or(Block::empty())) block.or(TREES[*tree_seed as usize % TREES.len()]
}, .get(wpos - tree_pos3d)
_ => block, .map(|b| b.clone())
} .unwrap_or(Block::empty()))
}); }
_ => block,
}
});
let z = wposf.z as f32; let z = wposf.z as f32;
Some(Sample3d { Some(Sample3d {
@ -268,18 +275,42 @@ impl<'a> Sampler<'a> {
lazy_static! { lazy_static! {
static ref TREES: [Arc<Structure>; 12] = [ static ref TREES: [Arc<Structure>; 12] = [
assets::load_map("world/tree/oak/1.vox", |s: Structure| s.with_center(Vec3::new(15, 18, 14))).unwrap(), assets::load_map("world/tree/oak/1.vox", |s: Structure| s
assets::load_map("world/tree/oak/2.vox", |s: Structure| s.with_center(Vec3::new(15, 18, 14))).unwrap(), .with_center(Vec3::new(15, 18, 14)))
assets::load_map("world/tree/oak/3.vox", |s: Structure| s.with_center(Vec3::new(15, 18, 14))).unwrap(), .unwrap(),
assets::load_map("world/tree/pine/3.vox", |s: Structure| s.with_center(Vec3::new(15, 15, 14))).unwrap(), assets::load_map("world/tree/oak/2.vox", |s: Structure| s
assets::load_map("world/tree/pine/4.vox", |s: Structure| s.with_center(Vec3::new(15, 15, 14))).unwrap(), .with_center(Vec3::new(15, 18, 14)))
assets::load_map("world/tree/pine/5.vox", |s: Structure| s.with_center(Vec3::new(15, 15, 12))).unwrap(), .unwrap(),
assets::load_map("world/tree/temperate/1.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), assets::load_map("world/tree/oak/3.vox", |s: Structure| s
assets::load_map("world/tree/temperate/2.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), .with_center(Vec3::new(15, 18, 14)))
assets::load_map("world/tree/temperate/3.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), .unwrap(),
assets::load_map("world/tree/temperate/4.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), assets::load_map("world/tree/pine/3.vox", |s: Structure| s
assets::load_map("world/tree/temperate/5.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), .with_center(Vec3::new(15, 15, 14)))
assets::load_map("world/tree/temperate/6.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), .unwrap(),
assets::load_map("world/tree/pine/4.vox", |s: Structure| s
.with_center(Vec3::new(15, 15, 14)))
.unwrap(),
assets::load_map("world/tree/pine/5.vox", |s: Structure| s
.with_center(Vec3::new(15, 15, 12)))
.unwrap(),
assets::load_map("world/tree/temperate/1.vox", |s: Structure| s
.with_center(Vec3::new(4, 4, 7)))
.unwrap(),
assets::load_map("world/tree/temperate/2.vox", |s: Structure| s
.with_center(Vec3::new(4, 4, 7)))
.unwrap(),
assets::load_map("world/tree/temperate/3.vox", |s: Structure| s
.with_center(Vec3::new(4, 4, 7)))
.unwrap(),
assets::load_map("world/tree/temperate/4.vox", |s: Structure| s
.with_center(Vec3::new(4, 4, 7)))
.unwrap(),
assets::load_map("world/tree/temperate/5.vox", |s: Structure| s
.with_center(Vec3::new(4, 4, 7)))
.unwrap(),
assets::load_map("world/tree/temperate/6.vox", |s: Structure| s
.with_center(Vec3::new(4, 4, 7)))
.unwrap(),
]; ];
} }
@ -327,9 +358,16 @@ impl SimChunk {
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 = (0.0 let hill = (0.0
+ gen_ctx.hill_nz.get((wposf.div(3_500.0)).into_array()).mul(1.0) as f32 + gen_ctx
+ gen_ctx.hill_nz.get((wposf.div(1_000.0)).into_array()).mul(0.3) as f32 .hill_nz
).add(0.3).max(0.0); .get((wposf.div(3_500.0)).into_array())
.mul(1.0) as f32
+ gen_ctx
.hill_nz
.get((wposf.div(1_000.0)).into_array())
.mul(0.3) as f32)
.add(0.3)
.max(0.0);
let chaos = (gen_ctx.chaos_nz.get((wposf.div(4_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) .add(1.0)
@ -350,7 +388,8 @@ impl SimChunk {
Self { Self {
chaos, chaos,
alt_base, alt_base,
alt: SEA_LEVEL + alt_base alt: SEA_LEVEL
+ alt_base
+ (0.0 + (0.0
+ alt_main + alt_main
+ gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32 + gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32

View File

@ -8,20 +8,24 @@ pub struct StructureGen2d {
impl StructureGen2d { impl StructureGen2d {
pub fn new(seed: u32, freq: u32, spread: u32) -> Self { pub fn new(seed: u32, freq: u32, spread: u32) -> Self {
Self { Self { seed, freq, spread }
seed,
freq,
spread,
}
} }
fn random(&self, seed: u32, pos: Vec2<i32>) -> u32 { fn random(&self, seed: u32, pos: Vec2<i32>) -> u32 {
let pos = pos.map(|e| (e * 13 + (1 << 31)) as u32); let pos = pos.map(|e| (e * 13 + (1 << 31)) as u32);
let next = (self.seed + seed).wrapping_mul(0x168E3D1F).wrapping_add(0xDEADBEAD); let next = (self.seed + seed)
let next = next.rotate_left(13).wrapping_mul(133227).wrapping_add(pos.x); .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_mul(318912) ^ 0x42133742;
let next = next.rotate_left(13).wrapping_mul(938219).wrapping_add(pos.y); let next = next
.rotate_left(13)
.wrapping_mul(938219)
.wrapping_add(pos.y);
let next = next.rotate_left(13).wrapping_mul(313322) ^ 0xDEADBEEF; 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(929009) ^ 0xFF329DE3;
let next = next.rotate_left(13).wrapping_mul(422671) ^ 0x42892942; let next = next.rotate_left(13).wrapping_mul(422671) ^ 0x42892942;
@ -38,10 +42,16 @@ impl StructureGen2d {
let center = sample_closest let center = sample_closest
+ Vec2::new(i, j).map(|e| e as i32 - 1) * self.freq as i32 + Vec2::new(i, j).map(|e| e as i32 - 1) * self.freq as i32
+ self.freq as i32 / 2; + self.freq as i32 / 2;
samples[i * 3 + j] = (center + Vec2::new( samples[i * 3 + j] = (
(self.random(1, center) % (self.spread * 2)) as i32 - self.spread as i32, center
(self.random(2, center) % (self.spread * 2)) as i32 - self.spread as i32, + Vec2::new(
), self.random(3, center)); (self.random(1, center) % (self.spread * 2)) as i32
- self.spread as i32,
(self.random(2, center) % (self.spread * 2)) as i32
- self.spread as i32,
),
self.random(3, center),
);
} }
} }