1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
//! `bevy_flora`: parametric procedural trees that grow over time, for Bevy.
//!
//! Pipeline: [`TreeParams`] → [`generate_skeleton`] → [`Skeleton::aged`] →
//! wood mesh ([`mesh::branch::skeleton_mesh`]) + leaves
//! ([`foliage::collect_leaf_points`] / [`foliage::foliage_mesh`]) → [`MeshData`]
//! → Bevy `Mesh`. [`build_tree`] runs the whole thing; [`FloraPlugin`] drives it
//! from the [`ProceduralTree`] / [`TreeAge`] / [`Growing`] components.
//!
//! # Growing a tree in a Bevy app
//!
//! ```rust,no_run
//! use bevy::prelude::*;
//! use bevy_flora::{FloraPlugin, Growing, ProceduralTree, TreeAge, TreePreset};
//!
//! fn main() {
//! App::new()
//! .add_plugins((DefaultPlugins, FloraPlugin))
//! .add_systems(Startup, setup)
//! .run();
//! }
//!
//! fn setup(mut commands: Commands) {
//! commands.spawn((
//! ProceduralTree(TreePreset::Oak.params()),
//! TreeAge(0.0),
//! Growing::default(),
//! ));
//! }
//! ```
//!
//! # Growing a forest: [`GpuGrowth`]
//!
//! Rebuilding a growing tree's meshes costs the CPU 0.1-0.4 ms per tree per
//! frame. Add [`GpuGrowth`] and the tree is built once, at maturity, and grown in
//! the vertex shader instead (a few microseconds of CPU per tree per frame, 0.004
//! ms in the 0.4.0 measurements):
//!
//! ```rust,no_run
//! use bevy::prelude::*;
//! use bevy_flora::{FloraPlugin, GpuGrowth, Growing, ProceduralTree, TreeAge, TreePreset};
//!
//! fn setup(mut commands: Commands) {
//! for i in 0..200 {
//! commands.spawn((
//! ProceduralTree(TreePreset::Oak.params()),
//! TreeAge(0.0),
//! Growing::default(),
//! GpuGrowth,
//! Transform::from_xyz((i % 20) as f32 * 8.0, 0.0, (i / 20) as f32 * 8.0),
//! ));
//! }
//! }
//! ```
//!
//! It needs a device with storage buffers in the vertex stage (everything but
//! WebGL2; see [`GpuGrowthSupport`]); elsewhere the trees grow on the CPU.
//!
//! # Drawing a forest: [`TreePool`]
//!
//! Every [`ProceduralTree`] has meshes of its own, which a GPU draws a few thousand
//! of. For a forest build a [`TreePool`] (a few seed variants of one tree, each at
//! three levels of detail from [`build_lods`]) and place [`PooledTree`]s from it:
//! trees that share a mesh are drawn in one instanced call, the distance to the
//! camera picks the level, and beyond the last one a tree is a baked camera-facing
//! quad ([`ImpostorAtlas`]), shaded by the scene's own lights. 100 000 oaks draw at
//! 7.4 ms a frame (1080p, Apple M4 Pro).
//! Pooled trees are static; add [`FloraPlugin`] after `DefaultPlugins` to get the
//! impostors. See [`pool`] for an example.
//!
//! [`Scatter`] says where the trees of a forest stand: trunks at least a spacing apart and
//! otherwise irregular (Poisson-disc sampling), species in groves with bending borders, every
//! tree its own yaw, size and variant, and a density per spot for clearings and roads. It is
//! pure CPU and deterministic per seed; see [`scatter`].
//!
//! # Leaf shading and wind
//!
//! The plugin draws trees with [`FloraMaterial`]: a darker, glossier upper side of
//! every leaf, a paler lower side, veins and light through a leaf lit from behind
//! ([`LeafShading`]), and wind. The [`FloraWind`] resource sets the weather (a
//! [`GustFront`] sweeps a band of stronger wind across the world,
//! [`FloraWind::launch_gust`]) and [`TreeParams::wind`] ([`WindResponse`]) how each
//! species answers it.
//!
//! ```rust,no_run
//! use bevy::prelude::*;
//! use bevy_flora::{FloraWind, GustFront};
//!
//! // Call this once, when the gust begins (a system run on an event or a timer), not
//! // every frame: launching restarts the front at its origin.
//! fn start_storm(mut wind: ResMut<FloraWind>, time: Res<Time>) {
//! wind.strength = 0.6;
//! wind.launch_gust(GustFront { speed: 20.0, ..default() }, &time);
//! }
//! ```
//!
//! # Bark
//!
//! Wood wears a bundled CC0 bark scan ([`BarkScan`], chosen per species by the presets in
//! [`TreeParams::bark`]). The scan is laid out in metres on the mature tree, so a growing tree's
//! bark never slides, and [`BarkParams`] fades it in as a branch thickens: smooth wood below
//! `smooth_below` metres of radius, the whole scan above `fissured_above`. The scan's average
//! colour is divided out of the base colour, so a textured tree keeps its preset colour. The
//! images are compiled in by the default `textures` feature (about 3.6 MB with the leaf scans);
//! without it every scan is absent and wood is plain colour.
//!
//! # Leaf scans and grown veins
//!
//! A [`FoliageParams::scan`] ([`LeafScan`]) cuts leaf cards to the real outline of a bundled leaf
//! scan (one of four leaves of an atlas, by a hash of the leaf's own random draws) and the leaf
//! shader wears the atlas's colour and normal map on them. Leaves without a scan keep the
//! procedural outline and get veins grown by space colonisation ([`venation`]), drawn from one
//! small image every such leaf shares. Both need the `textures` feature only for the scans: the
//! veins are grown at run time.
//!
//! # Looks: natural, painterly, toon
//!
//! [`TreeParams::style`] ([`RenderStyle`]) changes how a tree is lit, not its shape. `Painterly`
//! gives every leaf the normal that points out of the centre of its own clump (the leaves of a
//! primary branch, the leader or a split) rather than out of the crown's, so a crown reads as
//! rounded masses with a lit and a shaded side each. `Toon` keeps those normals and cuts the
//! light of every directional light into three bands, with an ink rim toward the silhouette. The
//! pools, the impostors and `GpuGrowth` draw them all.
//!
//! # Seasons
//!
//! The [`FloraSeason`] resource turns deciduous trees ([`FoliageParams::autumn`], set on the
//! oak, willow, birch, bonsai, maple, poplar, baobab and Japanese maple presets) to their autumn
//! colour and sheds their leaves, one leaf at a time; evergreens ignore it. It shares the wind's
//! buffer, so a season that changes every frame costs no material change and nothing per tree.
//!
//! ```rust,no_run
//! use bevy::prelude::*;
//! use bevy_flora::FloraSeason;
//!
//! // A year every two minutes.
//! fn seasons(time: Res<Time>, mut season: ResMut<FloraSeason>) {
//! *season = FloraSeason::of_year(time.elapsed_secs() / 120.0);
//! }
//! ```
//!
//! # Gameplay shapes
//!
//! A [`TreeShape`] on a tree (opt-in: insert `TreeShape::default()`) is kept up to date by the
//! plugin: capsules up the trunk and along every limb thicker than its `limb_radius`, and a box
//! around the crown, in the tree's local space, for colliders, picking or line of sight.
//! [`TreeMature`] is sent once when a [`Growing`] tree reaches maturity. The [`prelude`] has the
//! types a game usually needs.
//!
//! # Building meshes without Bevy's ECS
//!
//! ```rust
//! use bevy_flora::{TreeMeshes, TreePreset, build_tree};
//!
//! let params = TreePreset::Oak.params();
//! let meshes: TreeMeshes = build_tree(¶ms, f32::INFINITY);
//! assert!(!meshes.trunk.is_empty());
//! ```
pub use CrownShape;
pub use LeafPoint;
pub use ;
pub use GrowthParams;
pub use ;
pub use ;
pub use MeshData;
pub use ;
pub use ;
pub use ;
pub use ;
pub use TreePreset;
pub use SeededRng;
pub use ;
pub use ;
pub use ;
pub use ;
/// What a game usually needs, in one `use bevy_flora::prelude::*;`: the plugin, the tree, pool and
/// growth components, the presets and parameters, the wind, the season, the gameplay shape and the
/// forest scatter.
// Compile the README's Rust examples as doctests.
;