mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added basic structure generation
Former-commit-id: 88a6bf2e18ac4f8f9b560797c8aac82ca318afb0
This commit is contained in:
parent
79ae6f10e7
commit
857315a27d
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -1129,6 +1129,11 @@ dependencies = [
|
||||
"svg_fmt 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "hibitset"
|
||||
version = "0.5.4"
|
||||
@ -2707,6 +2712,7 @@ dependencies = [
|
||||
name = "veloren-world"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"hashbrown 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"minifb 0.11.2 (git+https://github.com/emoon/rust_minifb.git)",
|
||||
"noise 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vek 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -3030,6 +3036,7 @@ dependencies = [
|
||||
"checksum gtk 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d695d6be4110618a97c19cd068e8a00e53e33b87e3c65cdc5397667498b1bc24"
|
||||
"checksum gtk-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d9554cf5b3a85a13fb39258c65b04b262989c1d7a758f8f555b77a478621a91"
|
||||
"checksum guillotiere 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "182af928b4435d8fbef910535586ecdca95ab4068493769c090e6573477f5e35"
|
||||
"checksum hashbrown 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "570178d5e4952010d138b0f1d581271ff3a02406d990f887d1e87e3d6e43b0ac"
|
||||
"checksum hibitset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6527bc88f32e0d3926c7572874b2bf17a19b36978aacd0aacf75f7d27a5992d0"
|
||||
"checksum hound 3.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549"
|
||||
"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
|
||||
|
@ -8,6 +8,7 @@ edition = "2018"
|
||||
common = { package = "veloren-common", path = "../common" }
|
||||
vek = "0.9"
|
||||
noise = "0.5"
|
||||
hashbrown = "0.3.0"
|
||||
|
||||
[dev-dependencies]
|
||||
minifb = { git = "https://github.com/emoon/rust_minifb.git" }
|
||||
|
@ -1,4 +1,7 @@
|
||||
#![feature(euclidean_division)]
|
||||
|
||||
mod sim;
|
||||
mod structure;
|
||||
|
||||
use common::{
|
||||
terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
|
||||
@ -6,6 +9,7 @@ use common::{
|
||||
};
|
||||
use noise::{BasicMulti, MultiFractal, NoiseFn, Perlin, Seedable};
|
||||
use std::{
|
||||
hash::Hash,
|
||||
ops::{Add, Div, Mul, Neg, Sub},
|
||||
time::Duration,
|
||||
};
|
||||
@ -64,7 +68,8 @@ impl World {
|
||||
alt,
|
||||
chaos,
|
||||
surface_color,
|
||||
} = if let Some(sample) = self.sim.sample(wpos2d) {
|
||||
close_trees,
|
||||
} = if let Some(sample) = self.sim.sampler().sample(wpos2d) {
|
||||
sample
|
||||
} else {
|
||||
continue;
|
||||
@ -90,6 +95,15 @@ impl World {
|
||||
let height = alt + warp;
|
||||
let temp = 0.0;
|
||||
|
||||
let above_ground = if (&close_trees)
|
||||
.iter()
|
||||
.any(|tree| tree.distance_squared(wpos.into()) < 36)
|
||||
{
|
||||
grass
|
||||
} else {
|
||||
air
|
||||
};
|
||||
|
||||
let z = wposf.z as f32;
|
||||
let _ = chunk.set(
|
||||
lpos,
|
||||
@ -100,7 +114,7 @@ impl World {
|
||||
} else if z < sim::SEA_LEVEL {
|
||||
water
|
||||
} else {
|
||||
air
|
||||
above_ground
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -108,7 +122,23 @@ impl World {
|
||||
}
|
||||
|
||||
chunk
|
||||
|
||||
// */
|
||||
}
|
||||
}
|
||||
|
||||
struct Cache<K: Hash + Eq + Copy, V> {
|
||||
map: hashbrown::HashMap<K, V>,
|
||||
}
|
||||
|
||||
impl<K: Hash + Eq + Copy, V> Cache<K, V> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
map: hashbrown::HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<F: FnOnce(K) -> V>(&mut self, k: K, f: F) -> &V {
|
||||
self.map
|
||||
.entry(k)
|
||||
.or_insert_with(|| f(k))
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
use crate::{
|
||||
structure::StructureGen2d,
|
||||
Cache,
|
||||
};
|
||||
use common::{terrain::TerrainChunkSize, vol::VolSize};
|
||||
use noise::{
|
||||
BasicMulti, HybridMulti, MultiFractal, NoiseFn, OpenSimplex, RidgedMulti, Seedable,
|
||||
@ -15,6 +19,7 @@ pub struct WorldSim {
|
||||
pub seed: u32,
|
||||
chunks: Vec<SimChunk>,
|
||||
gen_ctx: GenCtx,
|
||||
tree_gen: StructureGen2d,
|
||||
}
|
||||
|
||||
impl WorldSim {
|
||||
@ -44,6 +49,7 @@ impl WorldSim {
|
||||
seed,
|
||||
chunks,
|
||||
gen_ctx,
|
||||
tree_gen: StructureGen2d::new(seed, 64, 32),
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,29 +113,41 @@ impl WorldSim {
|
||||
Some(cubic(x[0], x[1], x[2], x[3], pos.x.fract() as f32))
|
||||
}
|
||||
|
||||
pub fn sample(&self, pos: Vec2<i32>) -> Option<Sample> {
|
||||
let wposf = pos.map(|e| e as f64);
|
||||
pub fn sampler(&self) -> Sampler {
|
||||
Sampler {
|
||||
sim: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let alt_base = self.get_interpolated(pos, |chunk| chunk.alt_base)?;
|
||||
let chaos = self.get_interpolated(pos, |chunk| chunk.chaos)?;
|
||||
let temp = self.get_interpolated(pos, |chunk| chunk.temp)?;
|
||||
let rockiness = self.get_interpolated(pos, |chunk| chunk.rockiness)?;
|
||||
pub struct Sampler<'a> {
|
||||
sim: &'a WorldSim,
|
||||
}
|
||||
|
||||
let rock = (self.gen_ctx.small_nz.get((wposf.div(100.0)).into_array()) as f32)
|
||||
impl<'a> Sampler<'a> {
|
||||
pub fn sample(&self, wpos: Vec2<i32>) -> Option<Sample> {
|
||||
let wposf = wpos.map(|e| e as f64);
|
||||
|
||||
let alt_base = self.sim.get_interpolated(wpos, |chunk| chunk.alt_base)?;
|
||||
let chaos = self.sim.get_interpolated(wpos, |chunk| chunk.chaos)?;
|
||||
let temp = self.sim.get_interpolated(wpos, |chunk| chunk.temp)?;
|
||||
let rockiness = self.sim.get_interpolated(wpos, |chunk| chunk.rockiness)?;
|
||||
|
||||
let rock = (self.sim.gen_ctx.small_nz.get((wposf.div(100.0)).into_array()) as f32)
|
||||
.mul(rockiness)
|
||||
.sub(0.2)
|
||||
.max(0.0)
|
||||
.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
|
||||
let alt = self.sim.get_interpolated(wpos, |chunk| chunk.alt)?
|
||||
+ self.sim.gen_ctx.small_nz.get((wposf.div(128.0)).into_array()) as f32
|
||||
* chaos.max(0.15)
|
||||
* 32.0
|
||||
+ rock * 15.0;
|
||||
|
||||
let wposf3d = Vec3::new(wposf.x, wposf.y, alt as f64);
|
||||
|
||||
let marble = (self.gen_ctx.hill_nz.get((wposf3d.div(64.0)).into_array()) as f32)
|
||||
let marble = (self.sim.gen_ctx.hill_nz.get((wposf3d.div(64.0)).into_array()) as f32)
|
||||
.mul(0.5)
|
||||
.add(1.0).mul(0.5);
|
||||
|
||||
@ -164,6 +182,7 @@ impl WorldSim {
|
||||
// Beach
|
||||
(alt - SEA_LEVEL - 2.0) / 5.0,
|
||||
),
|
||||
close_trees: self.sim.tree_gen.sample(wpos),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -172,6 +191,7 @@ pub struct Sample {
|
||||
pub alt: f32,
|
||||
pub chaos: f32,
|
||||
pub surface_color: Rgb<f32>,
|
||||
pub close_trees: [Vec2<i32>; 9],
|
||||
}
|
||||
|
||||
struct GenCtx {
|
||||
@ -250,18 +270,3 @@ impl SimChunk {
|
||||
self.alt + Z_TOLERANCE.1
|
||||
}
|
||||
}
|
||||
|
||||
trait Hsv {
|
||||
fn into_hsv(self) -> Self;
|
||||
fn into_rgb(self) -> Self;
|
||||
}
|
||||
|
||||
impl Hsv for Rgb<f32> {
|
||||
fn into_hsv(mut self) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn into_rgb(mut self) -> Self {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,50 @@
|
||||
pub struct StructureGen {
|
||||
freq: f32,
|
||||
use vek::*;
|
||||
|
||||
pub struct StructureGen2d {
|
||||
seed: u32,
|
||||
freq: u32,
|
||||
spread: u32,
|
||||
}
|
||||
|
||||
impl StructureGen2d {
|
||||
pub fn new(seed: u32, freq: u32, spread: u32) -> Self {
|
||||
Self {
|
||||
seed,
|
||||
freq,
|
||||
spread,
|
||||
}
|
||||
}
|
||||
|
||||
fn random(&self, seed: u32, pos: Vec2<i32>) -> 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 = 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(938219).wrapping_add(pos.y);
|
||||
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 & 0xFFFF
|
||||
}
|
||||
|
||||
pub fn sample(&self, sample_pos: Vec2<i32>) -> [Vec2<i32>; 9] {
|
||||
let mut samples = [Vec2::zero(); 9];
|
||||
|
||||
let sample_closest = sample_pos.map(|e| e - e.rem_euclid(self.freq as i32));
|
||||
|
||||
for i in 0..3 {
|
||||
for j in 0..3 {
|
||||
let center = sample_closest
|
||||
+ Vec2::new(i, j).map(|e| e as i32 - 1) * self.freq as i32
|
||||
+ self.freq as i32 / 2;
|
||||
samples[i * 3 + j] = center + Vec2::new(
|
||||
(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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
samples
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user