mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add new primitive to draw giant trees
This commit is contained in:
parent
c23e96f979
commit
8359d5754a
@ -52,10 +52,12 @@ pub enum Primitive {
|
||||
degree: f32,
|
||||
},
|
||||
Plane(Aabr<i32>, Vec3<i32>, Vec2<f32>),
|
||||
/// A line segment from start to finish point with a given radius
|
||||
/// A line segment from start to finish point with a given radius for both
|
||||
/// points
|
||||
Segment {
|
||||
segment: LineSegment3<f32>,
|
||||
radius: f32,
|
||||
r0: f32,
|
||||
r1: f32,
|
||||
},
|
||||
/// A prism created by projecting a line segment with a given radius along
|
||||
/// the z axis up to a provided height
|
||||
@ -117,10 +119,11 @@ impl std::fmt::Debug for Primitive {
|
||||
.field(&origin)
|
||||
.field(&gradient)
|
||||
.finish(),
|
||||
Primitive::Segment { segment, radius } => f
|
||||
Primitive::Segment { segment, r0, r1 } => f
|
||||
.debug_tuple("Segment")
|
||||
.field(&segment)
|
||||
.field(&radius)
|
||||
.field(&r0)
|
||||
.field(&r1)
|
||||
.finish(),
|
||||
Primitive::SegmentPrism {
|
||||
segment,
|
||||
@ -333,8 +336,13 @@ impl Fill {
|
||||
.as_()
|
||||
.dot(*gradient) as i32)
|
||||
},
|
||||
Primitive::Segment { segment, radius } => {
|
||||
segment.distance_to_point(pos.map(|e| e as f32)) < radius - 0.25
|
||||
// TODO: Aabb calculation could be improved here by only considering the relevant radius
|
||||
Primitive::Segment { segment, r0, r1 } => {
|
||||
let distance = segment.end - segment.start;
|
||||
let length = pos - segment.start.as_();
|
||||
let t =
|
||||
(length.as_().dot(distance) / distance.magnitude_squared()).clamped(0.0, 1.0);
|
||||
segment.distance_to_point(pos.map(|e| e as f32)) < Lerp::lerp(r0, r1, t) - 0.25
|
||||
},
|
||||
Primitive::SegmentPrism {
|
||||
segment,
|
||||
@ -507,15 +515,15 @@ impl Fill {
|
||||
};
|
||||
vec![aabb.made_valid()]
|
||||
},
|
||||
Primitive::Segment { segment, radius } => {
|
||||
Primitive::Segment { segment, r0, r1 } => {
|
||||
let aabb = Aabb {
|
||||
min: segment.start,
|
||||
max: segment.end,
|
||||
}
|
||||
.made_valid();
|
||||
vec![Aabb {
|
||||
min: (aabb.min - *radius).floor().as_(),
|
||||
max: (aabb.max + *radius).ceil().as_(),
|
||||
min: (aabb.min - r0.max(*r1)).floor().as_(),
|
||||
max: (aabb.max + r0.max(*r1)).ceil().as_(),
|
||||
}]
|
||||
},
|
||||
Primitive::SegmentPrism {
|
||||
@ -815,7 +823,27 @@ impl Painter {
|
||||
start: a.as_(),
|
||||
end: b.as_(),
|
||||
},
|
||||
radius,
|
||||
r0: radius,
|
||||
r1: radius,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a `PrimitiveRef` of a 3-dimensional line segment with two
|
||||
/// radius.
|
||||
pub fn line_two_radius(
|
||||
&self,
|
||||
a: Vec3<impl AsPrimitive<f32>>,
|
||||
b: Vec3<impl AsPrimitive<f32>>,
|
||||
r0: f32,
|
||||
r1: f32,
|
||||
) -> PrimitiveRef {
|
||||
self.prim(Primitive::Segment {
|
||||
segment: LineSegment3 {
|
||||
start: a.as_(),
|
||||
end: b.as_(),
|
||||
},
|
||||
r0,
|
||||
r1,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ impl GiantTree {
|
||||
let wpos = site.tile_center_wpos(center_tile);
|
||||
Self {
|
||||
name: format!("Tree of {}", NameGen::location(rng).generate()),
|
||||
// Find the tree's altitude
|
||||
// Get the tree's altitude
|
||||
wpos: wpos.with_z(land.get_alt_approx(wpos) as i32),
|
||||
tree: {
|
||||
let config = TreeConfig::giant(rng, 4.0, true);
|
||||
@ -48,17 +48,17 @@ impl Structure for GiantTree {
|
||||
light,
|
||||
fast_noise.get((self.wpos.map(|e| e as f64) * 0.05) * 0.5 + 0.5),
|
||||
);
|
||||
self.tree.walk(|branch, _| {
|
||||
self.tree.walk(|branch, parent| {
|
||||
let aabr = Aabr {
|
||||
min: self.wpos.xy() + branch.get_aabb().min.xy().as_(),
|
||||
max: self.wpos.xy() + branch.get_aabb().max.xy().as_(),
|
||||
};
|
||||
if aabr.collides_with_aabr(painter.render_aabr().as_()) {
|
||||
// TODO : Migrate to using Painter#line() instead
|
||||
painter
|
||||
.line(
|
||||
.line_two_radius(
|
||||
self.wpos + branch.get_line().start.as_(),
|
||||
self.wpos + branch.get_line().end.as_(),
|
||||
parent.get_wood_radius(),
|
||||
branch.get_wood_radius(),
|
||||
)
|
||||
.fill(Fill::Block(Block::new(
|
||||
@ -67,9 +67,10 @@ impl Structure for GiantTree {
|
||||
)));
|
||||
if branch.get_leaf_radius() > branch.get_wood_radius() {
|
||||
painter
|
||||
.line(
|
||||
.line_two_radius(
|
||||
self.wpos + branch.get_line().start.as_(),
|
||||
self.wpos + branch.get_line().end.as_(),
|
||||
parent.get_leaf_radius(),
|
||||
branch.get_leaf_radius(),
|
||||
)
|
||||
.fill(Fill::Block(Block::new(
|
||||
|
Loading…
Reference in New Issue
Block a user