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:
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)",
|
"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]]
|
[[package]]
|
||||||
name = "hibitset"
|
name = "hibitset"
|
||||||
version = "0.5.4"
|
version = "0.5.4"
|
||||||
@ -2707,6 +2712,7 @@ dependencies = [
|
|||||||
name = "veloren-world"
|
name = "veloren-world"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
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)",
|
"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)",
|
"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)",
|
"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 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 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 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 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 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"
|
"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" }
|
common = { package = "veloren-common", path = "../common" }
|
||||||
vek = "0.9"
|
vek = "0.9"
|
||||||
noise = "0.5"
|
noise = "0.5"
|
||||||
|
hashbrown = "0.3.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
minifb = { git = "https://github.com/emoon/rust_minifb.git" }
|
minifb = { git = "https://github.com/emoon/rust_minifb.git" }
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
#![feature(euclidean_division)]
|
||||||
|
|
||||||
mod sim;
|
mod sim;
|
||||||
|
mod structure;
|
||||||
|
|
||||||
use common::{
|
use common::{
|
||||||
terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
|
terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
|
||||||
@ -6,6 +9,7 @@ use common::{
|
|||||||
};
|
};
|
||||||
use noise::{BasicMulti, MultiFractal, NoiseFn, Perlin, Seedable};
|
use noise::{BasicMulti, MultiFractal, NoiseFn, Perlin, Seedable};
|
||||||
use std::{
|
use std::{
|
||||||
|
hash::Hash,
|
||||||
ops::{Add, Div, Mul, Neg, Sub},
|
ops::{Add, Div, Mul, Neg, Sub},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
@ -64,7 +68,8 @@ impl World {
|
|||||||
alt,
|
alt,
|
||||||
chaos,
|
chaos,
|
||||||
surface_color,
|
surface_color,
|
||||||
} = if let Some(sample) = self.sim.sample(wpos2d) {
|
close_trees,
|
||||||
|
} = if let Some(sample) = self.sim.sampler().sample(wpos2d) {
|
||||||
sample
|
sample
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
@ -90,6 +95,15 @@ impl World {
|
|||||||
let height = alt + warp;
|
let height = alt + warp;
|
||||||
let temp = 0.0;
|
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 z = wposf.z as f32;
|
||||||
let _ = chunk.set(
|
let _ = chunk.set(
|
||||||
lpos,
|
lpos,
|
||||||
@ -100,7 +114,7 @@ impl World {
|
|||||||
} else if z < sim::SEA_LEVEL {
|
} else if z < sim::SEA_LEVEL {
|
||||||
water
|
water
|
||||||
} else {
|
} else {
|
||||||
air
|
above_ground
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -108,7 +122,23 @@ impl World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chunk
|
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 common::{terrain::TerrainChunkSize, vol::VolSize};
|
||||||
use noise::{
|
use noise::{
|
||||||
BasicMulti, HybridMulti, MultiFractal, NoiseFn, OpenSimplex, RidgedMulti, Seedable,
|
BasicMulti, HybridMulti, MultiFractal, NoiseFn, OpenSimplex, RidgedMulti, Seedable,
|
||||||
@ -15,6 +19,7 @@ pub struct WorldSim {
|
|||||||
pub seed: u32,
|
pub seed: u32,
|
||||||
chunks: Vec<SimChunk>,
|
chunks: Vec<SimChunk>,
|
||||||
gen_ctx: GenCtx,
|
gen_ctx: GenCtx,
|
||||||
|
tree_gen: StructureGen2d,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorldSim {
|
impl WorldSim {
|
||||||
@ -44,6 +49,7 @@ impl WorldSim {
|
|||||||
seed,
|
seed,
|
||||||
chunks,
|
chunks,
|
||||||
gen_ctx,
|
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))
|
Some(cubic(x[0], x[1], x[2], x[3], pos.x.fract() as f32))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sample(&self, pos: Vec2<i32>) -> Option<Sample> {
|
pub fn sampler(&self) -> Sampler {
|
||||||
let wposf = pos.map(|e| e as f64);
|
Sampler {
|
||||||
|
sim: self,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let alt_base = self.get_interpolated(pos, |chunk| chunk.alt_base)?;
|
pub struct Sampler<'a> {
|
||||||
let chaos = self.get_interpolated(pos, |chunk| chunk.chaos)?;
|
sim: &'a WorldSim,
|
||||||
let temp = self.get_interpolated(pos, |chunk| chunk.temp)?;
|
}
|
||||||
let rockiness = self.get_interpolated(pos, |chunk| chunk.rockiness)?;
|
|
||||||
|
|
||||||
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)
|
.mul(rockiness)
|
||||||
.sub(0.2)
|
.sub(0.2)
|
||||||
.max(0.0)
|
.max(0.0)
|
||||||
.mul(2.0);
|
.mul(2.0);
|
||||||
|
|
||||||
let alt = self.get_interpolated(pos, |chunk| chunk.alt)?
|
let alt = self.sim.get_interpolated(wpos, |chunk| chunk.alt)?
|
||||||
+ self.gen_ctx.small_nz.get((wposf.div(128.0)).into_array()) as f32
|
+ self.sim.gen_ctx.small_nz.get((wposf.div(128.0)).into_array()) as f32
|
||||||
* chaos.max(0.15)
|
* chaos.max(0.15)
|
||||||
* 32.0
|
* 32.0
|
||||||
+ rock * 15.0;
|
+ rock * 15.0;
|
||||||
|
|
||||||
let wposf3d = Vec3::new(wposf.x, wposf.y, alt as f64);
|
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)
|
.mul(0.5)
|
||||||
.add(1.0).mul(0.5);
|
.add(1.0).mul(0.5);
|
||||||
|
|
||||||
@ -164,6 +182,7 @@ impl WorldSim {
|
|||||||
// Beach
|
// Beach
|
||||||
(alt - SEA_LEVEL - 2.0) / 5.0,
|
(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 alt: f32,
|
||||||
pub chaos: f32,
|
pub chaos: f32,
|
||||||
pub surface_color: Rgb<f32>,
|
pub surface_color: Rgb<f32>,
|
||||||
|
pub close_trees: [Vec2<i32>; 9],
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GenCtx {
|
struct GenCtx {
|
||||||
@ -250,18 +270,3 @@ impl SimChunk {
|
|||||||
self.alt + Z_TOLERANCE.1
|
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 {
|
use vek::*;
|
||||||
freq: f32,
|
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user