use super::*;
use crate::physics::behaviors::BehaviorBlock;
use crate::physics::classes::{ReplicationClass, SimulationMode};
use crate::physics::collision::{CollisionMode, CollisionPolicy, CollisionResponse};
use crate::physics::emitter::*;
use crate::physics::promotion::PromotionPolicy;
use crate::physics::render_mode::{RenderMode, RepresentationMode};
use crate::physics::render_policy::RenderPolicy;
use crate::physics::semantic_binding::SemanticBinding;
fn base_entry(id: &str, name: &str) -> PresetCatalogEntry {
PresetCatalogEntry {
id: id.into(),
name: name.into(),
family: PresetFamily::Weather,
authority: AuthorityProfile::VisualOnly,
semantics: SemanticBinding::default(),
shape: SpawnShape::Box {
extents: [20.0, 0.5, 20.0],
},
spawn: SpawnPolicy {
mode: SpawnMode::Continuous,
rate_per_sec: 100.0,
burst_count: 0,
max_live: 2000,
warmup_seconds: 1.0,
looped: true,
seed: 0,
density_scale_lod: true,
},
initialize: InitPolicy::default(),
simulate: SimPolicy {
mode: SimulationMode::Full,
gravity: [0.0, -5.0, 0.0],
drag: 0.01,
damping: 0.0,
noise: None,
forces: vec![],
lifetime: LifetimePolicy {
seconds: 4.0,
random_range: None,
},
behaviors: vec![],
},
collision: CollisionPolicy {
mode: CollisionMode::Plane,
response: CollisionResponse::Die,
..CollisionPolicy::default()
},
render: RenderPolicy {
mode: RenderMode::StretchedBillboard,
velocity_alignment: true,
..RenderPolicy::default()
},
promotion: PromotionPolicy::default(),
budgets: BudgetPolicy {
max_gpu_particles: 4000,
importance: "Normal".into(),
offscreen_mode: SimulationMode::Culled,
},
replication: ReplicationPolicy {
class: ReplicationClass::None,
},
supported_views: vec![RepresentationMode::World3D, RepresentationMode::Sprite2D],
tags: vec!["weather".into()],
}
}
pub fn catalog() -> Vec<PresetCatalogEntry> {
vec![
{
let mut e = base_entry("weather_rain_light", "Light Rain");
e.spawn.rate_per_sec = 60.0;
e.spawn.max_live = 1000;
e.simulate.gravity = [0.0, -8.0, 0.0];
e.initialize.color = [0.6, 0.7, 0.9, 0.4];
e.tags.push("rain".into());
e
},
{
let mut e = base_entry("weather_rain_heavy", "Heavy Rain");
e.spawn.rate_per_sec = 200.0;
e.spawn.max_live = 4000;
e.simulate.gravity = [0.0, -12.0, 0.0];
e.initialize.color = [0.5, 0.6, 0.85, 0.5];
e.tags.push("rain".into());
e
},
{
let mut e = base_entry("weather_rain_storm", "Storm Rain");
e.spawn.rate_per_sec = 400.0;
e.spawn.max_live = 8000;
e.simulate.gravity = [-2.0, -15.0, 0.0];
e.initialize.color = [0.4, 0.5, 0.75, 0.6];
e.budgets.max_gpu_particles = 8000;
e.tags.push("rain".into());
e.tags.push("storm".into());
e
},
{
let mut e = base_entry("weather_snow_light", "Light Snow");
e.spawn.rate_per_sec = 30.0;
e.spawn.max_live = 600;
e.simulate.gravity = [0.0, -1.0, 0.0];
e.simulate.behaviors = vec![BehaviorBlock::Wobble];
e.render.mode = RenderMode::Billboard;
e.render.velocity_alignment = false;
e.collision.response = CollisionResponse::Stick;
e.initialize.color = [0.95, 0.97, 1.0, 0.8];
e.tags.push("snow".into());
e
},
{
let mut e = base_entry("weather_snow_heavy", "Heavy Snow");
e.spawn.rate_per_sec = 100.0;
e.spawn.max_live = 2000;
e.simulate.gravity = [0.0, -1.5, 0.0];
e.simulate.behaviors = vec![BehaviorBlock::Wobble];
e.render.mode = RenderMode::Billboard;
e.render.velocity_alignment = false;
e.collision.response = CollisionResponse::Stick;
e.initialize.color = [0.92, 0.95, 1.0, 0.85];
e.tags.push("snow".into());
e
},
{
let mut e = base_entry("weather_snow_blizzard", "Blizzard");
e.spawn.rate_per_sec = 300.0;
e.spawn.max_live = 6000;
e.simulate.gravity = [-3.0, -2.0, 0.0];
e.render.mode = RenderMode::Billboard;
e.render.velocity_alignment = false;
e.initialize.color = [0.9, 0.93, 1.0, 0.7];
e.budgets.max_gpu_particles = 6000;
e.tags.push("snow".into());
e.tags.push("storm".into());
e
},
{
let mut e = base_entry("weather_hail", "Hail");
e.spawn.rate_per_sec = 50.0;
e.spawn.max_live = 800;
e.simulate.gravity = [0.0, -12.0, 0.0];
e.collision.response = CollisionResponse::Bounce;
e.collision.restitution = 0.4;
e.initialize.color = [0.85, 0.9, 0.95, 0.9];
e.tags.push("hail".into());
e
},
{
let mut e = base_entry("weather_fog_ground", "Ground Fog");
e.spawn.rate_per_sec = 5.0;
e.spawn.max_live = 100;
e.shape = SpawnShape::Box {
extents: [10.0, 0.5, 10.0],
};
e.simulate.gravity = [0.0, 0.0, 0.0];
e.simulate.behaviors = vec![BehaviorBlock::Drift];
e.simulate.lifetime.seconds = 15.0;
e.render.mode = RenderMode::VolumetricImpostor;
e.collision.mode = CollisionMode::None;
e.initialize.color = [0.85, 0.87, 0.9, 0.3];
e.tags.push("fog".into());
e
},
{
let mut e = base_entry("weather_fog_thick", "Thick Fog");
e.spawn.rate_per_sec = 10.0;
e.spawn.max_live = 200;
e.shape = SpawnShape::Box {
extents: [15.0, 3.0, 15.0],
};
e.simulate.gravity = [0.0, 0.0, 0.0];
e.simulate.behaviors = vec![BehaviorBlock::Drift];
e.simulate.lifetime.seconds = 20.0;
e.render.mode = RenderMode::VolumetricImpostor;
e.collision.mode = CollisionMode::None;
e.initialize.color = [0.8, 0.83, 0.87, 0.4];
e.tags.push("fog".into());
e
},
{
let mut e = base_entry("weather_sandstorm", "Sandstorm");
e.spawn.rate_per_sec = 250.0;
e.spawn.max_live = 5000;
e.simulate.gravity = [-4.0, -0.5, 0.0];
e.simulate.lifetime.seconds = 5.0;
e.collision.mode = CollisionMode::None;
e.initialize.color = [0.85, 0.75, 0.5, 0.6];
e.budgets.max_gpu_particles = 5000;
e.tags.push("sand".into());
e.tags.push("storm".into());
e
},
{
let mut e = base_entry("weather_dust_devil", "Dust Devil");
e.spawn.rate_per_sec = 80.0;
e.spawn.max_live = 1000;
e.shape = SpawnShape::Cone {
radius: 1.0,
angle_radians: 0.5,
};
e.simulate.gravity = [0.0, 1.0, 0.0];
e.simulate.behaviors = vec![BehaviorBlock::Orbit];
e.simulate.lifetime.seconds = 3.0;
e.collision.mode = CollisionMode::None;
e.initialize.color = [0.8, 0.7, 0.5, 0.5];
e.tags.push("dust".into());
e
},
{
let mut e = base_entry("weather_tornado_debris", "Tornado Debris");
e.spawn.rate_per_sec = 150.0;
e.spawn.max_live = 3000;
e.shape = SpawnShape::Cone {
radius: 3.0,
angle_radians: 0.3,
};
e.simulate.gravity = [0.0, 2.0, 0.0];
e.simulate.behaviors = vec![BehaviorBlock::Orbit];
e.simulate.lifetime.seconds = 5.0;
e.collision.mode = CollisionMode::None;
e.render.mode = RenderMode::ShardInstance;
e.budgets.max_gpu_particles = 3000;
e.tags.push("tornado".into());
e
},
{
let mut e = base_entry("weather_lightning_sparks", "Lightning Sparks");
e.spawn.mode = SpawnMode::Burst;
e.spawn.burst_count = 50;
e.spawn.max_live = 50;
e.shape = SpawnShape::Point;
e.simulate.gravity = [0.0, -3.0, 0.0];
e.simulate.lifetime.seconds = 0.5;
e.collision.mode = CollisionMode::None;
e.initialize.color = [0.8, 0.9, 1.0, 1.0];
e.tags.push("lightning".into());
e
},
{
let mut e = base_entry("weather_wind_leaves", "Wind Leaves");
e.spawn.rate_per_sec = 8.0;
e.spawn.max_live = 150;
e.simulate.gravity = [0.0, -0.3, 0.0];
e.simulate.behaviors = vec![BehaviorBlock::Wobble, BehaviorBlock::Drift];
e.simulate.lifetime.seconds = 6.0;
e.collision.mode = CollisionMode::None;
e.render.mode = RenderMode::Billboard;
e.render.velocity_alignment = false;
e.initialize.color = [0.5, 0.6, 0.2, 0.8];
e.tags.push("leaves".into());
e
},
{
let mut e = base_entry("weather_cloud_wisp", "Cloud Wisp");
e.spawn.rate_per_sec = 2.0;
e.spawn.max_live = 30;
e.shape = SpawnShape::Box {
extents: [20.0, 1.0, 20.0],
};
e.simulate.gravity = [0.0, 0.0, 0.0];
e.simulate.behaviors = vec![BehaviorBlock::Drift];
e.simulate.lifetime.seconds = 30.0;
e.render.mode = RenderMode::VolumetricImpostor;
e.collision.mode = CollisionMode::None;
e.initialize.color = [1.0, 1.0, 1.0, 0.5];
e.tags.push("cloud".into());
e
},
{
let mut e = base_entry("weather_drizzle_mist", "Drizzle Mist");
e.spawn.rate_per_sec = 40.0;
e.spawn.max_live = 800;
e.simulate.gravity = [0.0, -3.0, 0.0];
e.simulate.lifetime.seconds = 3.0;
e.initialize.color = [0.7, 0.75, 0.85, 0.3];
e.tags.push("rain".into());
e.tags.push("mist".into());
e
},
]
}