2019-05-16 17:40:32 +00:00
|
|
|
use std::ops::{Mul, Div};
|
2019-05-18 08:59:58 +00:00
|
|
|
use noise::{NoiseFn, OpenSimplex, Seedable};
|
2019-05-16 17:40:32 +00:00
|
|
|
use vek::*;
|
|
|
|
use common::{
|
|
|
|
terrain::TerrainChunkSize,
|
|
|
|
vol::VolSize,
|
|
|
|
};
|
2019-05-18 08:59:58 +00:00
|
|
|
use crate::WORLD_SIZE;
|
|
|
|
|
|
|
|
pub struct WorldSim {
|
|
|
|
seed: u32,
|
|
|
|
chunks: Vec<SimChunk>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl WorldSim {
|
|
|
|
pub fn generate(seed: u32) -> Self {
|
|
|
|
let mut gen_ctx = GenCtx {
|
|
|
|
alt_nz: OpenSimplex::new()
|
|
|
|
.set_seed(seed),
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut chunks = Vec::new();
|
2019-05-16 17:40:32 +00:00
|
|
|
for x in 0..WORLD_SIZE.x as u32 {
|
|
|
|
for y in 0..WORLD_SIZE.y as u32 {
|
|
|
|
chunks.push(SimChunk::generate(Vec2::new(x, y), &mut gen_ctx));
|
2019-05-18 08:59:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Self {
|
|
|
|
seed,
|
|
|
|
chunks,
|
|
|
|
}
|
|
|
|
}
|
2019-05-16 17:40:32 +00:00
|
|
|
|
|
|
|
pub fn get(&self, chunk_pos: Vec2<u32>) -> Option<&SimChunk> {
|
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
2019-05-18 08:59:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct GenCtx {
|
|
|
|
alt_nz: OpenSimplex,
|
|
|
|
}
|
|
|
|
|
2019-05-16 17:40:32 +00:00
|
|
|
pub struct SimChunk {
|
|
|
|
pub alt: f32,
|
2019-05-18 08:59:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl SimChunk {
|
2019-05-16 17:40:32 +00:00
|
|
|
fn generate(pos: Vec2<u32>, gen_ctx: &mut GenCtx) -> Self {
|
|
|
|
let wposf = (pos * Vec2::from(TerrainChunkSize::SIZE)).map(|e| e as f64);
|
|
|
|
|
2019-05-18 08:59:58 +00:00
|
|
|
Self {
|
2019-05-16 17:40:32 +00:00
|
|
|
alt: gen_ctx.alt_nz
|
|
|
|
.get((wposf.div(2048.0)).into_array())
|
|
|
|
.mul(512.0) as f32,
|
2019-05-18 08:59:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|