use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ForceFieldKind {
Gravity,
Drag,
Damping,
Directional,
Radial,
Attractor,
Repulsor,
Vortex,
Orbital,
Turbulence,
CurlNoise,
Wind,
Buoyancy,
CustomVectorField,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ForceBinding {
pub kind: ForceFieldKind,
pub strength: f32,
pub radius: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ForceFieldDescriptor {
pub kind: ForceFieldKind,
pub position: [f32; 3],
pub direction: [f32; 3],
pub strength: f32,
pub radius: f32,
pub falloff: f32,
pub noise_frequency: f32,
pub noise_amplitude: f32,
}
impl Default for ForceFieldDescriptor {
fn default() -> Self {
Self {
kind: ForceFieldKind::Gravity,
position: [0.0, 0.0, 0.0],
direction: [0.0, -1.0, 0.0],
strength: 9.81,
radius: f32::MAX,
falloff: 0.0,
noise_frequency: 0.0,
noise_amplitude: 0.0,
}
}
}
impl ForceFieldKind {
pub const ALL: &[ForceFieldKind] = &[
Self::Gravity,
Self::Drag,
Self::Damping,
Self::Directional,
Self::Radial,
Self::Attractor,
Self::Repulsor,
Self::Vortex,
Self::Orbital,
Self::Turbulence,
Self::CurlNoise,
Self::Wind,
Self::Buoyancy,
Self::CustomVectorField,
];
pub fn name(&self) -> &'static str {
match self {
Self::Gravity => "Gravity",
Self::Drag => "Drag",
Self::Damping => "Damping",
Self::Directional => "Directional",
Self::Radial => "Radial",
Self::Attractor => "Attractor",
Self::Repulsor => "Repulsor",
Self::Vortex => "Vortex",
Self::Orbital => "Orbital",
Self::Turbulence => "Turbulence",
Self::CurlNoise => "Curl Noise",
Self::Wind => "Wind",
Self::Buoyancy => "Buoyancy",
Self::CustomVectorField => "Custom Vector Field",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn force_field_kind_all() {
assert_eq!(ForceFieldKind::ALL.len(), 14);
}
#[test]
fn force_field_descriptor_default() {
let f = ForceFieldDescriptor::default();
assert_eq!(f.kind, ForceFieldKind::Gravity);
assert_eq!(f.direction, [0.0, -1.0, 0.0]);
}
#[test]
fn force_field_serde() {
let f = ForceFieldDescriptor {
kind: ForceFieldKind::Vortex,
position: [1.0, 2.0, 3.0],
direction: [0.0, 1.0, 0.0],
strength: 5.0,
radius: 10.0,
falloff: 1.0,
noise_frequency: 0.0,
noise_amplitude: 0.0,
};
let json = serde_json::to_string(&f).unwrap();
let restored: ForceFieldDescriptor = serde_json::from_str(&json).unwrap();
assert_eq!(restored.kind, ForceFieldKind::Vortex);
}
}