microscope_memory/
emotional_21d.rs1use std::fs;
7use std::path::Path;
8
9const MAGIC: &[u8; 4] = b"E21D";
10const STATE_SIZE: usize = 4 + 21 * 4; pub struct EmotionalState21D {
14 pub vector: [f32; 21],
15}
16
17impl EmotionalState21D {
18 pub fn load_or_init(path: &Path) -> Self {
20 if path.exists() {
21 if let Ok(data) = fs::read(path) {
22 if data.len() >= STATE_SIZE && &data[0..4] == MAGIC {
23 let mut vector = [0.0f32; 21];
24 for (i, v) in vector.iter_mut().enumerate() {
25 let off = 4 + i * 4;
26 *v = f32::from_le_bytes(data[off..off + 4].try_into().unwrap_or([0u8; 4]));
27 }
28 for v in &mut vector {
30 if v.is_nan() || v.is_infinite() {
31 *v = 0.0;
32 }
33 }
34 return Self { vector };
35 }
36 }
37 }
38 Self {
39 vector: [0.0f32; 21],
40 }
41 }
42
43 pub fn save(&self, path: &Path) -> Result<(), String> {
45 let mut buf = Vec::with_capacity(STATE_SIZE);
46 buf.extend_from_slice(MAGIC);
47 for &v in &self.vector {
48 buf.extend_from_slice(&v.to_le_bytes());
49 }
50 let tmp_path = path.with_extension("bin.tmp");
51 fs::write(&tmp_path, &buf).map_err(|e| format!("write emotion_21d.bin: {}", e))?;
52 fs::rename(&tmp_path, path).map_err(|e| format!("rename emotion_21d.bin: {}", e))
53 }
54}
55
56pub fn emotion_21d_bias(state: &EmotionalState21D) -> (f32, f32, f32) {
60 let intensity: f32 = state
61 .vector
62 .iter()
63 .map(|x| x * x)
64 .sum::<f32>()
65 .sqrt()
66 .min(1.0);
67 if intensity.is_nan() {
69 return (0.0, 0.0, 0.0);
70 }
71 let dx = state.vector[0].clamp(-1.0, 1.0) * intensity;
72 let dy = state.vector[1].clamp(-1.0, 1.0) * intensity;
73 let dz = state.vector[2].clamp(-1.0, 1.0) * intensity;
74 (dx * 0.1, dy * 0.1, dz * 0.1)
75}