mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Procedural pines (first attempt), more tree parameters
This commit is contained in:
parent
24773afe76
commit
953d8841b4
@ -41,7 +41,7 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
|
|||||||
// TODO: Get rid of this
|
// TODO: Get rid of this
|
||||||
enum TreeModel {
|
enum TreeModel {
|
||||||
Structure(Structure),
|
Structure(Structure),
|
||||||
Procedural(ProceduralTree),
|
Procedural(ProceduralTree, StructureBlock),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Tree {
|
struct Tree {
|
||||||
@ -99,10 +99,15 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
|
|||||||
ForestKind::Acacia => *ACACIAS,
|
ForestKind::Acacia => *ACACIAS,
|
||||||
ForestKind::Baobab => *BAOBABS,
|
ForestKind::Baobab => *BAOBABS,
|
||||||
// ForestKind::Oak => *OAKS,
|
// ForestKind::Oak => *OAKS,
|
||||||
ForestKind::Oak => {
|
ForestKind::Oak => break 'model TreeModel::Procedural(
|
||||||
break 'model TreeModel::Procedural(ProceduralTree::generate(TreeConfig::OAK, seed));
|
ProceduralTree::generate(TreeConfig::OAK, seed),
|
||||||
},
|
StructureBlock::TemperateLeaves,
|
||||||
ForestKind::Pine => *PINES,
|
),
|
||||||
|
//ForestKind::Pine => *PINES,
|
||||||
|
ForestKind::Pine => break 'model TreeModel::Procedural(
|
||||||
|
ProceduralTree::generate(TreeConfig::PINE, seed),
|
||||||
|
StructureBlock::PineLeaves,
|
||||||
|
),
|
||||||
ForestKind::Birch => *BIRCHES,
|
ForestKind::Birch => *BIRCHES,
|
||||||
ForestKind::Mangrove => *MANGROVE_TREES,
|
ForestKind::Mangrove => *MANGROVE_TREES,
|
||||||
ForestKind::Swamp => *SWAMP_TREES,
|
ForestKind::Swamp => *SWAMP_TREES,
|
||||||
@ -124,7 +129,7 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
|
|||||||
|
|
||||||
let bounds = match &tree.model {
|
let bounds = match &tree.model {
|
||||||
TreeModel::Structure(s) => s.get_bounds(),
|
TreeModel::Structure(s) => s.get_bounds(),
|
||||||
TreeModel::Procedural(t) => t.get_bounds().map(|e| e as i32),
|
TreeModel::Procedural(t, _) => t.get_bounds().map(|e| e as i32),
|
||||||
};
|
};
|
||||||
|
|
||||||
let rpos2d = (wpos2d - tree.pos.xy())
|
let rpos2d = (wpos2d - tree.pos.xy())
|
||||||
@ -153,9 +158,9 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
|
|||||||
info.index(),
|
info.index(),
|
||||||
if let Some(block) = match &tree.model {
|
if let Some(block) = match &tree.model {
|
||||||
TreeModel::Structure(s) => s.get(model_pos).ok().copied(),
|
TreeModel::Structure(s) => s.get(model_pos).ok().copied(),
|
||||||
TreeModel::Procedural(t) => Some(match t.is_branch_or_leaves_at(model_pos.map(|e| e as f32 + 0.5)) {
|
TreeModel::Procedural(t, leaf_block) => Some(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::Normal(Rgb::new(60, 30, 0)),
|
||||||
(_, true) => StructureBlock::TemperateLeaves,
|
(_, true) => *leaf_block,
|
||||||
(_, _) => StructureBlock::None,
|
(_, _) => StructureBlock::None,
|
||||||
}),
|
}),
|
||||||
} {
|
} {
|
||||||
@ -198,10 +203,12 @@ pub struct TreeConfig {
|
|||||||
pub trunk_len: f32,
|
pub trunk_len: f32,
|
||||||
/// Radius of trunk, also scales other branches.
|
/// Radius of trunk, also scales other branches.
|
||||||
pub trunk_radius: f32,
|
pub trunk_radius: f32,
|
||||||
// The scale that child branch lengths should be compared to their parents
|
// The scale that child branch lengths should be compared to their parents.
|
||||||
pub branch_child_len: f32,
|
pub branch_child_len: f32,
|
||||||
// The scale that child branch radii should be compared to their parents
|
// The scale that child branch radii should be compared to their parents.
|
||||||
pub branch_child_radius: f32,
|
pub branch_child_radius: f32,
|
||||||
|
/// The range of radii that leaf-emitting branches might have.
|
||||||
|
pub leaf_radius: Range<f32>,
|
||||||
/// 0 - 1 (0 = chaotic, 1 = straight).
|
/// 0 - 1 (0 = chaotic, 1 = straight).
|
||||||
pub straightness: f32,
|
pub straightness: f32,
|
||||||
/// Maximum number of branch layers (not including trunk).
|
/// Maximum number of branch layers (not including trunk).
|
||||||
@ -211,6 +218,11 @@ pub struct TreeConfig {
|
|||||||
/// The range of proportions along a branch at which a split into another branch might occur.
|
/// The range of proportions along a branch at which a split into another branch might occur.
|
||||||
/// This value is clamped between 0 and 1, but a wider range may bias the results towards branch ends.
|
/// This value is clamped between 0 and 1, but a wider range may bias the results towards branch ends.
|
||||||
pub split_range: Range<f32>,
|
pub split_range: Range<f32>,
|
||||||
|
/// The bias applied to the length of branches based on the proportion along their parent that they eminate from.
|
||||||
|
/// -1.0 = negative bias (branches at ends are longer, branches at the start are shorter)
|
||||||
|
/// 0.0 = no bias (branches do not change their length with regard to parent branch proportion)
|
||||||
|
/// 1.0 = positive bias (branches at ends are shorter, branches at the start are longer)
|
||||||
|
pub branch_len_bias: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TreeConfig {
|
impl TreeConfig {
|
||||||
@ -219,10 +231,25 @@ impl TreeConfig {
|
|||||||
trunk_radius: 3.0,
|
trunk_radius: 3.0,
|
||||||
branch_child_len: 0.8,
|
branch_child_len: 0.8,
|
||||||
branch_child_radius: 0.6,
|
branch_child_radius: 0.6,
|
||||||
|
leaf_radius: 3.0..5.0,
|
||||||
straightness: 0.5,
|
straightness: 0.5,
|
||||||
max_depth: 4,
|
max_depth: 4,
|
||||||
splits: 3,
|
splits: 3,
|
||||||
split_range: 0.5..1.5,
|
split_range: 0.5..1.5,
|
||||||
|
branch_len_bias: 0.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PINE: Self = Self {
|
||||||
|
trunk_len: 32.0,
|
||||||
|
trunk_radius: 1.5,
|
||||||
|
branch_child_len: 0.3,
|
||||||
|
branch_child_radius: 0.0,
|
||||||
|
leaf_radius: 1.0..1.25,
|
||||||
|
straightness: 0.0,
|
||||||
|
max_depth: 1,
|
||||||
|
splits: 128,
|
||||||
|
split_range: 0.2..1.1,
|
||||||
|
branch_len_bias: 0.8,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +304,11 @@ impl ProceduralTree {
|
|||||||
let end = start + dir * branch_len;
|
let end = start + dir * branch_len;
|
||||||
let line = LineSegment3 { start, end };
|
let line = LineSegment3 { start, end };
|
||||||
let wood_radius = branch_radius;
|
let wood_radius = branch_radius;
|
||||||
let leaf_radius = if depth == config.max_depth { rng.gen_range(3.0, 5.0) } else { 0.0 };
|
let leaf_radius = if depth == config.max_depth {
|
||||||
|
rng.gen_range(config.leaf_radius.start, config.leaf_radius.end)
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
|
||||||
// The AABB that covers this branch, along with wood and leaves that eminate from it
|
// The AABB that covers this branch, along with wood and leaves that eminate from it
|
||||||
let mut aabb = Aabb {
|
let mut aabb = Aabb {
|
||||||
@ -290,10 +321,11 @@ impl ProceduralTree {
|
|||||||
if depth < config.max_depth {
|
if depth < config.max_depth {
|
||||||
for _ in 0..config.splits {
|
for _ in 0..config.splits {
|
||||||
// Choose a point close to the branch to act as the target direction for the branch to grow in
|
// Choose a point close to the branch to act as the target direction for the branch to grow in
|
||||||
|
let split_factor = rng.gen_range(config.split_range.start, config.split_range.end).clamped(0.0, 1.0);
|
||||||
let tgt = Lerp::lerp(
|
let tgt = Lerp::lerp(
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
rng.gen_range(config.split_range.start, config.split_range.end).clamped(0.0, 1.0),
|
split_factor,
|
||||||
) + Vec3::<f32>::zero().map(|_| rng.gen_range(-1.0, 1.0));
|
) + Vec3::<f32>::zero().map(|_| rng.gen_range(-1.0, 1.0));
|
||||||
// Start the branch at the closest point to the target
|
// Start the branch at the closest point to the target
|
||||||
let branch_start = line.projected_point(tgt);
|
let branch_start = line.projected_point(tgt);
|
||||||
@ -304,7 +336,9 @@ impl ProceduralTree {
|
|||||||
config,
|
config,
|
||||||
branch_start,
|
branch_start,
|
||||||
branch_dir,
|
branch_dir,
|
||||||
branch_len * config.branch_child_len,
|
branch_len
|
||||||
|
* config.branch_child_len
|
||||||
|
* (1.0 - (split_factor - 0.5) * 2.0 * config.branch_len_bias.clamped(-1.0, 1.0)),
|
||||||
branch_radius * config.branch_child_radius,
|
branch_radius * config.branch_child_radius,
|
||||||
depth + 1,
|
depth + 1,
|
||||||
child_idx,
|
child_idx,
|
||||||
|
Loading…
Reference in New Issue
Block a user