bevy_feronia/wind/
plugin.rs1use super::systems::*;
2use crate::prelude::*;
3
4use bevy_app::{App, Plugin, PreUpdate, Startup, Update};
5use bevy_asset::Assets;
6use bevy_ecs::prelude::*;
7use bevy_pbr::StandardMaterial;
8use bevy_shader::load_shader_library;
9use std::fmt::Debug;
10use std::marker::PhantomData;
11
12pub struct WindPlugin;
13
14#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
15pub struct WindTextureSetup;
16
17impl Plugin for WindPlugin {
18 fn build(&self, app: &mut App) {
19 load_shader_library!(app, "types.wgsl");
20 load_shader_library!(app, "wind.wgsl");
21 load_shader_library!(app, "bindings.wgsl");
22 load_shader_library!(app, "noise.wgsl");
23 load_shader_library!(app, "displace.wgsl");
24 load_shader_library!(app, "forward_sss_io.wgsl");
25
26 app.register_type::<GlobalWind>()
27 .register_type::<Wind>()
28 .init_resource::<GlobalWind>()
29 .configure_sets(Startup, WindTextureSetup)
30 .add_systems(Startup, setup_wind_texture.in_set(WindTextureSetup))
31 .add_systems(
32 PreUpdate,
33 (
34 sync_wind_preset.run_if(resource_changed::<GlobalWind>),
35 cycle_wind_history,
36 )
37 .chain(),
38 );
39 }
40}
41
42pub struct ScatterMaterialPlugin<T = StandardMaterial>
43where
44 T: ScatterMaterial,
45{
46 pub _marker: PhantomData<T>,
47}
48
49impl<T> Default for ScatterMaterialPlugin<T>
50where
51 T: ScatterMaterial,
52{
53 fn default() -> Self {
54 Self {
55 _marker: PhantomData,
56 }
57 }
58}
59
60impl<T> ScatterMaterialPlugin<T>
61where
62 T: ScatterMaterial,
63{
64 pub fn new() -> Self {
65 Self::default()
66 }
67}
68
69impl<T> Plugin for ScatterMaterialPlugin<T>
70where
71 T: ScatterMaterial,
72{
73 fn build(&self, app: &mut App) {
74 app.add_systems(
75 Update,
76 (update_materials::<T>.run_if(
77 resource_changed::<GlobalWind>
78 .or(material_options_changed)
79 .and(resource_exists::<Assets<ScatterAsset<T>>>)
80 .and(resource_exists::<ScatterAssetManager<T>>),
81 ),),
82 );
83 }
84}
85
86fn material_options_changed(
88 q_layer_changed: Query<(), (Or<(MaterialChangedFilter, WindChangedFilter)>,)>,
89 q_root_changed: Query<
90 (),
91 (
92 With<ScatterRoot>,
93 Or<(MaterialChangedFilter, WindChangedFilter)>,
94 ),
95 >,
96) -> bool {
97 !q_layer_changed.is_empty() || !q_root_changed.is_empty()
98}