diff --git a/src/app.rs b/src/app.rs index a4553a7..27affbe 100644 --- a/src/app.rs +++ b/src/app.rs @@ -25,6 +25,7 @@ use std::{ const SUMMARY_POINTS_PER_SERIES: usize = 42; const HAND_FORCE_PANEL_COUNT: usize = 7; const HAND_FORCE_SEGMENT_COUNTS: [usize; HAND_FORCE_PANEL_COUNT] = [84, 84, 84, 84, 84, 70, 44]; +const HAND_FORCE_DISPLAY_THRESHOLD_N: f32 = 0.05; const HAND_IMAGE_SIZE_PX: [f32; 2] = [971.0, 1117.0]; const HAND_FINGERTIP_FORCE_ANCHORS_PX: [[f32; 2]; HAND_FINGERTIP_COUNT] = [ [265.0, 495.0], @@ -246,7 +247,12 @@ impl EskinDesktopApp { fn analyze_spatial_force(&mut self, values: &[u32]) { if matches!(self.config_state.mode, SerialMode::Hand) { - self.latest_hand_spatial_forces = self.force_estimator.analyze_fingertips(values); + let enabled = std::array::from_fn(|tip_index| { + hand_segment_force(values, tip_index) > HAND_FORCE_DISPLAY_THRESHOLD_N + }); + self.latest_hand_spatial_forces = self + .force_estimator + .analyze_fingertips_masked(values, &enabled); self.latest_spatial_force = self.strongest_hand_spatial_force(); } else { self.latest_spatial_force = self.force_estimator.analyze(values); @@ -707,33 +713,42 @@ fn update_hand_signal_histories( histories: &mut [Vec; HAND_FORCE_PANEL_COUNT], raw_values: &[u32], ) -> f32 { - let mut offset = 0usize; let mut total_force = 0.0; - for (index, (history, sample_count)) in histories - .iter_mut() - .zip(HAND_FORCE_SEGMENT_COUNTS) - .enumerate() - { - let raw_total = raw_values - .get(offset..offset + sample_count) - .unwrap_or(&[]) - .iter() - .fold(0_u64, |sum, value| sum + *value as u64) - .min(u32::MAX as u64) as u32; - let force = raw_to_hand_segment_g(index, raw_total).min(20.6); - let force = if force <= 0.05 { 0.0 } else { force }; + for (index, history) in histories.iter_mut().enumerate() { + let force = hand_segment_force(raw_values, index); + let force = if force <= HAND_FORCE_DISPLAY_THRESHOLD_N { + 0.0 + } else { + force + }; total_force += force; history.push(force); if history.len() > SUMMARY_POINTS_PER_SERIES { history.remove(0); } - - offset += sample_count; } total_force } +fn hand_segment_force(raw_values: &[u32], index: usize) -> f32 { + let offset: usize = HAND_FORCE_SEGMENT_COUNTS[..index.min(HAND_FORCE_PANEL_COUNT)] + .iter() + .sum(); + let sample_count = HAND_FORCE_SEGMENT_COUNTS + .get(index) + .copied() + .unwrap_or_default(); + let raw_total = raw_values + .get(offset..offset + sample_count) + .unwrap_or(&[]) + .iter() + .fold(0_u64, |sum, value| sum + *value as u64) + .min(u32::MAX as u64) as u32; + + raw_to_hand_segment_g(index, raw_total).min(20.6) +} + fn raw_to_hand_segment_g(index: usize, raw: u32) -> f32 { match index { 0 => raw_to_g1(raw), diff --git a/src/force.rs b/src/force.rs index 7205006..6a2c262 100644 --- a/src/force.rs +++ b/src/force.rs @@ -50,10 +50,22 @@ impl ForceEstimatorState { pub fn analyze_fingertips( &mut self, values: &[u32], + ) -> [Option; HAND_FINGERTIP_COUNT] { + self.analyze_fingertips_masked(values, &[true; HAND_FINGERTIP_COUNT]) + } + + pub fn analyze_fingertips_masked( + &mut self, + values: &[u32], + enabled: &[bool; HAND_FINGERTIP_COUNT], ) -> [Option; HAND_FINGERTIP_COUNT] { let mut forces = [None; HAND_FINGERTIP_COUNT]; for (tip_index, processor) in self.fingertip_processors.iter_mut().enumerate() { + if !enabled[tip_index] { + continue; + } + let start = tip_index * FINGER_SAMPLE_COUNT; let end = start + FINGER_SAMPLE_COUNT; let Some(segment) = values.get(start..end) else {