Skip to main content

dreamwell_engine/physics/
behaviors.rs

1use serde::{Deserialize, Serialize};
2
3/// Behavior block — steering/simulation behavior applied to particles.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
5pub enum BehaviorBlock {
6    Seek,
7    Flee,
8    Orbit,
9    AlignToVelocity,
10    AlignToSurfaceNormal,
11    Drift,
12    Wobble,
13    Settle,
14    Hover,
15    Tether,
16    Fuse,
17    Split,
18    ParticleLite,
19}
20
21impl BehaviorBlock {
22    pub const ALL: &[BehaviorBlock] = &[
23        Self::Seek,
24        Self::Flee,
25        Self::Orbit,
26        Self::AlignToVelocity,
27        Self::AlignToSurfaceNormal,
28        Self::Drift,
29        Self::Wobble,
30        Self::Settle,
31        Self::Hover,
32        Self::Tether,
33        Self::Fuse,
34        Self::Split,
35        Self::ParticleLite,
36    ];
37
38    pub fn name(&self) -> &'static str {
39        match self {
40            Self::Seek => "Seek",
41            Self::Flee => "Flee",
42            Self::Orbit => "Orbit",
43            Self::AlignToVelocity => "Align to Velocity",
44            Self::AlignToSurfaceNormal => "Align to Surface Normal",
45            Self::Drift => "Drift",
46            Self::Wobble => "Wobble",
47            Self::Settle => "Settle",
48            Self::Hover => "Hover",
49            Self::Tether => "Tether",
50            Self::Fuse => "Fuse",
51            Self::Split => "Split",
52            Self::ParticleLite => "Particle Lite",
53        }
54    }
55
56    /// GPU compute weight (relative cost, 1.0 = baseline).
57    pub fn compute_weight(&self) -> f32 {
58        match self {
59            Self::Seek | Self::Flee | Self::Drift => 1.0,
60            Self::Orbit | Self::Hover | Self::Wobble => 1.2,
61            Self::AlignToVelocity | Self::AlignToSurfaceNormal => 1.5,
62            Self::Settle | Self::Tether => 1.0,
63            Self::Fuse | Self::Split => 2.0,
64            Self::ParticleLite => 3.0,
65        }
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn behavior_block_all() {
75        assert_eq!(BehaviorBlock::ALL.len(), 13);
76    }
77
78    #[test]
79    fn behavior_serde_roundtrip() {
80        for &b in BehaviorBlock::ALL {
81            let json = serde_json::to_string(&b).unwrap();
82            let restored: BehaviorBlock = serde_json::from_str(&json).unwrap();
83            assert_eq!(b, restored);
84        }
85    }
86}