Prepare sample delivery UI
This commit is contained in:
@@ -118,6 +118,10 @@ impl HudChartState {
|
||||
push_summary_point(&mut self.summary_points, value);
|
||||
}
|
||||
|
||||
pub fn clear_summary(&mut self) {
|
||||
self.summary_points.clear();
|
||||
}
|
||||
|
||||
pub fn record_pressure_matrix(&mut self, values: &[i32]) {
|
||||
if values.is_empty() {
|
||||
return;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -317,7 +317,7 @@ where
|
||||
#[cfg(feature = "multi-dim")]
|
||||
{
|
||||
let pzt_values = vals.iter().map(|value| *value as f32).collect::<Vec<f32>>();
|
||||
if let Ok(analysis) = pzt_processor.get_pzt_analysis(&pzt_values) {
|
||||
if let Ok(analysis) = pzt_processor.get_pzt_analysis_at(&pzt_values, frame.dts_ms() as f32) {
|
||||
if PztProcessor::should_report(&analysis) {
|
||||
spatial_force = Some(HudSpatialForce {
|
||||
angle_deg: analysis.angle_deg,
|
||||
@@ -355,11 +355,81 @@ fn build_display_values(
|
||||
spatial_force: Option<HudSpatialForce>,
|
||||
) -> Option<Vec<i32>> {
|
||||
let summary = values.iter().copied().sum::<i32>();
|
||||
let force = raw_to_g1(summary as u32);
|
||||
chart_state.record_summary(force as f32);
|
||||
chart_state.record_pressure_matrix(values);
|
||||
chart_state.record_spatial_force(spatial_force);
|
||||
Some(vec![summary])
|
||||
|
||||
match ad_to_x(summary as f64) {
|
||||
Some(x) => {
|
||||
if x <= MIN_DISPLAY_FORCE {
|
||||
let zero_values = vec![0; values.len()];
|
||||
chart_state.record_summary(0.0);
|
||||
chart_state.record_pressure_matrix(&zero_values);
|
||||
return Some(vec![0]);
|
||||
}
|
||||
|
||||
chart_state.record_pressure_matrix(values);
|
||||
chart_state.record_summary(x as f32);
|
||||
Some(vec![x.round() as i32])
|
||||
}
|
||||
None => {
|
||||
chart_state.record_pressure_matrix(values);
|
||||
chart_state.record_summary(MAX_DISPLAY_FORCE as f32);
|
||||
Some(vec![MAX_DISPLAY_FORCE.round() as i32])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const MIN_DISPLAY_FORCE: f64 = 0.1;
|
||||
const MAX_DISPLAY_FORCE: f64 = 25.6;
|
||||
|
||||
fn ad_to_x(ad: f64) -> Option<f64> {
|
||||
const CUBIC_LIMIT: f64 = 6.57;
|
||||
const QUADRATIC_A: f64 = -377.8;
|
||||
const QUADRATIC_B: f64 = 26040.0;
|
||||
const EPSILON: f64 = 0.000_001;
|
||||
|
||||
let cubic_min = ad_from_cubic_x(0.0);
|
||||
if ad <= cubic_min {
|
||||
return Some(0.0);
|
||||
}
|
||||
|
||||
let cubic_threshold = ad_from_cubic_x(CUBIC_LIMIT);
|
||||
if ad <= cubic_threshold {
|
||||
return Some(solve_monotonic_ad(ad, 0.0, CUBIC_LIMIT, ad_from_cubic_x));
|
||||
}
|
||||
|
||||
let quadratic_vertex = -QUADRATIC_B / (2.0 * QUADRATIC_A);
|
||||
let quadratic_max = ad_from_quadratic_x(quadratic_vertex);
|
||||
if ad - EPSILON > quadratic_max {
|
||||
return Some(MAX_DISPLAY_FORCE);
|
||||
}
|
||||
|
||||
Some(solve_monotonic_ad(
|
||||
ad,
|
||||
CUBIC_LIMIT,
|
||||
quadratic_vertex,
|
||||
ad_from_quadratic_x,
|
||||
))
|
||||
}
|
||||
|
||||
fn solve_monotonic_ad(ad: f64, mut low: f64, mut high: f64, f: fn(f64) -> f64) -> f64 {
|
||||
for _ in 0..80 {
|
||||
let mid = (low + high) / 2.0;
|
||||
if f(mid) < ad {
|
||||
low = mid;
|
||||
} else {
|
||||
high = mid;
|
||||
}
|
||||
}
|
||||
|
||||
(low + high) / 2.0
|
||||
}
|
||||
|
||||
fn ad_from_cubic_x(x: f64) -> f64 {
|
||||
-5.732 * x.powi(3) - 131.5 * x.powi(2) + 31980.0 * x + 13490.0
|
||||
}
|
||||
|
||||
fn ad_from_quadratic_x(x: f64) -> f64 {
|
||||
-377.8 * x.powi(2) + 26040.0 * x + 51120.0
|
||||
}
|
||||
|
||||
#[cfg(feature = "devkit")]
|
||||
@@ -414,6 +484,7 @@ fn infer_matrix_shape(len: usize) -> (u32, u32) {
|
||||
(best.0 as u32, best.1 as u32)
|
||||
}
|
||||
|
||||
#[cfg(feature = "devkit")]
|
||||
fn raw_to_g1(raw: u32) -> f64 {
|
||||
const X: [u32; 12] = [
|
||||
0, 84402, 117218, 140176, 159126, 175812, 191484, 208758, 224703, 252448, 302361, 352703,
|
||||
|
||||
Reference in New Issue
Block a user