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,
|
GreenSludge: None,
|
||||||
// Leaves all actually get interpolated.
|
// Leaves all actually get interpolated.
|
||||||
TemperateLeaves: [
|
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: (178, 216, 0), end: (255, 185, 63)),
|
||||||
//(start: (142, 164, 0), end: (142, 164, 0)),
|
//(start: (142, 164, 0), end: (142, 164, 0)),
|
||||||
//(start: (168, 81, 0), end: (54, 150, 31)),
|
//(start: (168, 81, 0), end: (54, 150, 31)),
|
||||||
@ -26,9 +26,11 @@
|
|||||||
PineLeaves: [(start: (0, 60, 50), end: (30, 80, 10))],
|
PineLeaves: [(start: (0, 60, 50), end: (30, 80, 10))],
|
||||||
PalmLeavesInner: [(start: (70, 140, 43), end: (55, 140, 32))],
|
PalmLeavesInner: [(start: (70, 140, 43), end: (55, 140, 32))],
|
||||||
PalmLeavesOuter: [(start: (60, 130, 38), end: (30, 130, 65))],
|
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))],
|
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
|
// 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,
|
Log = 16,
|
||||||
Filled(kind: BlockKind, color: Rgb<u8>) = 17,
|
Filled(kind: BlockKind, color: Rgb<u8>) = 17,
|
||||||
Sprite(kind: SpriteKind) = 18,
|
Sprite(kind: SpriteKind) = 18,
|
||||||
|
Chestnut = 19,
|
||||||
|
Baobab = 20,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ pub enum ForestKind {
|
|||||||
Acacia,
|
Acacia,
|
||||||
Baobab,
|
Baobab,
|
||||||
Oak,
|
Oak,
|
||||||
|
Chestnut,
|
||||||
|
Cedar,
|
||||||
Pine,
|
Pine,
|
||||||
Birch,
|
Birch,
|
||||||
Mangrove,
|
Mangrove,
|
||||||
@ -29,6 +31,8 @@ impl ForestKind {
|
|||||||
ForestKind::Acacia => 0.05..0.55,
|
ForestKind::Acacia => 0.05..0.55,
|
||||||
ForestKind::Baobab => 0.2..0.6,
|
ForestKind::Baobab => 0.2..0.6,
|
||||||
ForestKind::Oak => 0.35..1.5,
|
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::Pine => 0.2..1.4,
|
||||||
ForestKind::Birch => 0.0..0.6,
|
ForestKind::Birch => 0.0..0.6,
|
||||||
ForestKind::Mangrove => 0.65..1.3,
|
ForestKind::Mangrove => 0.65..1.3,
|
||||||
@ -42,7 +46,9 @@ impl ForestKind {
|
|||||||
ForestKind::Palm => 0.4..1.6,
|
ForestKind::Palm => 0.4..1.6,
|
||||||
ForestKind::Acacia => 0.3..1.6,
|
ForestKind::Acacia => 0.3..1.6,
|
||||||
ForestKind::Baobab => 0.4..0.9,
|
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::Pine => -1.8..-0.2,
|
||||||
ForestKind::Birch => -0.7..0.25,
|
ForestKind::Birch => -0.7..0.25,
|
||||||
ForestKind::Mangrove => 0.4..1.6,
|
ForestKind::Mangrove => 0.4..1.6,
|
||||||
@ -66,9 +72,11 @@ impl ForestKind {
|
|||||||
ForestKind::Acacia => 0.6,
|
ForestKind::Acacia => 0.6,
|
||||||
ForestKind::Baobab => 0.2,
|
ForestKind::Baobab => 0.2,
|
||||||
ForestKind::Oak => 1.0,
|
ForestKind::Oak => 1.0,
|
||||||
|
ForestKind::Chestnut => 0.3,
|
||||||
|
ForestKind::Cedar => 0.3,
|
||||||
ForestKind::Pine => 1.0,
|
ForestKind::Pine => 1.0,
|
||||||
ForestKind::Birch => 0.65,
|
ForestKind::Birch => 0.65,
|
||||||
ForestKind::Mangrove => 1.0,
|
ForestKind::Mangrove => 2.0,
|
||||||
ForestKind::Swamp => 1.0,
|
ForestKind::Swamp => 1.0,
|
||||||
_ => 0.0,
|
_ => 0.0,
|
||||||
}
|
}
|
||||||
|
@ -289,7 +289,9 @@ pub fn block_from_structure(
|
|||||||
| StructureBlock::PalmLeavesInner
|
| StructureBlock::PalmLeavesInner
|
||||||
| StructureBlock::PalmLeavesOuter
|
| StructureBlock::PalmLeavesOuter
|
||||||
| StructureBlock::Acacia
|
| StructureBlock::Acacia
|
||||||
| StructureBlock::Mangrove => {
|
| StructureBlock::Mangrove
|
||||||
|
| StructureBlock::Chestnut
|
||||||
|
| StructureBlock::Baobab => {
|
||||||
let ranges = sblock
|
let ranges = sblock
|
||||||
.elim_case_pure(&index.colors.block.structure_blocks)
|
.elim_case_pure(&index.colors.block.structure_blocks)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -95,8 +95,26 @@ pub fn apply_trees_to(canvas: &mut Canvas, dynamic_rng: &mut impl Rng) {
|
|||||||
*FRUIT_TREES
|
*FRUIT_TREES
|
||||||
},
|
},
|
||||||
ForestKind::Palm => *PALMS,
|
ForestKind::Palm => *PALMS,
|
||||||
ForestKind::Acacia => *ACACIAS,
|
ForestKind::Acacia => {
|
||||||
ForestKind::Baobab => *BAOBABS,
|
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 => *OAKS,
|
||||||
ForestKind::Oak => {
|
ForestKind::Oak => {
|
||||||
break 'model TreeModel::Procedural(
|
break 'model TreeModel::Procedural(
|
||||||
@ -107,6 +125,15 @@ pub fn apply_trees_to(canvas: &mut Canvas, dynamic_rng: &mut impl Rng) {
|
|||||||
StructureBlock::TemperateLeaves,
|
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 => *PINES,
|
||||||
ForestKind::Pine => {
|
ForestKind::Pine => {
|
||||||
break 'model TreeModel::Procedural(
|
break 'model TreeModel::Procedural(
|
||||||
@ -117,8 +144,26 @@ pub fn apply_trees_to(canvas: &mut Canvas, dynamic_rng: &mut impl Rng) {
|
|||||||
StructureBlock::PineLeaves,
|
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::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::Swamp => *SWAMP_TREES,
|
||||||
ForestKind::Giant => {
|
ForestKind::Giant => {
|
||||||
break 'model TreeModel::Procedural(
|
break 'model TreeModel::Procedural(
|
||||||
@ -164,6 +209,11 @@ pub fn apply_trees_to(canvas: &mut Canvas, dynamic_rng: &mut impl Rng) {
|
|||||||
continue;
|
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_top = true;
|
||||||
let mut is_leaf_top = true;
|
let mut is_leaf_top = true;
|
||||||
let mut last_block = Block::empty();
|
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;
|
last_block = block;
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
if last_block.kind() == BlockKind::Wood && dynamic_rng.gen_range(0..2048) == 0 {
|
// Hanging sprites
|
||||||
canvas.set(wpos, Block::air(SpriteKind::Beehive));
|
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;
|
is_leaf_top = true;
|
||||||
@ -282,11 +337,12 @@ pub struct TreeConfig {
|
|||||||
pub proportionality: f32,
|
pub proportionality: f32,
|
||||||
/// Whether the tree is inhabited (adds various features and effects)
|
/// Whether the tree is inhabited (adds various features and effects)
|
||||||
pub inhabited: bool,
|
pub inhabited: bool,
|
||||||
|
pub hanging_sprites: &'static [(f32, SpriteKind)],
|
||||||
}
|
}
|
||||||
|
|
||||||
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 * (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);
|
let log_scale = 1.0 + scale.log2().max(0.0);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -305,6 +361,127 @@ impl TreeConfig {
|
|||||||
leaf_vertical_scale: 1.0,
|
leaf_vertical_scale: 1.0,
|
||||||
proportionality: 0.0,
|
proportionality: 0.0,
|
||||||
inhabited: false,
|
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,
|
leaf_vertical_scale: 0.3,
|
||||||
proportionality: 1.0,
|
proportionality: 1.0,
|
||||||
inhabited: false,
|
inhabited: false,
|
||||||
|
hanging_sprites: &[(0.0005, SpriteKind::Beehive)],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,6 +528,7 @@ impl TreeConfig {
|
|||||||
leaf_vertical_scale: 0.6,
|
leaf_vertical_scale: 0.6,
|
||||||
proportionality: 0.0,
|
proportionality: 0.0,
|
||||||
inhabited,
|
inhabited,
|
||||||
|
hanging_sprites: &[(0.0005, SpriteKind::Beehive)],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,7 +645,7 @@ impl ProceduralTree {
|
|||||||
// Now, interpolate between the target direction and the parent branch's
|
// Now, interpolate between the target direction and the parent branch's
|
||||||
// direction to find a direction
|
// direction to find a direction
|
||||||
let branch_dir =
|
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(
|
let (branch_idx, branch_aabb) = self.add_branch(
|
||||||
config,
|
config,
|
||||||
|
Loading…
Reference in New Issue
Block a user