use bevy::ecs::prelude::Resource;
use bevy::math::Vec3;
use bevy::reflect::{FromReflect, Reflect};
#[cfg_attr(feature = "debug", derive(bevy_inspector_egui::Inspectable))]
#[derive(Debug, Clone, Reflect, FromReflect)]
pub enum Wind {
ConstantWind {
velocity: Vec3,
},
SinWave {
max_velocity: Vec3,
frequency: f32,
normalize: bool,
abs: bool,
},
}
#[cfg_attr(feature = "debug", derive(bevy_inspector_egui::Inspectable))]
#[derive(Debug, Clone, Reflect, Resource, Default)]
pub struct Winds {
pub wind_forces: Vec<Wind>,
}
impl Default for Wind {
fn default() -> Self {
Self::SinWave {
max_velocity: Vec3::ZERO,
frequency: 0.5,
normalize: true,
abs: false,
}
}
}
impl Wind {
#[must_use]
pub fn current_velocity(&self, elapsed_time: f32) -> Vec3 {
match self {
Self::ConstantWind { velocity } => *velocity,
Self::SinWave {
max_velocity,
frequency,
normalize,
abs,
} => {
let mut sin_value = (elapsed_time * frequency).sin();
if *normalize {
sin_value = (sin_value + 1.0) / 2.0;
}
if *abs {
sin_value = sin_value.abs();
}
sin_value * *max_velocity
}
}
}
}
impl Winds {
#[must_use]
pub fn current_velocity(&self, elapsed_time: f32) -> Vec3 {
self.wind_forces
.iter()
.map(|w| w.current_velocity(elapsed_time))
.sum()
}
}
impl From<Wind> for Winds {
fn from(wind: Wind) -> Self {
Self {
wind_forces: vec![wind],
}
}
}
impl From<Vec<Wind>> for Winds {
fn from(wind_forces: Vec<Wind>) -> Self {
Self { wind_forces }
}
}