mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
More tree variety
This commit is contained in:
parent
4a9641cf44
commit
0011e75526
@ -18,7 +18,7 @@
|
||||
GreenSludge: None,
|
||||
// Leaves all actually get interpolated.
|
||||
TemperateLeaves: [
|
||||
(start: (0, 100, 50), end: (105, 175, 0)),
|
||||
(start: (20, 100, 40), end: (60, 120, 0)),
|
||||
//(start: (178, 216, 0), end: (255, 185, 63)),
|
||||
//(start: (142, 164, 0), end: (142, 164, 0)),
|
||||
//(start: (168, 81, 0), end: (54, 150, 31)),
|
||||
@ -26,9 +26,11 @@
|
||||
PineLeaves: [(start: (0, 60, 50), end: (30, 80, 10))],
|
||||
PalmLeavesInner: [(start: (70, 140, 43), end: (55, 140, 32))],
|
||||
PalmLeavesOuter: [(start: (60, 130, 38), end: (30, 130, 65))],
|
||||
Acacia: [(start: (30, 100, 0), end: (90, 110, 20))],
|
||||
Acacia: [(start: (35, 70, 0), end: (100, 120, 30))],
|
||||
Liana: [(start: (0, 125, 107), end: (0, 155, 129))],
|
||||
Mangrove: [(start: (15, 80, 10), end: (20, 120, 47))],
|
||||
Mangrove: [(start: (20, 60, 0), end: (40, 90, 30))],
|
||||
Chestnut: [(start: (30, 80, 0), end: (50, 120, 0))],
|
||||
Baobab: [(start: (50, 100, 40), end: (50, 90, 0))],
|
||||
)
|
||||
|
||||
// Water blocks ignore color now so this isn't used, but just in case this color was worth
|
||||
|
@ -34,6 +34,8 @@ make_case_elim!(
|
||||
Log = 16,
|
||||
Filled(kind: BlockKind, color: Rgb<u8>) = 17,
|
||||
Sprite(kind: SpriteKind) = 18,
|
||||
Chestnut = 19,
|
||||
Baobab = 20,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -9,6 +9,8 @@ pub enum ForestKind {
|
||||
Acacia,
|
||||
Baobab,
|
||||
Oak,
|
||||
Chestnut,
|
||||
Cedar,
|
||||
Pine,
|
||||
Birch,
|
||||
Mangrove,
|
||||
@ -29,6 +31,8 @@ impl ForestKind {
|
||||
ForestKind::Acacia => 0.05..0.55,
|
||||
ForestKind::Baobab => 0.2..0.6,
|
||||
ForestKind::Oak => 0.35..1.5,
|
||||
ForestKind::Chestnut => 0.35..1.5,
|
||||
ForestKind::Cedar => 0.275..1.45,
|
||||
ForestKind::Pine => 0.2..1.4,
|
||||
ForestKind::Birch => 0.0..0.6,
|
||||
ForestKind::Mangrove => 0.65..1.3,
|
||||
@ -42,7 +46,9 @@ impl ForestKind {
|
||||
ForestKind::Palm => 0.4..1.6,
|
||||
ForestKind::Acacia => 0.3..1.6,
|
||||
ForestKind::Baobab => 0.4..0.9,
|
||||
ForestKind::Oak => -0.35..0.6,
|
||||
ForestKind::Oak => -0.35..0.45,
|
||||
ForestKind::Chestnut => -0.35..0.45,
|
||||
ForestKind::Cedar => -1.0..0.1,
|
||||
ForestKind::Pine => -1.8..-0.2,
|
||||
ForestKind::Birch => -0.7..0.25,
|
||||
ForestKind::Mangrove => 0.4..1.6,
|
||||
@ -66,9 +72,11 @@ impl ForestKind {
|
||||
ForestKind::Acacia => 0.6,
|
||||
ForestKind::Baobab => 0.2,
|
||||
ForestKind::Oak => 1.0,
|
||||
ForestKind::Chestnut => 0.3,
|
||||
ForestKind::Cedar => 0.3,
|
||||
ForestKind::Pine => 1.0,
|
||||
ForestKind::Birch => 0.65,
|
||||
ForestKind::Mangrove => 1.0,
|
||||
ForestKind::Mangrove => 2.0,
|
||||
ForestKind::Swamp => 1.0,
|
||||
_ => 0.0,
|
||||
}
|
||||
|
@ -289,7 +289,9 @@ pub fn block_from_structure(
|
||||
| StructureBlock::PalmLeavesInner
|
||||
| StructureBlock::PalmLeavesOuter
|
||||
| StructureBlock::Acacia
|
||||
| StructureBlock::Mangrove => {
|
||||
| StructureBlock::Mangrove
|
||||
| StructureBlock::Chestnut
|
||||
| StructureBlock::Baobab => {
|
||||
let ranges = sblock
|
||||
.elim_case_pure(&index.colors.block.structure_blocks)
|
||||
.as_ref()
|
||||
|
@ -95,8 +95,26 @@ pub fn apply_trees_to(canvas: &mut Canvas, dynamic_rng: &mut impl Rng) {
|
||||
*FRUIT_TREES
|
||||
},
|
||||
ForestKind::Palm => *PALMS,
|
||||
ForestKind::Acacia => *ACACIAS,
|
||||
ForestKind::Baobab => *BAOBABS,
|
||||
ForestKind::Acacia => {
|
||||
break 'model TreeModel::Procedural(
|
||||
ProceduralTree::generate(
|
||||
TreeConfig::acacia(&mut RandomPerm::new(seed), scale),
|
||||
&mut RandomPerm::new(seed),
|
||||
),
|
||||
StructureBlock::Acacia,
|
||||
);
|
||||
},
|
||||
// ForestKind::Acacia => *ACACIAS,
|
||||
ForestKind::Baobab => {
|
||||
break 'model TreeModel::Procedural(
|
||||
ProceduralTree::generate(
|
||||
TreeConfig::baobab(&mut RandomPerm::new(seed), scale),
|
||||
&mut RandomPerm::new(seed),
|
||||
),
|
||||
StructureBlock::Baobab,
|
||||
);
|
||||
},
|
||||
// ForestKind::Baobab => *BAOBABS,
|
||||
// ForestKind::Oak => *OAKS,
|
||||
ForestKind::Oak => {
|
||||
break 'model TreeModel::Procedural(
|
||||
@ -107,6 +125,15 @@ pub fn apply_trees_to(canvas: &mut Canvas, dynamic_rng: &mut impl Rng) {
|
||||
StructureBlock::TemperateLeaves,
|
||||
);
|
||||
},
|
||||
ForestKind::Chestnut => {
|
||||
break 'model TreeModel::Procedural(
|
||||
ProceduralTree::generate(
|
||||
TreeConfig::chestnut(&mut RandomPerm::new(seed), scale),
|
||||
&mut RandomPerm::new(seed),
|
||||
),
|
||||
StructureBlock::Chestnut,
|
||||
);
|
||||
},
|
||||
//ForestKind::Pine => *PINES,
|
||||
ForestKind::Pine => {
|
||||
break 'model TreeModel::Procedural(
|
||||
@ -117,8 +144,26 @@ pub fn apply_trees_to(canvas: &mut Canvas, dynamic_rng: &mut impl Rng) {
|
||||
StructureBlock::PineLeaves,
|
||||
);
|
||||
},
|
||||
ForestKind::Cedar => {
|
||||
break 'model TreeModel::Procedural(
|
||||
ProceduralTree::generate(
|
||||
TreeConfig::cedar(&mut RandomPerm::new(seed), scale),
|
||||
&mut RandomPerm::new(seed),
|
||||
),
|
||||
StructureBlock::PineLeaves,
|
||||
);
|
||||
},
|
||||
ForestKind::Birch => *BIRCHES,
|
||||
ForestKind::Mangrove => *MANGROVE_TREES,
|
||||
// ForestKind::Mangrove => *MANGROVE_TREES,
|
||||
ForestKind::Mangrove => {
|
||||
break 'model TreeModel::Procedural(
|
||||
ProceduralTree::generate(
|
||||
TreeConfig::jungle(&mut RandomPerm::new(seed), scale),
|
||||
&mut RandomPerm::new(seed),
|
||||
),
|
||||
StructureBlock::Mangrove,
|
||||
);
|
||||
},
|
||||
ForestKind::Swamp => *SWAMP_TREES,
|
||||
ForestKind::Giant => {
|
||||
break 'model TreeModel::Procedural(
|
||||
@ -164,6 +209,11 @@ pub fn apply_trees_to(canvas: &mut Canvas, dynamic_rng: &mut impl Rng) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let hanging_sprites = match &tree.model {
|
||||
TreeModel::Structure(_) => &[(0.0004, SpriteKind::Beehive)],
|
||||
TreeModel::Procedural(t, _) => t.config.hanging_sprites,
|
||||
};
|
||||
|
||||
let mut is_top = true;
|
||||
let mut is_leaf_top = true;
|
||||
let mut last_block = Block::empty();
|
||||
@ -228,8 +278,13 @@ pub fn apply_trees_to(canvas: &mut Canvas, dynamic_rng: &mut impl Rng) {
|
||||
last_block = block;
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
if last_block.kind() == BlockKind::Wood && dynamic_rng.gen_range(0..2048) == 0 {
|
||||
canvas.set(wpos, Block::air(SpriteKind::Beehive));
|
||||
// Hanging sprites
|
||||
if last_block.is_filled() {
|
||||
for (chance, sprite) in hanging_sprites {
|
||||
if dynamic_rng.gen_bool(*chance as f64) {
|
||||
canvas.map(wpos, |block| block.with_sprite(*sprite));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is_leaf_top = true;
|
||||
@ -282,11 +337,12 @@ pub struct TreeConfig {
|
||||
pub proportionality: f32,
|
||||
/// Whether the tree is inhabited (adds various features and effects)
|
||||
pub inhabited: bool,
|
||||
pub hanging_sprites: &'static [(f32, SpriteKind)],
|
||||
}
|
||||
|
||||
impl TreeConfig {
|
||||
pub fn oak(rng: &mut impl Rng, scale: f32) -> Self {
|
||||
let scale = scale * (0.8 + rng.gen::<f32>().powi(4) * 0.75);
|
||||
let scale = scale * (0.8 + rng.gen::<f32>().powi(2) * 0.5);
|
||||
let log_scale = 1.0 + scale.log2().max(0.0);
|
||||
|
||||
Self {
|
||||
@ -305,6 +361,127 @@ impl TreeConfig {
|
||||
leaf_vertical_scale: 1.0,
|
||||
proportionality: 0.0,
|
||||
inhabited: false,
|
||||
hanging_sprites: &[(0.0005, SpriteKind::Beehive)],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn jungle(rng: &mut impl Rng, scale: f32) -> Self {
|
||||
let scale = scale * (0.9 + rng.gen::<f32>().powi(4) * 1.0);
|
||||
let log_scale = 1.0 + scale.log2().max(0.0);
|
||||
|
||||
Self {
|
||||
trunk_len: 44.0 * scale,
|
||||
trunk_radius: 2.25 * scale,
|
||||
branch_child_len: 0.35,
|
||||
branch_child_radius: 0.5,
|
||||
branch_child_radius_lerp: true,
|
||||
leaf_radius: 4.0 * log_scale..4.5 * log_scale,
|
||||
leaf_radius_scaled: 0.0,
|
||||
straightness: 0.2,
|
||||
max_depth: 2,
|
||||
splits: 7.5..8.5,
|
||||
split_range: 0.3..1.25,
|
||||
branch_len_bias: 0.5,
|
||||
leaf_vertical_scale: 0.4,
|
||||
proportionality: 0.8,
|
||||
inhabited: false,
|
||||
hanging_sprites: &[(0.00015, SpriteKind::Beehive), (0.015, SpriteKind::Liana)],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn baobab(rng: &mut impl Rng, scale: f32) -> Self {
|
||||
let scale = scale * (0.5 + rng.gen::<f32>().powi(4) * 1.0);
|
||||
let log_scale = 1.0 + scale.log2().max(0.0);
|
||||
|
||||
Self {
|
||||
trunk_len: 24.0 * scale,
|
||||
trunk_radius: 7.0 * scale,
|
||||
branch_child_len: 0.55,
|
||||
branch_child_radius: 0.3,
|
||||
branch_child_radius_lerp: true,
|
||||
leaf_radius: 2.5 * log_scale..3.0 * log_scale,
|
||||
leaf_radius_scaled: 0.0,
|
||||
straightness: 0.5,
|
||||
max_depth: 4,
|
||||
splits: 3.0..3.5,
|
||||
split_range: 0.95..1.0,
|
||||
branch_len_bias: 0.0,
|
||||
leaf_vertical_scale: 0.2,
|
||||
proportionality: 1.0,
|
||||
inhabited: false,
|
||||
hanging_sprites: &[(0.0005, SpriteKind::Beehive)],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cedar(rng: &mut impl Rng, scale: f32) -> Self {
|
||||
let scale = scale * (0.8 + rng.gen::<f32>().powi(2) * 0.5);
|
||||
let log_scale = 1.0 + scale.log2().max(0.0);
|
||||
|
||||
Self {
|
||||
trunk_len: 9.0 * scale,
|
||||
trunk_radius: 2.0 * scale,
|
||||
branch_child_len: 0.9,
|
||||
branch_child_radius: 0.75,
|
||||
branch_child_radius_lerp: true,
|
||||
leaf_radius: 4.0 * log_scale..5.0 * log_scale,
|
||||
leaf_radius_scaled: 0.0,
|
||||
straightness: 0.55,
|
||||
max_depth: 4,
|
||||
splits: 1.75..2.0,
|
||||
split_range: 0.75..1.5,
|
||||
branch_len_bias: 0.0,
|
||||
leaf_vertical_scale: 0.2,
|
||||
proportionality: 0.0,
|
||||
inhabited: false,
|
||||
hanging_sprites: &[(0.0005, SpriteKind::Beehive)],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn acacia(rng: &mut impl Rng, scale: f32) -> Self {
|
||||
let scale = scale * (0.9 + rng.gen::<f32>().powi(4) * 0.3);
|
||||
let log_scale = 1.0 + scale.log2().max(0.0);
|
||||
|
||||
Self {
|
||||
trunk_len: 12.0 * scale,
|
||||
trunk_radius: 1.5 * scale,
|
||||
branch_child_len: 0.75,
|
||||
branch_child_radius: 0.75,
|
||||
branch_child_radius_lerp: true,
|
||||
leaf_radius: 6.0 * log_scale..7.0 * log_scale,
|
||||
leaf_radius_scaled: 0.0,
|
||||
straightness: 0.3,
|
||||
max_depth: 5,
|
||||
splits: 1.75..2.25,
|
||||
split_range: 1.0..1.25,
|
||||
branch_len_bias: 0.0,
|
||||
leaf_vertical_scale: 0.15,
|
||||
proportionality: 1.0,
|
||||
inhabited: false,
|
||||
hanging_sprites: &[(0.0005, SpriteKind::Beehive)],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn chestnut(rng: &mut impl Rng, scale: f32) -> Self {
|
||||
let scale = scale * (0.85 + rng.gen::<f32>().powi(4) * 0.3);
|
||||
let log_scale = 1.0 + scale.log2().max(0.0);
|
||||
|
||||
Self {
|
||||
trunk_len: 13.0 * scale,
|
||||
trunk_radius: 1.5 * scale,
|
||||
branch_child_len: 0.75,
|
||||
branch_child_radius: 0.75,
|
||||
branch_child_radius_lerp: true,
|
||||
leaf_radius: 2.5 * log_scale..2.6 * log_scale,
|
||||
leaf_radius_scaled: 0.0,
|
||||
straightness: 0.4,
|
||||
max_depth: 5,
|
||||
splits: 3.0..3.5,
|
||||
split_range: 0.5..1.25,
|
||||
branch_len_bias: 0.0,
|
||||
leaf_vertical_scale: 0.35,
|
||||
proportionality: 0.5,
|
||||
inhabited: false,
|
||||
hanging_sprites: &[(0.0005, SpriteKind::Beehive)],
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,6 +505,7 @@ impl TreeConfig {
|
||||
leaf_vertical_scale: 0.3,
|
||||
proportionality: 1.0,
|
||||
inhabited: false,
|
||||
hanging_sprites: &[(0.0005, SpriteKind::Beehive)],
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,6 +528,7 @@ impl TreeConfig {
|
||||
leaf_vertical_scale: 0.6,
|
||||
proportionality: 0.0,
|
||||
inhabited,
|
||||
hanging_sprites: &[(0.0005, SpriteKind::Beehive)],
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -466,7 +645,7 @@ impl ProceduralTree {
|
||||
// Now, interpolate between the target direction and the parent branch's
|
||||
// direction to find a direction
|
||||
let branch_dir =
|
||||
Lerp::lerp(tgt - branch_start, dir, config.straightness).normalized();
|
||||
Lerp::lerp_unclamped(tgt - branch_start, dir, config.straightness).normalized();
|
||||
|
||||
let (branch_idx, branch_aabb) = self.add_branch(
|
||||
config,
|
||||
|
Loading…
Reference in New Issue
Block a user