diff options
| author | JacobPalecki <[email protected]> | 2021-01-20 20:13:33 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-01-20 20:13:33 -0800 |
| commit | 5b6479013c8f35df933dd57c680063f4db1e4028 (patch) | |
| tree | 60dd7c67a0f163457da2519b42553382a39a591b /common | |
| parent | show custom dialog on bad input (#63) (diff) | |
| parent | Guard against bad anisotropy args (diff) | |
| download | rawaccel-5b6479013c8f35df933dd57c680063f4db1e4028.tar.xz rawaccel-5b6479013c8f35df933dd57c680063f4db1e4028.zip | |
Merge pull request #65 from JacobPalecki/Directional
Directionality Features + Graph Fidelity
Diffstat (limited to 'common')
| -rw-r--r-- | common/accel-base.hpp | 5 | ||||
| -rw-r--r-- | common/accel-motivity.hpp | 20 | ||||
| -rw-r--r-- | common/rawaccel-settings.h | 2 | ||||
| -rw-r--r-- | common/rawaccel-version.h | 4 | ||||
| -rw-r--r-- | common/rawaccel.hpp | 90 |
5 files changed, 114 insertions, 7 deletions
diff --git a/common/accel-base.hpp b/common/accel-base.hpp index b15d695..42b3bb1 100644 --- a/common/accel-base.hpp +++ b/common/accel-base.hpp @@ -17,6 +17,11 @@ namespace rawaccel { double speed_cap = 0; }; + struct domain_args { + vec2d domain_weights = { 1, 1 }; + double lp_norm = 2; + }; + template <typename Func> struct accel_val_base { bool legacy_offset = false; diff --git a/common/accel-motivity.hpp b/common/accel-motivity.hpp index f88320b..246cf37 100644 --- a/common/accel-motivity.hpp +++ b/common/accel-motivity.hpp @@ -55,28 +55,40 @@ namespace rawaccel { inline void fill(si_pair* lookup) const { double lookup_speed = 0; + double integral_interval = 0; double gain_integral_speed = 0; + double gain_integral_speed_prev = 0; double gain = 0; double intercept = 0; double output = 0; + double output_prev = 0; double x = -2; + double logarithm_interval = 0.01; + double integral_intervals_per_speed = 10; + double integral_interval_factor = pow(10, logarithm_interval) / integral_intervals_per_speed; + lookup[0] = {}; for (size_t i = 1; i < LUT_SIZE; i++) { - x += 0.01; + x += logarithm_interval; + // Each lookup speed will be 10^0.01 = 2.33% higher than the previous + // To get 10 integral intervals per speed, set interval to 0.233% lookup_speed = pow(10, x); + integral_interval = lookup_speed * integral_interval_factor; while (gain_integral_speed < lookup_speed) { - gain_integral_speed += 0.001; + output_prev = output; + gain_integral_speed_prev = gain_integral_speed; + gain_integral_speed += integral_interval; gain = operator()(gain_integral_speed); - output += gain * 0.001; + output += gain * integral_interval; } - intercept = output - gain * lookup_speed; + intercept = output_prev - gain_integral_speed_prev * gain; lookup[i] = { gain, intercept }; } diff --git a/common/rawaccel-settings.h b/common/rawaccel-settings.h index eb7c49a..6fa2aa9 100644 --- a/common/rawaccel-settings.h +++ b/common/rawaccel-settings.h @@ -24,6 +24,8 @@ namespace rawaccel { vec2<accel_args> argsv; vec2d sens = { 1, 1 }; vec2d dir_multipliers = {}; + domain_args domain_args = {}; + vec2d range_weights = { 1, 1 }; milliseconds time_min = DEFAULT_TIME_MIN; wchar_t device_id[MAX_DEV_ID_LEN] = {0}; }; diff --git a/common/rawaccel-version.h b/common/rawaccel-version.h index 9470ca0..0e02036 100644 --- a/common/rawaccel-version.h +++ b/common/rawaccel-version.h @@ -1,7 +1,7 @@ #pragma once #define RA_VER_MAJOR 1 -#define RA_VER_MINOR 3 +#define RA_VER_MINOR 4 #define RA_VER_PATCH 0 #define RA_MIN_OS "Win7" @@ -20,7 +20,7 @@ namespace rawaccel { }; #ifndef _KERNEL_MODE - inline constexpr version_t min_driver_version = { 1, 3, 0 }; + inline constexpr version_t min_driver_version = { 1, 4, 0 }; #endif } diff --git a/common/rawaccel.hpp b/common/rawaccel.hpp index 3e049cb..c617bed 100644 --- a/common/rawaccel.hpp +++ b/common/rawaccel.hpp @@ -225,12 +225,90 @@ namespace rawaccel { accelerator() = default; }; + struct weighted_distance { + double p = 2.0; + double p_inverse = 0.5; + bool lp_norm_infinity = false; + double sigma_x = 1.0; + double sigma_y = 1.0; + + weighted_distance(domain_args args) + { + sigma_x = args.domain_weights.x; + sigma_y = args.domain_weights.y; + if (args.lp_norm <= 0) + { + lp_norm_infinity = true; + p = 0.0; + p_inverse = 0.0; + } + else + { + lp_norm_infinity = false; + p = args.lp_norm; + p_inverse = 1 / args.lp_norm; + } + } + + double calculate(double x, double y) + { + double abs_x = fabs(x); + double abs_y = fabs(y); + + if (lp_norm_infinity) + { + return abs_x > abs_y ? abs_x : abs_y; + } + + double x_scaled = abs_x * sigma_x; + double y_scaled = abs_y * sigma_y; + return pow(pow(x_scaled, p) + pow(y_scaled, p), p_inverse); + } + + weighted_distance() = default; + }; + + struct direction_weight { + double diff = 0.0; + double start = 1.0; + bool should_apply = false; + + direction_weight(vec2d thetas) + { + diff = thetas.y - thetas.x; + start = thetas.x; + + if (diff != 0) + { + should_apply = true; + } + else + { + should_apply = false; + } + } + + inline double atan_scale(double x, double y) + { + return M_2_PI * atan2(fabs(y), fabs(x)); + } + + double apply(double x, double y) + { + return atan_scale(x, y) * diff + start; + } + + direction_weight() = default; + }; + /// <summary> Struct to hold variables and methods for modifying mouse input </summary> struct mouse_modifier { bool apply_rotate = false; bool apply_accel = false; bool combine_magnitudes = true; rotator rotate; + weighted_distance distance; + direction_weight directional; vec2<accelerator> accels; vec2d sensitivity = { 1, 1 }; vec2d directional_multipliers = {}; @@ -257,6 +335,10 @@ namespace rawaccel { accels.x = accelerator(args.argsv.x, args.modes.x, luts.x); accels.y = accelerator(args.argsv.y, args.modes.y, luts.y); + + distance = weighted_distance(args.domain_args); + directional = direction_weight(args.range_weights); + apply_accel = true; } @@ -276,9 +358,15 @@ namespace rawaccel { milliseconds time = time_supp(); if (combine_magnitudes) { - double mag = sqrtsd(movement.x * movement.x + movement.y * movement.y); + double mag = distance.calculate(movement.x, movement.y); double speed = mag / time; double scale = accels.x.apply(speed); + + if (directional.should_apply) + { + scale = (scale - 1)*directional.apply(movement.x, movement.y) + 1; + } + movement.x *= scale; movement.y *= scale; } |