2019-06-09 10:24:18 +00:00
|
|
|
#![feature(euclidean_division, bind_by_move_pattern_guards)]
|
2019-05-23 20:41:01 +00:00
|
|
|
|
2019-06-11 18:39:25 +00:00
|
|
|
mod all;
|
2019-06-09 10:24:18 +00:00
|
|
|
mod block;
|
|
|
|
mod column;
|
2019-06-15 12:34:28 +00:00
|
|
|
pub mod config;
|
2019-06-18 21:22:31 +00:00
|
|
|
pub mod sim;
|
2019-06-15 12:34:28 +00:00
|
|
|
pub mod util;
|
2019-06-09 10:24:18 +00:00
|
|
|
|
|
|
|
// Reexports
|
|
|
|
pub use crate::config::CONFIG;
|
2019-05-18 08:59:58 +00:00
|
|
|
|
2019-06-15 10:36:26 +00:00
|
|
|
use crate::{
|
|
|
|
block::BlockGen,
|
2019-06-15 12:34:28 +00:00
|
|
|
column::{ColumnGen, ColumnSample},
|
2019-06-15 10:36:26 +00:00
|
|
|
util::{HashCache, Sampler, SamplerMut},
|
|
|
|
};
|
2019-01-15 15:13:11 +00:00
|
|
|
use common::{
|
2019-05-17 17:54:56 +00:00
|
|
|
terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
|
2019-06-06 14:48:41 +00:00
|
|
|
vol::{VolSize, Vox, WriteVol},
|
2019-01-15 15:13:11 +00:00
|
|
|
};
|
2019-06-09 10:24:18 +00:00
|
|
|
use std::time::Duration;
|
2019-05-21 22:31:38 +00:00
|
|
|
use vek::*;
|
2019-01-15 15:13:11 +00:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Error {
|
|
|
|
Other(String),
|
|
|
|
}
|
|
|
|
|
2019-05-18 08:59:58 +00:00
|
|
|
pub struct World {
|
|
|
|
sim: sim::WorldSim,
|
|
|
|
}
|
2019-01-15 15:13:11 +00:00
|
|
|
|
|
|
|
impl World {
|
2019-05-18 08:59:58 +00:00
|
|
|
pub fn generate(seed: u32) -> Self {
|
2019-05-21 22:31:38 +00:00
|
|
|
Self {
|
|
|
|
sim: sim::WorldSim::generate(seed),
|
|
|
|
}
|
2019-05-18 08:59:58 +00:00
|
|
|
}
|
|
|
|
|
2019-05-21 00:57:16 +00:00
|
|
|
pub fn sim(&self) -> &sim::WorldSim {
|
|
|
|
&self.sim
|
|
|
|
}
|
|
|
|
|
2019-05-16 17:40:32 +00:00
|
|
|
pub fn tick(&self, dt: Duration) {
|
2019-05-18 08:59:58 +00:00
|
|
|
// TODO
|
2019-01-15 15:13:11 +00:00
|
|
|
}
|
|
|
|
|
2019-06-15 12:34:28 +00:00
|
|
|
pub fn sample_columns(
|
|
|
|
&self,
|
|
|
|
) -> impl Sampler<Index = Vec2<i32>, Sample = Option<ColumnSample>> + '_ {
|
|
|
|
ColumnGen::new(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn sample_blocks(&self) -> impl SamplerMut<Index = Vec3<i32>, Sample = Option<Block>> + '_ {
|
2019-06-09 10:24:18 +00:00
|
|
|
BlockGen::new(self, ColumnGen::new(self))
|
|
|
|
}
|
2019-01-23 22:21:47 +00:00
|
|
|
|
2019-06-09 10:24:18 +00:00
|
|
|
pub fn generate_chunk(&self, chunk_pos: Vec2<i32>) -> TerrainChunk {
|
2019-01-23 20:01:58 +00:00
|
|
|
let air = Block::empty();
|
2019-04-29 20:37:19 +00:00
|
|
|
let stone = Block::new(1, Rgb::new(200, 220, 255));
|
2019-05-21 00:57:16 +00:00
|
|
|
let water = Block::new(5, Rgb::new(100, 150, 255));
|
2019-01-23 20:01:58 +00:00
|
|
|
|
2019-06-04 17:19:40 +00:00
|
|
|
let chunk_size2d = Vec2::from(TerrainChunkSize::SIZE);
|
2019-06-19 14:55:26 +00:00
|
|
|
let (base_z, sim_chunk) = match self
|
|
|
|
.sim
|
|
|
|
.get_interpolated(
|
|
|
|
chunk_pos.map2(chunk_size2d, |e, sz: u32| e * sz as i32 + sz as i32 / 2),
|
|
|
|
|chunk| chunk.get_base_z(),
|
|
|
|
)
|
|
|
|
.and_then(|base_z| self.sim.get(chunk_pos).map(|sim_chunk| (base_z, sim_chunk)))
|
|
|
|
{
|
2019-06-18 21:22:31 +00:00
|
|
|
Some((base_z, sim_chunk)) => (base_z as i32, sim_chunk),
|
2019-05-24 11:08:38 +00:00
|
|
|
None => return TerrainChunk::new(0, water, air, TerrainChunkMeta::void()),
|
2019-05-19 14:54:37 +00:00
|
|
|
};
|
2019-05-17 21:19:32 +00:00
|
|
|
|
2019-06-19 14:55:26 +00:00
|
|
|
let meta = TerrainChunkMeta::new(sim_chunk.get_name(), sim_chunk.get_biome());
|
2019-06-18 21:22:31 +00:00
|
|
|
|
|
|
|
let mut chunk = TerrainChunk::new(base_z - 8, stone, air, meta);
|
2019-05-17 21:19:32 +00:00
|
|
|
|
2019-06-15 12:34:28 +00:00
|
|
|
let mut sampler = self.sample_blocks();
|
2019-05-24 11:08:38 +00:00
|
|
|
|
2019-05-17 17:44:30 +00:00
|
|
|
for x in 0..TerrainChunkSize::SIZE.x as i32 {
|
|
|
|
for y in 0..TerrainChunkSize::SIZE.y as i32 {
|
2019-05-21 22:31:38 +00:00
|
|
|
let wpos2d = Vec2::new(x, y)
|
|
|
|
+ Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32);
|
2019-05-20 02:53:04 +00:00
|
|
|
let wposf2d = wpos2d.map(|e| e as f64);
|
|
|
|
|
2019-06-04 12:45:41 +00:00
|
|
|
let min_z = self
|
|
|
|
.sim
|
|
|
|
.get_interpolated(wpos2d, |chunk| chunk.get_min_z())
|
|
|
|
.unwrap_or(0.0) as i32;
|
|
|
|
|
2019-05-21 22:31:38 +00:00
|
|
|
let max_z = self
|
|
|
|
.sim
|
2019-05-20 15:01:27 +00:00
|
|
|
.get_interpolated(wpos2d, |chunk| chunk.get_max_z())
|
|
|
|
.unwrap_or(0.0) as i32;
|
|
|
|
|
2019-06-04 12:45:41 +00:00
|
|
|
for z in min_z..max_z {
|
2019-05-17 17:44:30 +00:00
|
|
|
let lpos = Vec3::new(x, y, z);
|
2019-05-21 22:31:38 +00:00
|
|
|
let wpos =
|
|
|
|
lpos + Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32);
|
2019-05-24 11:08:38 +00:00
|
|
|
|
2019-06-09 10:24:18 +00:00
|
|
|
if let Some(block) = sampler.get(wpos) {
|
|
|
|
let _ = chunk.set(lpos, block);
|
|
|
|
}
|
2019-05-17 17:44:30 +00:00
|
|
|
}
|
|
|
|
}
|
2019-01-23 20:01:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
chunk
|
2019-05-23 20:41:01 +00:00
|
|
|
}
|
|
|
|
}
|