Faster More interesting giant trees, better oaks, hives on branches

This commit is contained in:
Joshua Barretto 2021-02-08 02:29:25 +00:00
parent 185b1c3053
commit 6fc7d2a906
8 changed files with 38 additions and 19 deletions

View File

@ -30,6 +30,7 @@ make_case_elim!(
Hollow = 13, Hollow = 13,
Liana = 14, Liana = 14,
Normal(color: Rgb<u8>) = 15, Normal(color: Rgb<u8>) = 15,
Log = 16,
} }
); );

View File

@ -571,7 +571,7 @@ impl ParticleMgr {
cond: |_| true, cond: |_| true,
}, },
BlockParticles { BlockParticles {
blocks: |boi| &boi.reeds, blocks: |boi| &boi.fireflies,
range: 6, range: 6,
rate: 0.004, rate: 0.004,
lifetime: 40.0, lifetime: 40.0,

View File

@ -15,6 +15,7 @@ pub struct BlocksOfInterest {
pub smokers: Vec<Vec3<i32>>, pub smokers: Vec<Vec3<i32>>,
pub beehives: Vec<Vec3<i32>>, pub beehives: Vec<Vec3<i32>>,
pub reeds: Vec<Vec3<i32>>, pub reeds: Vec<Vec3<i32>>,
pub fireflies: Vec<Vec3<i32>>,
pub flowers: Vec<Vec3<i32>>, pub flowers: Vec<Vec3<i32>>,
pub fire_bowls: Vec<Vec3<i32>>, pub fire_bowls: Vec<Vec3<i32>>,
pub snow: Vec<Vec3<i32>>, pub snow: Vec<Vec3<i32>>,
@ -39,6 +40,7 @@ impl BlocksOfInterest {
let mut smokers = Vec::new(); let mut smokers = Vec::new();
let mut beehives = Vec::new(); let mut beehives = Vec::new();
let mut reeds = Vec::new(); let mut reeds = Vec::new();
let mut fireflies = Vec::new();
let mut flowers = Vec::new(); let mut flowers = Vec::new();
let mut interactables = Vec::new(); let mut interactables = Vec::new();
let mut lights = Vec::new(); let mut lights = Vec::new();
@ -94,10 +96,12 @@ impl BlocksOfInterest {
Some(SpriteKind::Beehive) => beehives.push(pos), Some(SpriteKind::Beehive) => beehives.push(pos),
Some(SpriteKind::Reed) => { Some(SpriteKind::Reed) => {
reeds.push(pos); reeds.push(pos);
fireflies.push(pos);
if thread_rng().gen_range(0..12) == 0 { if thread_rng().gen_range(0..12) == 0 {
frogs.push(pos) frogs.push(pos);
} }
}, },
Some(SpriteKind::CaveMushroom) => fireflies.push(pos),
Some(SpriteKind::PinkFlower) => flowers.push(pos), Some(SpriteKind::PinkFlower) => flowers.push(pos),
Some(SpriteKind::PurpleFlower) => flowers.push(pos), Some(SpriteKind::PurpleFlower) => flowers.push(pos),
Some(SpriteKind::RedFlower) => flowers.push(pos), Some(SpriteKind::RedFlower) => flowers.push(pos),
@ -123,6 +127,7 @@ impl BlocksOfInterest {
smokers, smokers,
beehives, beehives,
reeds, reeds,
fireflies,
flowers, flowers,
interactables, interactables,
lights, lights,

View File

@ -12,8 +12,8 @@ pub enum ForestKind {
Pine, Pine,
Birch, Birch,
Mangrove, Mangrove,
Swamp,
Giant, Giant,
Swamp,
} }
pub struct Environment { pub struct Environment {

View File

@ -249,6 +249,7 @@ pub fn block_from_structure(
Some(with_sprite(SpriteKind::Chest)) Some(with_sprite(SpriteKind::Chest))
} }
}, },
StructureBlock::Log => Some(Block::new(BlockKind::Wood, Rgb::new(60, 30, 0))),
// We interpolate all these BlockKinds as needed. // We interpolate all these BlockKinds as needed.
StructureBlock::TemperateLeaves StructureBlock::TemperateLeaves
| StructureBlock::PineLeaves | StructureBlock::PineLeaves

View File

@ -9,7 +9,7 @@ use common::{
assets::AssetHandle, assets::AssetHandle,
terrain::{ terrain::{
structure::{Structure, StructureBlock, StructuresGroup}, structure::{Structure, StructureBlock, StructuresGroup},
Block, BlockKind, Block, BlockKind, SpriteKind,
}, },
vol::ReadVol, vol::ReadVol,
}; };
@ -40,7 +40,7 @@ static UNIT_CHOOSER: UnitChooser = UnitChooser::new(0x700F4EC7);
static QUIRKY_RAND: RandomPerm = RandomPerm::new(0xA634460F); static QUIRKY_RAND: RandomPerm = RandomPerm::new(0xA634460F);
#[allow(clippy::if_same_then_else)] #[allow(clippy::if_same_then_else)]
pub fn apply_trees_to(canvas: &mut Canvas) { pub fn apply_trees_to(canvas: &mut Canvas, dynamic_rng: &mut impl Rng) {
// TODO: Get rid of this // TODO: Get rid of this
enum TreeModel { enum TreeModel {
Structure(Structure), Structure(Structure),
@ -167,6 +167,7 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
let mut is_top = true; let mut is_top = true;
let mut is_leaf_top = true; let mut is_leaf_top = true;
let mut last_block = Block::empty();
for z in (bounds.min.z..bounds.max.z).rev() { for z in (bounds.min.z..bounds.max.z).rev() {
let wpos = Vec3::new(wpos2d.x, wpos2d.y, tree.pos.z + z); let wpos = Vec3::new(wpos2d.x, wpos2d.y, tree.pos.z + z);
let model_pos = Vec3::from( let model_pos = Vec3::from(
@ -183,7 +184,7 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
TreeModel::Structure(s) => s.get(model_pos).ok().copied(), TreeModel::Structure(s) => s.get(model_pos).ok().copied(),
TreeModel::Procedural(t, leaf_block) => Some( TreeModel::Procedural(t, leaf_block) => Some(
match t.is_branch_or_leaves_at(model_pos.map(|e| e as f32 + 0.5)) { match t.is_branch_or_leaves_at(model_pos.map(|e| e as f32 + 0.5)) {
(true, _) => StructureBlock::Normal(Rgb::new(60, 30, 0)), (true, _) => StructureBlock::Log,
(_, true) => *leaf_block, (_, true) => *leaf_block,
(_, _) => StructureBlock::None, (_, _) => StructureBlock::None,
}, },
@ -200,8 +201,11 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
Block::air, Block::air,
) )
.map(|block| { .map(|block| {
// Add mushrooms to the tree
if last_block.is_air() && block.kind() == BlockKind::Wood && dynamic_rng.gen_range(0..48) == 0 {
canvas.set(wpos + Vec3::unit_z(), Block::air(SpriteKind::CaveMushroom));
// Add a snow covering to the block above under certain circumstances // Add a snow covering to the block above under certain circumstances
if col.snow_cover } else if col.snow_cover
&& ((block.kind() == BlockKind::Leaves && is_leaf_top) && ((block.kind() == BlockKind::Leaves && is_leaf_top)
|| (is_top && block.is_filled())) || (is_top && block.is_filled()))
{ {
@ -213,9 +217,15 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
canvas.set(wpos, block); canvas.set(wpos, block);
is_leaf_top = false; is_leaf_top = false;
is_top = false; is_top = false;
last_block = block;
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {
if last_block.kind() == BlockKind::Wood && dynamic_rng.gen_range(0..512) == 0 {
canvas.set(wpos, Block::air(SpriteKind::Beehive));
}
is_leaf_top = true; is_leaf_top = true;
last_block = Block::empty();
}); });
} }
} }
@ -260,18 +270,18 @@ pub struct TreeConfig {
impl TreeConfig { impl TreeConfig {
pub fn oak(rng: &mut impl Rng, scale: f32) -> Self { pub fn oak(rng: &mut impl Rng, scale: f32) -> Self {
let scale = scale * (1.0 + rng.gen::<f32>().powi(4)); let scale = scale * (0.9 + rng.gen::<f32>().powi(4));
let log_scale = 1.0 + scale.log2().max(0.0); let log_scale = 1.0 + scale.log2().max(0.0);
Self { Self {
trunk_len: 9.0 * scale, trunk_len: 9.0 * scale,
trunk_radius: 2.0 * scale, trunk_radius: 2.0 * scale,
branch_child_len: 0.8, branch_child_len: 0.9,
branch_child_radius: 0.75, branch_child_radius: 0.75,
leaf_radius: 2.5 * log_scale..3.25 * log_scale, leaf_radius: 2.5 * log_scale..3.25 * log_scale,
straightness: 0.5, straightness: 0.45,
max_depth: (4.0 + log_scale) as usize, max_depth: 4,
splits: 2.0..3.0, splits: 2.25..3.25,
split_range: 0.75..1.5, split_range: 0.75..1.5,
branch_len_bias: 0.0, branch_len_bias: 0.0,
leaf_vertical_scale: 1.0, leaf_vertical_scale: 1.0,
@ -308,11 +318,11 @@ impl TreeConfig {
trunk_radius: 4.0 * scale, trunk_radius: 4.0 * scale,
branch_child_len: 0.9, branch_child_len: 0.9,
branch_child_radius: 0.7, branch_child_radius: 0.7,
leaf_radius: 1.5 * log_scale..2.0 * log_scale, leaf_radius: 2.25 * log_scale..3.5 * log_scale,
straightness: 0.4, straightness: 0.5,
max_depth: (6.0 + log_scale) as usize, max_depth: (7.0 + log_scale) as usize,
splits: 1.8..3.0, splits: 1.5..2.75,
split_range: 0.8..1.5, split_range: 1.0..1.1,
branch_len_bias: 0.0, branch_len_bias: 0.0,
leaf_vertical_scale: 1.0, leaf_vertical_scale: 1.0,
proportionality: 0.0, proportionality: 0.0,

View File

@ -286,7 +286,7 @@ impl World {
chunk: &mut chunk, chunk: &mut chunk,
}; };
layer::apply_trees_to(&mut canvas); layer::apply_trees_to(&mut canvas, &mut dynamic_rng);
layer::apply_scatter_to(&mut canvas, &mut dynamic_rng); layer::apply_scatter_to(&mut canvas, &mut dynamic_rng);
layer::apply_caves_to(&mut canvas, &mut dynamic_rng); layer::apply_caves_to(&mut canvas, &mut dynamic_rng);
layer::apply_paths_to(&mut canvas); layer::apply_paths_to(&mut canvas);

View File

@ -2026,10 +2026,12 @@ impl WorldSim {
}); });
let giant_trees = std::array::IntoIter::new(self.gen_ctx.big_structure_gen.get(wpos)) let giant_trees = std::array::IntoIter::new(self.gen_ctx.big_structure_gen.get(wpos))
// Don't even consider trees if we aren't close
.filter(move |(pos, _)| pos.distance_squared(wpos) < 256i32.pow(2))
.map(move |(pos, seed)| TreeAttr { .map(move |(pos, seed)| TreeAttr {
pos, pos,
seed, seed,
scale: 5.0, scale: 4.0,
forest_kind: ForestKind::Giant, forest_kind: ForestKind::Giant,
}); });