use bevy::{
ecs::prelude::{Component, ReflectComponent, Resource},
math::Vec3,
reflect::Reflect,
};
#[derive(Debug, Copy, Clone, Default, Reflect)]
pub enum AccelerationSmoothing {
#[default]
SquaredDeltaTime,
FixedCoefficient(f32),
}
#[derive(Debug, Clone, Component, Reflect, Resource)]
#[reflect(Component)]
pub struct ClothConfig {
pub gravity: Vec3,
pub friction: f32,
pub sticks_computation_depth: u8,
pub acceleration_smoothing: AccelerationSmoothing,
}
impl ClothConfig {
pub const DEFAULT_GRAVITY: f32 = -9.81;
#[must_use]
#[inline]
pub(crate) fn friction_coefficient(&self) -> f32 {
1.0 - self.friction.clamp(0.0, 1.0)
}
#[inline]
#[must_use]
pub fn smoothed_acceleration(&self, acceleration: Vec3, delta_time: f32) -> Vec3 {
acceleration * self.smooth_value(delta_time)
}
#[inline]
#[must_use]
pub fn smooth_value(&self, delta_time: f32) -> f32 {
match self.acceleration_smoothing {
AccelerationSmoothing::SquaredDeltaTime => delta_time * delta_time,
AccelerationSmoothing::FixedCoefficient(coef) => coef,
}
}
#[must_use]
#[inline]
pub fn no_gravity() -> Self {
Self {
gravity: Vec3::ZERO,
..Default::default()
}
}
}
impl Default for ClothConfig {
fn default() -> Self {
Self {
gravity: Vec3::Y * Self::DEFAULT_GRAVITY,
friction: 0.01,
sticks_computation_depth: 5,
acceleration_smoothing: Default::default(),
}
}
}