mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fixed clipping issues, faster generation
This commit is contained in:
parent
f472e88c6d
commit
c69a91804d
@ -34,7 +34,9 @@ make_case_elim!(
|
|||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum StructureError {}
|
pub enum StructureError {
|
||||||
|
OutOfBounds,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Structure {
|
pub struct Structure {
|
||||||
@ -109,7 +111,7 @@ impl ReadVol for Structure {
|
|||||||
fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, StructureError> {
|
fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, StructureError> {
|
||||||
match self.base.vol.get(pos + self.center) {
|
match self.base.vol.get(pos + self.center) {
|
||||||
Ok(block) => Ok(block),
|
Ok(block) => Ok(block),
|
||||||
Err(DynaError::OutOfBounds) => Ok(&self.base.empty),
|
Err(DynaError::OutOfBounds) => Err(StructureError::OutOfBounds),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,12 +128,14 @@ pub fn apply_trees_to(canvas: &mut Canvas) {
|
|||||||
TreeModel::Procedural(t) => t.get_bounds().map(|e| e as i32),
|
TreeModel::Procedural(t) => t.get_bounds().map(|e| e as i32),
|
||||||
};
|
};
|
||||||
|
|
||||||
tracing::info!("{:?}", bounds);
|
let rpos2d = (wpos2d - tree.pos.xy())
|
||||||
|
.map2(Vec2::new(tree.units.0, tree.units.1), |p, unit| {
|
||||||
// if !Aabr::from(bounds).contains_point(wpos2d - tree.pos.xy()) {
|
unit * p
|
||||||
if bounds.min.x + tree.pos.x < wpos2d.x || bounds.min.y + tree.pos.y < wpos2d.y || bounds.max.x + tree.pos.x > wpos2d.x || bounds.max.y + tree.pos.y > wpos2d.y {
|
})
|
||||||
|
.sum();
|
||||||
|
if !Aabr::from(bounds).contains_point(rpos2d) {
|
||||||
// Skip this column
|
// Skip this column
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut is_top = true;
|
let mut is_top = true;
|
||||||
@ -152,18 +154,15 @@ 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) => if t.is_branch_at(model_pos.map(|e| e as f32 + 0.5)) {
|
TreeModel::Procedural(t) => Some(match t.is_branch_or_leaves_at(model_pos.map(|e| e as f32 + 0.5)) {
|
||||||
Some(StructureBlock::Normal(Rgb::new(60, 30, 0)))
|
(true, _) => StructureBlock::Normal(Rgb::new(60, 30, 0)),
|
||||||
} else if t.is_leaves_at(model_pos.map(|e| e as f32 + 0.5)) {
|
(_, true) => StructureBlock::TemperateLeaves,
|
||||||
Some(StructureBlock::TemperateLeaves)
|
(_, _) => StructureBlock::None,
|
||||||
} else {
|
}),
|
||||||
Some(StructureBlock::None)
|
|
||||||
},
|
|
||||||
} {
|
} {
|
||||||
block
|
block
|
||||||
} else {
|
} else {
|
||||||
//break;
|
break
|
||||||
StructureBlock::None
|
|
||||||
},
|
},
|
||||||
wpos,
|
wpos,
|
||||||
tree.pos.xy(),
|
tree.pos.xy(),
|
||||||
@ -204,16 +203,16 @@ impl ProceduralTree {
|
|||||||
let mut branches = Vec::new();
|
let mut branches = Vec::new();
|
||||||
|
|
||||||
fn add_branches(branches: &mut Vec<Branch>, rng: &mut impl Rng, start: Vec3<f32>, dir: Vec3<f32>, depth: usize) {
|
fn add_branches(branches: &mut Vec<Branch>, rng: &mut impl Rng, start: Vec3<f32>, dir: Vec3<f32>, depth: usize) {
|
||||||
let branch_dir = (dir + Vec3::<f32>::zero().map(|_| rng.gen_range(-1.0, 1.0)) * 0.65).normalized(); // I wish `vek` had a `Vec3::from_fn`
|
let branch_dir = (dir + Vec3::<f32>::zero().map(|_| rng.gen_range(-1.0, 1.0)).cross(dir).normalized() * 0.45 * (depth as f32 + 0.5)).normalized(); // I wish `vek` had a `Vec3::from_fn`
|
||||||
let branch_len = 15.0 / (depth as f32 * 0.25 + 1.0); // Zipf, I guess
|
let branch_len = 12.0 / (depth as f32 * 0.25 + 1.0); // Zipf, I guess
|
||||||
|
|
||||||
let end = start + branch_dir * branch_len;
|
let end = start + branch_dir * branch_len;
|
||||||
|
|
||||||
branches.push(Branch {
|
branches.push(Branch {
|
||||||
line: LineSegment3 { start, end },
|
line: LineSegment3 { start, end },
|
||||||
radius: 0.3 + 3.5 / (depth + 1) as f32,
|
radius: 0.3 + 2.5 / (depth + 1) as f32,
|
||||||
health: if depth > 2 {
|
health: if depth == 4 {
|
||||||
1.5
|
2.0
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
},
|
},
|
||||||
@ -234,48 +233,33 @@ impl ProceduralTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_bounds(&self) -> Aabb<f32> {
|
pub fn get_bounds(&self) -> Aabb<f32> {
|
||||||
self.branches
|
let bounds = self.branches
|
||||||
.iter()
|
.iter()
|
||||||
.fold(
|
.fold(Aabb::default(), |Aabb { min, max }, branch| Aabb {
|
||||||
Aabb {
|
|
||||||
min: Vec3::broadcast(f32::MAX),
|
|
||||||
max: Vec3::broadcast(f32::MIN),
|
|
||||||
},
|
|
||||||
|Aabb { min, max }, branch| Aabb {
|
|
||||||
min: Vec3::partial_min(min, Vec3::partial_min(branch.line.start, branch.line.end) - branch.radius - 8.0),
|
min: Vec3::partial_min(min, Vec3::partial_min(branch.line.start, branch.line.end) - branch.radius - 8.0),
|
||||||
max: Vec3::partial_max(max, Vec3::partial_max(branch.line.start, branch.line.end) + branch.radius + 8.0),
|
max: Vec3::partial_max(max, Vec3::partial_max(branch.line.start, branch.line.end) + branch.radius + 8.0),
|
||||||
},
|
});
|
||||||
)
|
|
||||||
// Aabb {
|
self.branches
|
||||||
// min: Vec3::new(-32.0, -32.0, 0.0),
|
.iter()
|
||||||
// max: Vec3::new(32.0, 32.0, 64.0),
|
.for_each(|branch| {
|
||||||
// }
|
assert!(bounds.contains_point(branch.line.start));
|
||||||
|
assert!(bounds.contains_point(branch.line.end));
|
||||||
|
});
|
||||||
|
|
||||||
|
bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_branch_at(&self, pos: Vec3<f32>) -> bool {
|
pub fn is_branch_or_leaves_at(&self, pos: Vec3<f32>) -> (bool, bool) {
|
||||||
// TODO: Something visually nicer than this
|
let mut is_branch = false;
|
||||||
self.branches.iter().any(|branch| {
|
let mut health = 0.0;
|
||||||
branch.line.projected_point(pos).distance_squared(pos) < branch.radius.powi(2)
|
for branch in &self.branches {
|
||||||
// let mut a = branch.line.start;
|
let p_d2 = branch.line.projected_point(pos).distance_squared(pos);
|
||||||
// let mut b = branch.line.end;
|
|
||||||
// for _ in 0..10 {
|
|
||||||
// if a.distance_squared(pos) < b.distance_squared(pos) {
|
|
||||||
// b = (a + b) / 2.0;
|
|
||||||
// } else {
|
|
||||||
// a = (a + b) / 2.0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// let near = (a + b) / 2.0;
|
|
||||||
// near.distance(pos) < branch.radius
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_leaves_at(&self, pos: Vec3<f32>) -> bool {
|
is_branch |= p_d2 < branch.radius.powi(2);
|
||||||
self.branches.iter()
|
health += branch.health / (p_d2 + 0.001);
|
||||||
.map(|branch| {
|
}
|
||||||
branch.health / (branch.line.projected_point(pos).distance_squared(pos) + 0.001)
|
(is_branch, health > 1.0)
|
||||||
})
|
|
||||||
.sum::<f32>() > 1.0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user