mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Adjusted tree colour variation
This commit is contained in:
parent
30b668d0cc
commit
a9d30bbfb6
@ -12,19 +12,15 @@ use common::{
|
|||||||
msg::{ClientMsg, ClientState, ServerInfo, ServerMsg},
|
msg::{ClientMsg, ClientState, ServerInfo, ServerMsg},
|
||||||
net::PostBox,
|
net::PostBox,
|
||||||
state::State,
|
state::State,
|
||||||
terrain::{
|
terrain::{chonk::ChonkMetrics, TerrainChunk, TerrainChunkSize},
|
||||||
TerrainChunk,
|
|
||||||
TerrainChunkSize,
|
|
||||||
chonk::ChonkMetrics,
|
|
||||||
},
|
|
||||||
vol::VolSize,
|
vol::VolSize,
|
||||||
};
|
};
|
||||||
use log::{debug, info, log_enabled};
|
use log::{debug, info, log_enabled};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
time::{Duration, Instant},
|
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
use threadpool::ThreadPool;
|
use threadpool::ThreadPool;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
@ -155,11 +151,16 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_chunk(&self) -> Option<Arc<TerrainChunk>> {
|
pub fn current_chunk(&self) -> Option<Arc<TerrainChunk>> {
|
||||||
let chunk_pos = Vec2::from(self
|
let chunk_pos = Vec2::from(
|
||||||
.state
|
self.state
|
||||||
.read_storage::<comp::phys::Pos>()
|
.read_storage::<comp::phys::Pos>()
|
||||||
.get(self.entity)
|
.get(self.entity)
|
||||||
.cloned()?.0).map2(Vec2::from(TerrainChunkSize::SIZE), |e: f32, sz| (e as u32).div_euclid(sz) as i32);
|
.cloned()?
|
||||||
|
.0,
|
||||||
|
)
|
||||||
|
.map2(Vec2::from(TerrainChunkSize::SIZE), |e: f32, sz| {
|
||||||
|
(e as u32).div_euclid(sz) as i32
|
||||||
|
});
|
||||||
|
|
||||||
self.state.terrain().get_key_arc(chunk_pos).cloned()
|
self.state.terrain().get_key_arc(chunk_pos).cloned()
|
||||||
}
|
}
|
||||||
|
@ -267,9 +267,9 @@ impl<S: PostMsg, R: PostMsg> PostBox<S, R> {
|
|||||||
for _ in 0..100 {
|
for _ in 0..100 {
|
||||||
match incoming_buf.get(0..9) {
|
match incoming_buf.get(0..9) {
|
||||||
Some(len_bytes) => {
|
Some(len_bytes) => {
|
||||||
let len = u64::from_le_bytes(
|
let len =
|
||||||
<[u8; 8]>::try_from(&len_bytes[0..8]).unwrap(),
|
u64::from_le_bytes(<[u8; 8]>::try_from(&len_bytes[0..8]).unwrap())
|
||||||
) as usize; // Can't fail
|
as usize; // Can't fail
|
||||||
|
|
||||||
if len > MAX_MSG_SIZE {
|
if len > MAX_MSG_SIZE {
|
||||||
recv_tx.send(Err(Error::InvalidMessage)).unwrap();
|
recv_tx.send(Err(Error::InvalidMessage)).unwrap();
|
||||||
|
@ -33,10 +33,7 @@ pub struct TerrainChunkMeta {
|
|||||||
|
|
||||||
impl TerrainChunkMeta {
|
impl TerrainChunkMeta {
|
||||||
pub fn new(name: Option<String>, biome: BiomeKind) -> Self {
|
pub fn new(name: Option<String>, biome: BiomeKind) -> Self {
|
||||||
Self {
|
Self { name, biome }
|
||||||
name,
|
|
||||||
biome,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn void() -> Self {
|
pub fn void() -> Self {
|
||||||
|
@ -83,14 +83,17 @@ impl Asset for Structure {
|
|||||||
1 => StructureBlock::PineLeaves,
|
1 => StructureBlock::PineLeaves,
|
||||||
2 => StructureBlock::PalmLeaves,
|
2 => StructureBlock::PalmLeaves,
|
||||||
index => {
|
index => {
|
||||||
let color = palette.get(index as usize).copied().unwrap_or(Rgb::broadcast(0));
|
let color = palette
|
||||||
|
.get(index as usize)
|
||||||
|
.copied()
|
||||||
|
.unwrap_or(Rgb::broadcast(0));
|
||||||
StructureBlock::Block(Block::new(1, color))
|
StructureBlock::Block(Block::new(1, color))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = vol.set(
|
let _ = vol.set(
|
||||||
Vec3::new(voxel.x, voxel.y, voxel.z).map(|e| e as i32),
|
Vec3::new(voxel.x, voxel.y, voxel.z).map(|e| e as i32),
|
||||||
block
|
block,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ void main() {
|
|||||||
|
|
||||||
float sun_ambience = 0.8;
|
float sun_ambience = 0.8;
|
||||||
|
|
||||||
vec3 sun_dir = normalize(vec3(1.3, 1.7, 2.1));
|
vec3 sun_dir = normalize(vec3(0.7, 1.3, 2.1));
|
||||||
|
|
||||||
float sun_diffuse = dot(sun_dir, f_norm);
|
float sun_diffuse = dot(sun_dir, f_norm);
|
||||||
float sun_light = sun_ambience + sun_diffuse;
|
float sun_light = sun_ambience + sun_diffuse;
|
||||||
|
@ -117,7 +117,8 @@ impl Scene {
|
|||||||
// Alter camera position to match player.
|
// Alter camera position to match player.
|
||||||
let tilt = self.camera.get_orientation().y;
|
let tilt = self.camera.get_orientation().y;
|
||||||
let dist = self.camera.get_distance();
|
let dist = self.camera.get_distance();
|
||||||
self.camera.set_focus_pos(player_pos + Vec3::unit_z() * (2.1 - tilt.min(0.0) * dist * 0.75));
|
self.camera
|
||||||
|
.set_focus_pos(player_pos + Vec3::unit_z() * (2.1 - tilt.min(0.0) * dist * 0.75));
|
||||||
|
|
||||||
// Tick camera for interpolation.
|
// Tick camera for interpolation.
|
||||||
self.camera.update(client.state().get_time());
|
self.camera.update(client.state().get_time());
|
||||||
|
@ -72,7 +72,7 @@ impl SessionState {
|
|||||||
// TODO: Get rid of this
|
// TODO: Get rid of this
|
||||||
match self.client.borrow().current_chunk() {
|
match self.client.borrow().current_chunk() {
|
||||||
Some(chunk) => println!("Chunk location: {:?}", chunk.meta().name()),
|
Some(chunk) => println!("Chunk location: {:?}", chunk.meta().name()),
|
||||||
None => {},
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
mod tree;
|
mod tree;
|
||||||
|
|
||||||
use std::ops::{Add, Div, Mul, Neg, Sub};
|
|
||||||
use noise::NoiseFn;
|
|
||||||
use vek::*;
|
|
||||||
use common::{
|
|
||||||
terrain::{Block, structure::StructureBlock},
|
|
||||||
vol::{Vox, ReadVol},
|
|
||||||
};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
util::{Sampler, HashCache},
|
|
||||||
column::{ColumnGen, ColumnSample},
|
column::{ColumnGen, ColumnSample},
|
||||||
CONFIG,
|
util::{HashCache, RandomField, Sampler, SamplerMut},
|
||||||
World,
|
World, CONFIG,
|
||||||
};
|
};
|
||||||
|
use common::{
|
||||||
|
terrain::{structure::StructureBlock, Block},
|
||||||
|
vol::{ReadVol, Vox},
|
||||||
|
};
|
||||||
|
use noise::NoiseFn;
|
||||||
|
use std::ops::{Add, Div, Mul, Neg, Sub};
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
pub struct BlockGen<'a> {
|
pub struct BlockGen<'a> {
|
||||||
world: &'a World,
|
world: &'a World,
|
||||||
@ -37,7 +36,7 @@ impl<'a> BlockGen<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Sampler for BlockGen<'a> {
|
impl<'a> SamplerMut for BlockGen<'a> {
|
||||||
type Index = Vec3<i32>;
|
type Index = Vec3<i32>;
|
||||||
type Sample = Option<Block>;
|
type Sample = Option<Block>;
|
||||||
|
|
||||||
@ -60,7 +59,9 @@ impl<'a> Sampler for BlockGen<'a> {
|
|||||||
|
|
||||||
// Apply warping
|
// Apply warping
|
||||||
|
|
||||||
let warp = (self.world.sim()
|
let warp = (self
|
||||||
|
.world
|
||||||
|
.sim()
|
||||||
.gen_ctx
|
.gen_ctx
|
||||||
.warp_nz
|
.warp_nz
|
||||||
.get((wposf.div(Vec3::new(150.0, 150.0, 150.0))).into_array())
|
.get((wposf.div(Vec3::new(150.0, 150.0, 150.0))).into_array())
|
||||||
@ -69,29 +70,37 @@ impl<'a> Sampler for BlockGen<'a> {
|
|||||||
.mul(115.0);
|
.mul(115.0);
|
||||||
|
|
||||||
let is_cliff = if cliff > 0.0 {
|
let is_cliff = if cliff > 0.0 {
|
||||||
(self.world.sim()
|
(self
|
||||||
.gen_ctx
|
.world
|
||||||
.warp_nz
|
.sim()
|
||||||
.get((wposf.div(Vec3::new(300.0, 300.0, 1500.0))).into_array())
|
.gen_ctx
|
||||||
as f32) * cliff > 0.3
|
.warp_nz
|
||||||
|
.get((wposf.div(Vec3::new(300.0, 300.0, 1500.0))).into_array()) as f32)
|
||||||
|
* cliff
|
||||||
|
> 0.3
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
let cliff = if is_cliff {
|
let cliff = if is_cliff {
|
||||||
(0.0
|
(0.0 + (self
|
||||||
+ (self.world.sim()
|
.world
|
||||||
|
.sim()
|
||||||
.gen_ctx
|
.gen_ctx
|
||||||
.warp_nz
|
.warp_nz
|
||||||
.get((wposf.div(Vec3::new(350.0, 350.0, 800.0))).into_array())
|
.get((wposf.div(Vec3::new(350.0, 350.0, 800.0))).into_array())
|
||||||
as f32) * 0.8
|
as f32)
|
||||||
+ (self.world.sim()
|
* 0.8
|
||||||
.gen_ctx
|
+ (self
|
||||||
.warp_nz
|
.world
|
||||||
.get((wposf.div(Vec3::new(100.0, 100.0, 70.0))).into_array())
|
.sim()
|
||||||
as f32) * 0.3)
|
.gen_ctx
|
||||||
.add(0.4)
|
.warp_nz
|
||||||
.mul(64.0)
|
.get((wposf.div(Vec3::new(100.0, 100.0, 70.0))).into_array())
|
||||||
|
as f32)
|
||||||
|
* 0.3)
|
||||||
|
.add(0.4)
|
||||||
|
.mul(75.0)
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
};
|
};
|
||||||
@ -162,24 +171,43 @@ impl<'a> Sampler for BlockGen<'a> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
fn block_from_structure(sblock: StructureBlock, structure_pos: Vec2<i32>, sample: &ColumnSample) -> Block {
|
fn block_from_structure(
|
||||||
let temp_lerp = sample.temp * 4.0;
|
sblock: StructureBlock,
|
||||||
|
pos: Vec3<i32>,
|
||||||
|
structure_pos: Vec2<i32>,
|
||||||
|
structure_seed: u32,
|
||||||
|
sample: &ColumnSample,
|
||||||
|
) -> Block {
|
||||||
|
let field = RandomField::new(structure_seed + 0);
|
||||||
|
|
||||||
|
let lerp = 0.5
|
||||||
|
+ ((field.get(Vec3::from(structure_pos)) % 256) as f32 / 256.0 - 0.5) * 0.75
|
||||||
|
+ ((field.get(Vec3::from(pos)) % 256) as f32 / 256.0 - 0.5) * 0.2;
|
||||||
|
|
||||||
match sblock {
|
match sblock {
|
||||||
StructureBlock::TemperateLeaves => Block::new(1, Lerp::lerp(
|
StructureBlock::TemperateLeaves => Block::new(
|
||||||
Rgb::new(0.0, 150.0, 50.0),
|
1,
|
||||||
Rgb::new(200.0, 255.0, 0.0),
|
Lerp::lerp(
|
||||||
temp_lerp,
|
Rgb::new(0.0, 80.0, 40.0),
|
||||||
).map(|e| e as u8)),
|
Rgb::new(120.0, 255.0, 10.0),
|
||||||
StructureBlock::PineLeaves => Block::new(1, Lerp::lerp(
|
lerp,
|
||||||
Rgb::new(0.0, 100.0, 90.0),
|
)
|
||||||
Rgb::new(50.0, 150.0, 50.0),
|
.map(|e| e as u8),
|
||||||
temp_lerp,
|
),
|
||||||
).map(|e| e as u8)),
|
StructureBlock::PineLeaves => Block::new(
|
||||||
StructureBlock::PalmLeaves => Block::new(1, Lerp::lerp(
|
1,
|
||||||
Rgb::new(80.0, 150.0, 0.0),
|
Lerp::lerp(Rgb::new(0.0, 60.0, 50.0), Rgb::new(30.0, 100.0, 10.0), lerp)
|
||||||
Rgb::new(180.0, 255.0, 0.0),
|
.map(|e| e as u8),
|
||||||
temp_lerp,
|
),
|
||||||
).map(|e| e as u8)),
|
StructureBlock::PalmLeaves => Block::new(
|
||||||
|
1,
|
||||||
|
Lerp::lerp(
|
||||||
|
Rgb::new(30.0, 100.0, 30.0),
|
||||||
|
Rgb::new(120.0, 255.0, 0.0),
|
||||||
|
lerp,
|
||||||
|
)
|
||||||
|
.map(|e| e as u8),
|
||||||
|
),
|
||||||
StructureBlock::Block(block) => block,
|
StructureBlock::Block(block) => block,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,7 +230,15 @@ impl<'a> Sampler for BlockGen<'a> {
|
|||||||
|
|
||||||
block.or(trees[*tree_seed as usize % trees.len()]
|
block.or(trees[*tree_seed as usize % trees.len()]
|
||||||
.get((rpos * 128) / 128) // Scaling
|
.get((rpos * 128) / 128) // Scaling
|
||||||
.map(|b| block_from_structure(*b, *tree_pos, &tree_sample))
|
.map(|b| {
|
||||||
|
block_from_structure(
|
||||||
|
*b,
|
||||||
|
rpos,
|
||||||
|
*tree_pos,
|
||||||
|
*tree_seed,
|
||||||
|
&tree_sample,
|
||||||
|
)
|
||||||
|
})
|
||||||
.unwrap_or(Block::empty()))
|
.unwrap_or(Block::empty()))
|
||||||
}
|
}
|
||||||
_ => block,
|
_ => block,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
use crate::all::ForestKind;
|
||||||
use common::{assets, terrain::Structure};
|
use common::{assets, terrain::Structure};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use crate::all::ForestKind;
|
|
||||||
|
|
||||||
pub fn kinds(forest_kind: ForestKind) -> &'static [Arc<Structure>] {
|
pub fn kinds(forest_kind: ForestKind) -> &'static [Arc<Structure>] {
|
||||||
match forest_kind {
|
match forest_kind {
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
use std::ops::{Add, Div, Mul, Neg, Sub};
|
use crate::{all::ForestKind, util::Sampler, World, CONFIG};
|
||||||
use vek::*;
|
|
||||||
use noise::NoiseFn;
|
|
||||||
use common::{
|
use common::{
|
||||||
terrain::{Block, TerrainChunkSize},
|
terrain::{Block, TerrainChunkSize},
|
||||||
vol::{Vox, VolSize},
|
vol::{VolSize, Vox},
|
||||||
};
|
|
||||||
use crate::{
|
|
||||||
CONFIG,
|
|
||||||
all::ForestKind,
|
|
||||||
util::Sampler,
|
|
||||||
World,
|
|
||||||
};
|
};
|
||||||
|
use noise::NoiseFn;
|
||||||
|
use std::ops::{Add, Div, Mul, Neg, Sub};
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
pub struct ColumnGen<'a> {
|
pub struct ColumnGen<'a> {
|
||||||
world: &'a World,
|
world: &'a World,
|
||||||
@ -18,9 +13,7 @@ pub struct ColumnGen<'a> {
|
|||||||
|
|
||||||
impl<'a> ColumnGen<'a> {
|
impl<'a> ColumnGen<'a> {
|
||||||
pub fn new(world: &'a World) -> Self {
|
pub fn new(world: &'a World) -> Self {
|
||||||
Self {
|
Self { world }
|
||||||
world,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,9 +21,11 @@ impl<'a> Sampler for ColumnGen<'a> {
|
|||||||
type Index = Vec2<i32>;
|
type Index = Vec2<i32>;
|
||||||
type Sample = Option<ColumnSample>;
|
type Sample = Option<ColumnSample>;
|
||||||
|
|
||||||
fn get(&mut self, wpos: Vec2<i32>) -> Option<ColumnSample> {
|
fn get(&self, wpos: Vec2<i32>) -> Option<ColumnSample> {
|
||||||
let wposf = wpos.map(|e| e as f64);
|
let wposf = wpos.map(|e| e as f64);
|
||||||
let chunk_pos = wpos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| e as u32 / sz);
|
let chunk_pos = wpos.map2(Vec2::from(TerrainChunkSize::SIZE), |e, sz: u32| {
|
||||||
|
e as u32 / sz
|
||||||
|
});
|
||||||
|
|
||||||
let sim = self.world.sim();
|
let sim = self.world.sim();
|
||||||
|
|
||||||
@ -48,7 +43,11 @@ impl<'a> Sampler for ColumnGen<'a> {
|
|||||||
* chaos.max(0.2)
|
* chaos.max(0.2)
|
||||||
* 64.0;
|
* 64.0;
|
||||||
|
|
||||||
let rock = (sim.gen_ctx.small_nz.get(Vec3::new(wposf.x, wposf.y, alt as f64).div(100.0).into_array()) as f32)
|
let rock = (sim.gen_ctx.small_nz.get(
|
||||||
|
Vec3::new(wposf.x, wposf.y, alt as f64)
|
||||||
|
.div(100.0)
|
||||||
|
.into_array(),
|
||||||
|
) as f32)
|
||||||
.mul(rockiness)
|
.mul(rockiness)
|
||||||
.sub(0.4)
|
.sub(0.4)
|
||||||
.max(0.0)
|
.max(0.0)
|
||||||
@ -59,8 +58,8 @@ impl<'a> Sampler for ColumnGen<'a> {
|
|||||||
let marble = (0.0
|
let marble = (0.0
|
||||||
+ (sim.gen_ctx.hill_nz.get((wposf3d.div(48.0)).into_array()) as f32).mul(0.75)
|
+ (sim.gen_ctx.hill_nz.get((wposf3d.div(48.0)).into_array()) as f32).mul(0.75)
|
||||||
+ (sim.gen_ctx.hill_nz.get((wposf3d.div(3.0)).into_array()) as f32).mul(0.25))
|
+ (sim.gen_ctx.hill_nz.get((wposf3d.div(3.0)).into_array()) as f32).mul(0.25))
|
||||||
.add(1.0)
|
.add(1.0)
|
||||||
.mul(0.5);
|
.mul(0.5);
|
||||||
|
|
||||||
// Colours
|
// Colours
|
||||||
let cold_grass = Rgb::new(0.0, 0.3, 0.1);
|
let cold_grass = Rgb::new(0.0, 0.3, 0.1);
|
||||||
@ -79,7 +78,9 @@ impl<'a> Sampler for ColumnGen<'a> {
|
|||||||
Rgb::lerp(
|
Rgb::lerp(
|
||||||
snow,
|
snow,
|
||||||
grass,
|
grass,
|
||||||
temp.sub(CONFIG.snow_temp).sub((marble - 0.5) * 0.05).mul(256.0),
|
temp.sub(CONFIG.snow_temp)
|
||||||
|
.sub((marble - 0.5) * 0.05)
|
||||||
|
.mul(256.0),
|
||||||
),
|
),
|
||||||
sand,
|
sand,
|
||||||
temp.sub(CONFIG.desert_temp).mul(32.0),
|
temp.sub(CONFIG.desert_temp).mul(32.0),
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
#![feature(euclidean_division, bind_by_move_pattern_guards)]
|
#![feature(euclidean_division, bind_by_move_pattern_guards)]
|
||||||
|
|
||||||
mod config;
|
|
||||||
mod all;
|
mod all;
|
||||||
mod util;
|
|
||||||
mod block;
|
mod block;
|
||||||
mod column;
|
mod column;
|
||||||
|
mod config;
|
||||||
mod sim;
|
mod sim;
|
||||||
|
mod util;
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use crate::config::CONFIG;
|
pub use crate::config::CONFIG;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
block::BlockGen,
|
||||||
|
column::ColumnGen,
|
||||||
|
util::{HashCache, Sampler, SamplerMut},
|
||||||
|
};
|
||||||
use common::{
|
use common::{
|
||||||
terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
|
terrain::{Block, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
|
||||||
vol::{VolSize, Vox, WriteVol},
|
vol::{VolSize, Vox, WriteVol},
|
||||||
};
|
};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use crate::{
|
|
||||||
util::{Sampler, HashCache},
|
|
||||||
column::ColumnGen,
|
|
||||||
block::BlockGen,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
@ -46,7 +46,7 @@ impl World {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sample(&self) -> impl Sampler<Index=Vec3<i32>, Sample=Option<Block>> + '_ {
|
pub fn sample(&self) -> impl SamplerMut<Index = Vec3<i32>, Sample = Option<Block>> + '_ {
|
||||||
BlockGen::new(self, ColumnGen::new(self))
|
BlockGen::new(self, ColumnGen::new(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,20 +21,17 @@ pub struct Kingdom {
|
|||||||
|
|
||||||
fn generate_name() -> String {
|
fn generate_name() -> String {
|
||||||
let consts = [
|
let consts = [
|
||||||
"st", "tr", "b", "n", "p", "ph", "cr", "g", "c",
|
"st", "tr", "b", "n", "p", "ph", "cr", "g", "c", "d", "k", "kr", "kl", "gh", "sl", "st",
|
||||||
"d", "k", "kr", "kl", "gh", "sl", "st", "cr", "sp",
|
"cr", "sp", "th", "dr", "pr", "dr", "gr", "br", "ryth", "rh", "sl", "f", "fr", "p", "pr",
|
||||||
"th", "dr", "pr", "dr", "gr", "br", "ryth", "rh", "sl",
|
"qu", "s", "sh", "z", "k", "br", "wh", "tr", "h", "bl", "sl", "r", "kl", "sl", "w", "v",
|
||||||
"f", "fr", "p", "pr", "qu", "s", "sh", "z", "k",
|
"vr", "kr",
|
||||||
"br", "wh", "tr", "h", "bl", "sl", "r", "kl", "sl",
|
];
|
||||||
"w", "v", "vr", "kr",
|
let vowels = [
|
||||||
|
"oo", "o", "oa", "au", "e", "ee", "ea", "ou", "u", "a", "i", "ie",
|
||||||
];
|
];
|
||||||
let vowels = ["oo", "o", "oa", "au", "e", "ee", "ea", "ou", "u", "a", "i", "ie"];
|
|
||||||
let tails = [
|
let tails = [
|
||||||
"er", "in", "o", "on", "an",
|
"er", "in", "o", "on", "an", "ar", "is", "oon", "er", "aru", "ab", "um", "id", "and",
|
||||||
"ar", "is", "oon", "er", "aru",
|
"eld", "ald", "oft", "aft", "ift", "ity", "ell", "oll", "ill", "all",
|
||||||
"ab", "um", "id", "and", "eld",
|
|
||||||
"ald", "oft", "aft", "ift", "ity",
|
|
||||||
"ell", "oll", "ill", "all",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut name = String::new();
|
let mut name = String::new();
|
||||||
|
@ -1,24 +1,14 @@
|
|||||||
mod location;
|
mod location;
|
||||||
|
|
||||||
|
use self::location::Location;
|
||||||
|
use crate::{all::ForestKind, util::StructureGen2d, CONFIG};
|
||||||
|
use common::{terrain::TerrainChunkSize, vol::VolSize};
|
||||||
|
use noise::{BasicMulti, HybridMulti, MultiFractal, NoiseFn, RidgedMulti, Seedable, SuperSimplex};
|
||||||
use std::{
|
use std::{
|
||||||
ops::{Add, Div, Mul, Neg, Sub},
|
ops::{Add, Div, Mul, Neg, Sub},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use noise::{
|
|
||||||
BasicMulti, RidgedMulti, SuperSimplex, HybridMulti,
|
|
||||||
MultiFractal, NoiseFn, Seedable,
|
|
||||||
};
|
|
||||||
use common::{
|
|
||||||
terrain::TerrainChunkSize,
|
|
||||||
vol::VolSize,
|
|
||||||
};
|
|
||||||
use crate::{
|
|
||||||
CONFIG,
|
|
||||||
all::ForestKind,
|
|
||||||
util::StructureGen2d,
|
|
||||||
};
|
|
||||||
use self::location::Location;
|
|
||||||
|
|
||||||
pub const WORLD_SIZE: Vec2<usize> = Vec2 { x: 1024, y: 1024 };
|
pub const WORLD_SIZE: Vec2<usize> = Vec2 { x: 1024, y: 1024 };
|
||||||
|
|
||||||
@ -240,7 +230,11 @@ impl SimChunk {
|
|||||||
.mul(0.5)
|
.mul(0.5)
|
||||||
.mul(1.2 - chaos * 0.85)
|
.mul(1.2 - chaos * 0.85)
|
||||||
.add(0.1)
|
.add(0.1)
|
||||||
.mul(if alt > CONFIG.sea_level + 2.0 { 1.0 } else { 0.0 }),
|
.mul(if alt > CONFIG.sea_level + 5.0 {
|
||||||
|
1.0
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
}),
|
||||||
forest_kind: if temp > 0.0 {
|
forest_kind: if temp > 0.0 {
|
||||||
if temp > CONFIG.desert_temp {
|
if temp > CONFIG.desert_temp {
|
||||||
ForestKind::Palm
|
ForestKind::Palm
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::hash::Hash;
|
|
||||||
use fxhash::FxHashMap;
|
use fxhash::FxHashMap;
|
||||||
|
use std::hash::Hash;
|
||||||
|
|
||||||
pub struct HashCache<K: Hash + Eq + Clone, V> {
|
pub struct HashCache<K: Hash + Eq + Clone, V> {
|
||||||
capacity: usize,
|
capacity: usize,
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
pub mod sampler;
|
|
||||||
pub mod hash_cache;
|
pub mod hash_cache;
|
||||||
|
pub mod random;
|
||||||
|
pub mod sampler;
|
||||||
pub mod structure;
|
pub mod structure;
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use self::{
|
pub use self::{
|
||||||
sampler::Sampler,
|
|
||||||
hash_cache::HashCache,
|
hash_cache::HashCache,
|
||||||
|
random::RandomField,
|
||||||
|
sampler::{Sampler, SamplerMut},
|
||||||
structure::StructureGen2d,
|
structure::StructureGen2d,
|
||||||
};
|
};
|
||||||
|
41
world/src/util/random.rs
Normal file
41
world/src/util/random.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
use super::Sampler;
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
|
pub struct RandomField {
|
||||||
|
seed: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RandomField {
|
||||||
|
pub fn new(seed: u32) -> Self {
|
||||||
|
Self { seed }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sampler for RandomField {
|
||||||
|
type Index = Vec3<i32>;
|
||||||
|
type Sample = u32;
|
||||||
|
|
||||||
|
fn get(&self, pos: Self::Index) -> Self::Sample {
|
||||||
|
let pos = pos.map(|e| (e * 13 + (1 << 31)) as u32);
|
||||||
|
|
||||||
|
let next = self.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(318912) ^ 0x23341753;
|
||||||
|
let next = next
|
||||||
|
.rotate_left(13)
|
||||||
|
.wrapping_mul(938219)
|
||||||
|
.wrapping_add(pos.z);
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
@ -2,5 +2,12 @@ pub trait Sampler: Sized {
|
|||||||
type Index;
|
type Index;
|
||||||
type Sample;
|
type Sample;
|
||||||
|
|
||||||
|
fn get(&self, index: Self::Index) -> Self::Sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SamplerMut: Sized {
|
||||||
|
type Index;
|
||||||
|
type Sample;
|
||||||
|
|
||||||
fn get(&mut self, index: Self::Index) -> Self::Sample;
|
fn get(&mut self, index: Self::Index) -> Self::Sample;
|
||||||
}
|
}
|
||||||
|
@ -1,38 +1,31 @@
|
|||||||
|
use super::{RandomField, Sampler};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
pub struct StructureGen2d {
|
pub struct StructureGen2d {
|
||||||
seed: u32,
|
|
||||||
freq: u32,
|
freq: u32,
|
||||||
spread: u32,
|
spread: u32,
|
||||||
|
x_field: RandomField,
|
||||||
|
y_field: RandomField,
|
||||||
|
seed_field: RandomField,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StructureGen2d {
|
impl StructureGen2d {
|
||||||
pub fn new(seed: u32, freq: u32, spread: u32) -> Self {
|
pub fn new(seed: u32, freq: u32, spread: u32) -> Self {
|
||||||
Self { seed, freq, spread }
|
Self {
|
||||||
|
freq,
|
||||||
|
spread,
|
||||||
|
x_field: RandomField::new(seed + 0),
|
||||||
|
y_field: RandomField::new(seed + 1),
|
||||||
|
seed_field: RandomField::new(seed + 2),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn random(&self, seed: u32, pos: Vec2<i32>) -> u32 {
|
impl Sampler for StructureGen2d {
|
||||||
let pos = pos.map(|e| (e * 13 + (1 << 31)) as u32);
|
type Index = Vec2<i32>;
|
||||||
|
type Sample = [(Vec2<i32>, u32); 9];
|
||||||
|
|
||||||
let next = (self.seed + seed)
|
fn get(&self, sample_pos: Self::Index) -> Self::Sample {
|
||||||
.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
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&self, sample_pos: Vec2<i32>) -> [(Vec2<i32>, u32); 9] {
|
|
||||||
let mut samples = [(Vec2::zero(), 0); 9];
|
let mut samples = [(Vec2::zero(), 0); 9];
|
||||||
|
|
||||||
let sample_closest = sample_pos.map(|e| e - e.rem_euclid(self.freq as i32));
|
let sample_closest = sample_pos.map(|e| e - e.rem_euclid(self.freq as i32));
|
||||||
@ -45,12 +38,12 @@ impl StructureGen2d {
|
|||||||
samples[i * 3 + j] = (
|
samples[i * 3 + j] = (
|
||||||
center
|
center
|
||||||
+ Vec2::new(
|
+ Vec2::new(
|
||||||
(self.random(1, center) % (self.spread * 2)) as i32
|
(self.x_field.get(Vec3::from(center)) % (self.spread * 2)) as i32
|
||||||
- self.spread as i32,
|
- self.spread as i32,
|
||||||
(self.random(2, center) % (self.spread * 2)) as i32
|
(self.y_field.get(Vec3::from(center)) % (self.spread * 2)) as i32
|
||||||
- self.spread as i32,
|
- self.spread as i32,
|
||||||
),
|
),
|
||||||
self.random(3, center),
|
self.seed_field.get(Vec3::from(center)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user