Merge branch 'zesterer/worldgen' into 'master'

Dungeons

See merge request veloren/veloren!402
This commit is contained in:
Joshua Barretto 2019-08-03 21:33:01 +00:00
commit 8ef1532902
8 changed files with 106 additions and 74 deletions

BIN
assets/world/structure/dungeon/ruins.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -120,7 +120,7 @@ impl<'a> System<'a> for Sys {
&& (ori.0.normalized() - Vec3::from(ori_dir).normalized()).magnitude_squared()
> 0.001
{
ori.0 = vek::ops::Slerp::slerp(ori.0, ori_dir.into(), 5.0 * dt.0);
ori.0 = vek::ops::Slerp::slerp(ori.0, ori_dir.into(), 15.0 * dt.0);
}
}

View File

@ -15,6 +15,7 @@ pub enum StructureBlock {
Acacia,
PalmLeaves,
Fruit,
Hollow,
Block(Block),
}
@ -94,6 +95,7 @@ impl Asset for Structure {
2 => StructureBlock::PalmLeaves,
4 => StructureBlock::Acacia,
7 => StructureBlock::Fruit,
15 => StructureBlock::Hollow,
index => {
let color = palette
.get(index as usize)

View File

@ -289,40 +289,14 @@ impl<'a> BlockGen<'a> {
}
});
let block = if definitely_underground {
block.unwrap_or(Block::empty())
} else {
block
.or_else(|| {
structures.iter().find_map(|st| {
let (st, st_sample) = st.as_ref()?;
st.get(wpos, st_sample)
/*
let rpos = wpos - st.pos;
let block_pos = Vec3::unit_z() * rpos.z
+ Vec3::from(st.units.0) * rpos.x
+ Vec3::from(st.units.1) * rpos.y;
st.volume
.get((block_pos * 128) / 128) // Scaling
.map(|b| {
block_from_structure(
*b,
block_pos,
st.pos.into(),
st.seed,
st_sample,
)
})
.ok()
.filter(|block| !block.is_empty())
*/
})
})
.unwrap_or(Block::empty())
};
let block = structures
.iter()
.find_map(|st| {
let (st, st_sample) = st.as_ref()?;
st.get(wpos, st_sample)
})
.or(block)
.unwrap_or(Block::empty());
Some(block)
}
@ -346,9 +320,11 @@ impl<'a> ZCache<'a> {
let cliff = if self.sample.near_cliffs { 48.0 } else { 0.0 };
let warp = self.sample.chaos * 48.0;
let structure = self.structures.iter().filter_map(|st| st.as_ref()).fold(
0,
|a, (st_info, st_sample)| {
let (structure_min, structure_max) = self
.structures
.iter()
.filter_map(|st| st.as_ref())
.fold((0.0f32, 0.0f32), |(min, max), (st_info, st_sample)| {
let bounds = st_info.get_bounds();
let st_area = Aabr {
min: Vec2::from(bounds.min),
@ -356,14 +332,14 @@ impl<'a> ZCache<'a> {
};
if st_area.contains_point(self.wpos - st_info.pos) {
a.max(bounds.max.z)
(min.min(bounds.min.z as f32), max.max(bounds.max.z as f32))
} else {
a
(min, max)
}
},
) as f32;
});
let max = (self.sample.alt + cliff + structure + warp + 8.0)
let min = min + structure_min;
let max = (self.sample.alt + cliff + structure_max + warp + 8.0)
.max(self.sample.water_level)
.max(CONFIG.sea_level + 2.0);
@ -444,11 +420,10 @@ impl StructureInfo {
volume
.get((block_pos * 128) / 128) // Scaling
.map(|b| {
.ok()
.and_then(|b| {
block_from_structure(*b, block_pos, self.pos.into(), self.seed, sample)
})
.ok()
.filter(|block| !block.is_empty())
}
}
}
@ -460,7 +435,7 @@ fn block_from_structure(
structure_pos: Vec2<i32>,
structure_seed: u32,
_sample: &ColumnSample,
) -> Block {
) -> Option<Block> {
let field = RandomField::new(structure_seed + 0);
let lerp = 0.5
@ -468,17 +443,17 @@ fn block_from_structure(
+ ((field.get(Vec3::from(pos)) % 256) as f32 / 256.0 - 0.5) * 0.15;
match sblock {
StructureBlock::TemperateLeaves => Block::new(
StructureBlock::TemperateLeaves => Some(Block::new(
1,
Lerp::lerp(Rgb::new(0.0, 70.0, 35.0), Rgb::new(100.0, 140.0, 0.0), lerp)
.map(|e| e as u8),
),
StructureBlock::PineLeaves => Block::new(
)),
StructureBlock::PineLeaves => Some(Block::new(
1,
Lerp::lerp(Rgb::new(0.0, 60.0, 50.0), Rgb::new(30.0, 100.0, 10.0), lerp)
.map(|e| e as u8),
),
StructureBlock::PalmLeaves => Block::new(
)),
StructureBlock::PalmLeaves => Some(Block::new(
1,
Lerp::lerp(
Rgb::new(15.0, 100.0, 30.0),
@ -486,8 +461,8 @@ fn block_from_structure(
lerp,
)
.map(|e| e as u8),
),
StructureBlock::Acacia => Block::new(
)),
StructureBlock::Acacia => Some(Block::new(
1,
Lerp::lerp(
Rgb::new(35.0, 100.0, 10.0),
@ -495,12 +470,13 @@ fn block_from_structure(
lerp,
)
.map(|e| e as u8),
),
StructureBlock::Fruit => Block::new(
)),
StructureBlock::Fruit => Some(Block::new(
1,
Lerp::lerp(Rgb::new(255.0, 0.0, 0.0), Rgb::new(200.0, 255.0, 6.0), lerp)
.map(|e| e as u8),
),
StructureBlock::Block(block) => block,
)),
StructureBlock::Hollow => Some(Block::empty()),
StructureBlock::Block(block) => Some(block).filter(|block| !block.is_empty()),
}
}

View File

@ -2,7 +2,7 @@ use super::{BlockGen, StructureInfo, StructureMeta, ZCache};
use crate::{
all::ForestKind,
column::{ColumnGen, ColumnSample},
util::{HashCache, RandomPerm, Sampler},
util::{HashCache, RandomPerm, Sampler, UnitChooser},
CONFIG,
};
use common::{assets, terrain::Structure};
@ -11,7 +11,7 @@ use std::sync::Arc;
use vek::*;
static VOLUME_RAND: RandomPerm = RandomPerm::new(0xDB21C052);
static UNIT_RAND: RandomPerm = RandomPerm::new(0x700F4EC7);
static UNIT_CHOOSER: UnitChooser = UnitChooser::new(0x700F4EC7);
static QUIRKY_RAND: RandomPerm = RandomPerm::new(0xA634460F);
pub fn structure_gen<'a>(
@ -61,22 +61,11 @@ pub fn structure_gen<'a>(
}
};
const UNIT_CHOICES: [(Vec2<i32>, Vec2<i32>); 8] = [
(Vec2 { x: 1, y: 0 }, Vec2 { x: 0, y: 1 }),
(Vec2 { x: 1, y: 0 }, Vec2 { x: 0, y: -1 }),
(Vec2 { x: -1, y: 0 }, Vec2 { x: 0, y: 1 }),
(Vec2 { x: -1, y: 0 }, Vec2 { x: 0, y: -1 }),
(Vec2 { x: 0, y: 1 }, Vec2 { x: 1, y: 0 }),
(Vec2 { x: 0, y: 1 }, Vec2 { x: -1, y: 0 }),
(Vec2 { x: 0, y: -1 }, Vec2 { x: 1, y: 0 }),
(Vec2 { x: 0, y: -1 }, Vec2 { x: -1, y: 0 }),
];
Some(StructureInfo {
pos: st_pos3d,
seed: st_seed,
meta: StructureMeta::Volume {
units: UNIT_CHOICES[UNIT_RAND.get(st_seed) as usize % UNIT_CHOICES.len()],
units: UNIT_CHOOSER.get(st_seed),
volume: &volumes[(VOLUME_RAND.get(st_seed) / 13) as usize % volumes.len()],
},
})

View File

@ -2,14 +2,20 @@ use crate::{
all::ForestKind,
block::StructureMeta,
sim::{LocationInfo, SimChunk},
util::Sampler,
util::{Sampler, UnitChooser},
World, CONFIG,
};
use common::{terrain::TerrainChunkSize, vol::VolSize};
use common::{
assets,
terrain::{Structure, TerrainChunkSize},
vol::VolSize,
};
use lazy_static::lazy_static;
use noise::NoiseFn;
use std::{
f32,
ops::{Add, Div, Mul, Neg, Sub},
sync::Arc,
};
use vek::*;
@ -17,6 +23,17 @@ pub struct ColumnGen<'a> {
world: &'a World,
}
static UNIT_CHOOSER: UnitChooser = UnitChooser::new(0x700F4EC7);
lazy_static! {
pub static ref DUNGEONS: Vec<Arc<Structure>> = vec![
// green oaks
assets::load_map("world/structure/dungeon/ruins.vox", |s: Structure| s
.with_center(Vec3::new(57, 58, 62)))
.unwrap(),
];
}
impl<'a> ColumnGen<'a> {
pub fn new(world: &'a World) -> Self {
Self { world }
@ -45,6 +62,15 @@ impl<'a> ColumnGen<'a> {
seed,
meta: Some(StructureMeta::Pyramid { height: 140 }),
})
} else if seed % 17 == 2 && chunk.chaos < 0.2 {
Some(StructureData {
pos,
seed,
meta: Some(StructureMeta::Volume {
units: UNIT_CHOOSER.get(seed),
volume: &DUNGEONS[0],
}),
})
} else {
None
}

View File

@ -2,6 +2,7 @@ pub mod hash_cache;
pub mod random;
pub mod sampler;
pub mod structure;
pub mod unit_chooser;
// Reexports
pub use self::{
@ -9,4 +10,5 @@ pub use self::{
random::{RandomField, RandomPerm},
sampler::{Sampler, SamplerMut},
structure::StructureGen2d,
unit_chooser::UnitChooser,
};

View File

@ -0,0 +1,34 @@
use super::{RandomPerm, Sampler};
use vek::*;
const UNIT_CHOICES: [(Vec2<i32>, Vec2<i32>); 8] = [
(Vec2 { x: 1, y: 0 }, Vec2 { x: 0, y: 1 }),
(Vec2 { x: 1, y: 0 }, Vec2 { x: 0, y: -1 }),
(Vec2 { x: -1, y: 0 }, Vec2 { x: 0, y: 1 }),
(Vec2 { x: -1, y: 0 }, Vec2 { x: 0, y: -1 }),
(Vec2 { x: 0, y: 1 }, Vec2 { x: 1, y: 0 }),
(Vec2 { x: 0, y: 1 }, Vec2 { x: -1, y: 0 }),
(Vec2 { x: 0, y: -1 }, Vec2 { x: 1, y: 0 }),
(Vec2 { x: 0, y: -1 }, Vec2 { x: -1, y: 0 }),
];
pub struct UnitChooser {
perm: RandomPerm,
}
impl UnitChooser {
pub const fn new(seed: u32) -> Self {
Self {
perm: RandomPerm::new(seed),
}
}
}
impl Sampler for UnitChooser {
type Index = u32;
type Sample = (Vec2<i32>, Vec2<i32>);
fn get(&self, perm: Self::Index) -> Self::Sample {
UNIT_CHOICES[self.perm.get(perm) as usize % UNIT_CHOICES.len()]
}
}