Skip spatial force below display threshold

This commit is contained in:
lenn
2026-07-14 15:30:32 +08:00
parent 801a909c64
commit ca6ca377df
2 changed files with 44 additions and 17 deletions

View File

@@ -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,31 +713,40 @@ fn update_hand_signal_histories(
histories: &mut [Vec<f32>; 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()
{
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);
}
}
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;
let force = raw_to_hand_segment_g(index, raw_total).min(20.6);
let force = if force <= 0.05 { 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
raw_to_hand_segment_g(index, raw_total).min(20.6)
}
fn raw_to_hand_segment_g(index: usize, raw: u32) -> f32 {

View File

@@ -50,10 +50,22 @@ impl ForceEstimatorState {
pub fn analyze_fingertips(
&mut self,
values: &[u32],
) -> [Option<HudSpatialForce>; 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<HudSpatialForce>; 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 {