dreamwell_engine/physics/
particle_state.rs1use serde::{Deserialize, Serialize};
2
3#[repr(C)]
7#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
8#[cfg_attr(feature = "physics-gpu-types", derive(bytemuck::Pod, bytemuck::Zeroable))]
9pub struct ParticleState {
10 pub position: [f32; 3],
12 pub lifetime: f32,
13 pub velocity: [f32; 3],
15 pub age: f32,
16 pub acceleration: [f32; 3],
18 pub mass: f32,
19 pub rotation: [f32; 4],
21 pub angular_velocity: [f32; 3],
23 pub drag: f32,
24 pub color: [f32; 4],
26 pub scale: [f32; 2],
28 pub temperature: f32,
29 pub energy: f32,
30 pub emitter_id: u32,
32 pub material_id: u32,
33 pub flags: u32,
34 pub seed: u32,
35 pub tag_mask_lo: u32,
37 pub tag_mask_hi: u32,
38 pub custom_f32: [f32; 2],
40}
41
42impl ParticleState {
43 pub const FLAG_ALIVE: u32 = 1 << 0;
45 pub const FLAG_PROMOTE_CANDIDATE: u32 = 1 << 1;
47 pub const FLAG_RESTING: u32 = 1 << 2;
49 pub const FLAG_COLLIDED: u32 = 1 << 3;
51 pub const FLAG_SIGNAL_CARRIER: u32 = 1 << 4;
53
54 pub fn is_alive(&self) -> bool {
55 self.flags & Self::FLAG_ALIVE != 0
56 }
57
58 pub fn is_promotion_candidate(&self) -> bool {
59 self.flags & Self::FLAG_PROMOTE_CANDIDATE != 0
60 }
61}
62
63impl Default for ParticleState {
64 fn default() -> Self {
65 Self {
66 position: [0.0; 3],
67 lifetime: 5.0,
68 velocity: [0.0; 3],
69 age: 0.0,
70 acceleration: [0.0; 3],
71 mass: 1.0,
72 rotation: [0.0, 0.0, 0.0, 1.0],
73 angular_velocity: [0.0; 3],
74 drag: 0.0,
75 color: [1.0; 4],
76 scale: [0.1, 0.1],
77 temperature: 0.0,
78 energy: 0.0,
79 emitter_id: 0,
80 material_id: 0,
81 flags: Self::FLAG_ALIVE,
82 seed: 0,
83 tag_mask_lo: 0,
84 tag_mask_hi: 0,
85 custom_f32: [0.0; 2],
86 }
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn particle_state_size() {
96 assert_eq!(std::mem::size_of::<ParticleState>(), 144);
98 }
99
100 #[test]
101 fn particle_state_default() {
102 let p = ParticleState::default();
103 assert!(p.is_alive());
104 assert!(!p.is_promotion_candidate());
105 }
106
107 #[test]
108 fn particle_state_flags() {
109 let mut p = ParticleState::default();
110 p.flags |= ParticleState::FLAG_PROMOTE_CANDIDATE;
111 assert!(p.is_promotion_candidate());
112 p.flags &= !ParticleState::FLAG_ALIVE;
113 assert!(!p.is_alive());
114 }
115
116 #[test]
117 fn particle_state_alignment() {
118 assert_eq!(std::mem::align_of::<ParticleState>(), 4);
120 }
121}