2019-05-18 08:59:58 +00:00
|
|
|
mod sim;
|
|
|
|
|
2019-05-20 02:53:04 +00:00
|
|
|
use std::{
|
2019-05-21 12:28:53 +00:00
|
|
|
ops::{Add, Sub, Mul, Div, Neg},
|
2019-05-20 02:53:04 +00:00
|
|
|
time::Duration,
|
|
|
|
};
|
2019-05-21 12:28:53 +00:00
|
|
|
use noise::{NoiseFn, BasicMulti, Perlin, Seedable, MultiFractal};
|
2019-04-29 20:37:19 +00:00
|
|
|
use vek::*;
|
2019-01-15 15:13:11 +00:00
|
|
|
use common::{
|
2019-05-17 17:54:56 +00:00
|
|
|
terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
|
|
|
|
vol::{SizedVol, VolSize, Vox, WriteVol},
|
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 {
|
|
|
|
Self { sim: sim::WorldSim::generate(seed) }
|
|
|
|
}
|
|
|
|
|
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-05-16 17:40:32 +00:00
|
|
|
pub fn generate_chunk(&self, chunk_pos: Vec2<i32>) -> TerrainChunk {
|
2019-05-17 09:22:32 +00:00
|
|
|
// TODO: This is all test code, remove/improve this later.
|
2019-01-23 22:21:47 +00:00
|
|
|
|
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-04-25 21:43:32 +00:00
|
|
|
let grass = Block::new(2, Rgb::new(75, 150, 0));
|
2019-04-25 14:16:10 +00:00
|
|
|
let dirt = Block::new(3, Rgb::new(128, 90, 0));
|
|
|
|
let sand = Block::new(4, Rgb::new(180, 150, 50));
|
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-05-20 02:53:04 +00:00
|
|
|
let warp_nz = Perlin::new().set_seed(self.sim.seed + 0);
|
|
|
|
let temp_nz = Perlin::new().set_seed(self.sim.seed + 1);
|
2019-05-21 12:28:53 +00:00
|
|
|
/*
|
|
|
|
let cliff_nz = BasicMulti::new()
|
|
|
|
.set_octaves(2)
|
|
|
|
.set_seed(self.sim.seed + 2);
|
|
|
|
let cliff_mask_nz = BasicMulti::new()
|
|
|
|
.set_octaves(4)
|
|
|
|
.set_seed(self.sim.seed + 3);
|
|
|
|
*/
|
2019-05-17 21:19:32 +00:00
|
|
|
|
2019-05-20 02:53:04 +00:00
|
|
|
let base_z = match self.sim.get_base_z(chunk_pos.map(|e| e as u32)) {
|
|
|
|
Some(base_z) => base_z as i32,
|
|
|
|
None => return TerrainChunk::new(0, air, air, TerrainChunkMeta::void()),
|
2019-05-19 14:54:37 +00:00
|
|
|
};
|
2019-05-17 21:19:32 +00:00
|
|
|
|
2019-05-20 02:53:04 +00:00
|
|
|
let mut chunk = TerrainChunk::new(base_z, stone, air, TerrainChunkMeta::void());
|
2019-05-17 21:19:32 +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-20 02:53:04 +00:00
|
|
|
let wpos2d = Vec2::new(x, y) + Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32);
|
|
|
|
let wposf2d = wpos2d.map(|e| e as f64);
|
|
|
|
|
2019-05-21 00:57:16 +00:00
|
|
|
let sim::Sample {
|
|
|
|
alt,
|
|
|
|
surface_color
|
|
|
|
} = if let Some(sample) = self.sim.sample(wpos2d) {
|
|
|
|
sample
|
|
|
|
} else {
|
|
|
|
continue
|
|
|
|
};
|
|
|
|
|
2019-05-20 15:01:27 +00:00
|
|
|
let max_z = self.sim
|
|
|
|
.get_interpolated(wpos2d, |chunk| chunk.get_max_z())
|
|
|
|
.unwrap_or(0.0) as i32;
|
|
|
|
|
|
|
|
for z in base_z..max_z {
|
2019-05-17 17:44:30 +00:00
|
|
|
let lpos = Vec3::new(x, y, z);
|
2019-05-17 21:19:32 +00:00
|
|
|
let wpos = lpos
|
|
|
|
+ Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32);
|
2019-05-17 17:44:30 +00:00
|
|
|
let wposf = wpos.map(|e| e as f64);
|
2019-01-23 20:01:58 +00:00
|
|
|
|
2019-05-21 12:28:53 +00:00
|
|
|
/*
|
|
|
|
let cliff_mask = cliff_mask_nz.get((wposf.div(Vec3::new(512.0, 512.0, 2048.0))).into_array())
|
|
|
|
.sub(0.1)
|
|
|
|
.max(0.0)
|
|
|
|
.mul(1.5)
|
|
|
|
.round() as f32;
|
|
|
|
let cliff = (cliff_nz.get((wposf.div(Vec3::new(256.0, 256.0, 128.0))).into_array()) as f32)
|
|
|
|
.mul(cliff_mask)
|
|
|
|
//.mul((30.0).div((wposf.z as f32 - alt)).max(0.0))
|
|
|
|
.mul(150.0)
|
|
|
|
.min(64.0);
|
|
|
|
*/
|
|
|
|
|
|
|
|
let height = alt;// + cliff;
|
2019-05-21 00:57:16 +00:00
|
|
|
let temp = 0.0;
|
2019-01-23 20:01:58 +00:00
|
|
|
|
2019-05-20 02:53:04 +00:00
|
|
|
let z = wposf.z as f32;
|
2019-05-17 17:54:56 +00:00
|
|
|
let _ = chunk.set(
|
|
|
|
lpos,
|
2019-05-21 00:57:16 +00:00
|
|
|
if z < height - 6.0 {
|
2019-05-17 17:54:56 +00:00
|
|
|
stone
|
2019-05-20 02:53:04 +00:00
|
|
|
} else if z < height - 2.0 {
|
2019-05-17 17:54:56 +00:00
|
|
|
dirt
|
2019-05-20 02:53:04 +00:00
|
|
|
} else if z < height {
|
2019-05-21 00:57:16 +00:00
|
|
|
Block::new(1, surface_color.map(|e| (e * 255.0) as u8))
|
2019-05-17 17:54:56 +00:00
|
|
|
} else {
|
|
|
|
air
|
|
|
|
},
|
|
|
|
);
|
2019-05-17 17:44:30 +00:00
|
|
|
}
|
|
|
|
}
|
2019-01-23 20:01:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
chunk
|
2019-05-21 00:57:16 +00:00
|
|
|
|
|
|
|
// */
|
2019-01-15 15:13:11 +00:00
|
|
|
}
|
|
|
|
}
|