From 5b659e1cfbc4b8fbbd2f2bf41dc716929976c77d Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Sat, 28 Aug 2021 01:19:18 -0400 Subject: add per-device configuration adds input and [in, out] cap for classic mode adds input cap for power mode change wrapper/input, now gets useful device names change (now dev specific) dpi to adjust sensitivity change y sensitivity to y/x ratio remove spaced LUTs grapher and convert do not build --- common/accel-lookup.hpp | 139 +++++------------------------------------------- 1 file changed, 13 insertions(+), 126 deletions(-) (limited to 'common/accel-lookup.hpp') diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp index 99f39e9..b7e8b68 100644 --- a/common/accel-lookup.hpp +++ b/common/accel-lookup.hpp @@ -7,27 +7,6 @@ namespace rawaccel { - struct linear_range { - double start; - double stop; - int num; - - template - void for_each(Func fn) const - { - double interval = (stop - start) / (num - 1); - for (int i = 0; i < num; i++) { - fn(i * interval + start); - } - } - - int size() const - { - return num; - } - }; - - // represents the range [2^start, 2^stop], with num - 1 // elements linearly spaced between each exponential step struct fp_rep_range { @@ -55,103 +34,7 @@ namespace rawaccel { } }; - template - struct lut_base { - enum { capacity = SPACED_LUT_CAPACITY }; - using value_t = float; - - template - void fill(Func fn) - { - auto* self = static_cast(this); - - self->range.for_each([&, fn, i = 0](double x) mutable { - self->data[i++] = static_cast(fn(x)); - }); - } - - }; - - struct linear_lut : lut_base { - linear_range range; - bool transfer = false; - value_t data[capacity] = {}; - - double operator()(double x) const - { - if (x > range.start) { - double range_dist = range.stop - range.start; - double idx_f = (x - range.start) * (range.num - 1) / range_dist; - - unsigned idx = min(static_cast(idx_f), range.size() - 2); - - if (idx < capacity - 1) { - double y = lerp(data[idx], data[idx + 1], idx_f - idx); - if (transfer) y /= x; - return y; - } - } - - double y = data[0]; - if (transfer) y /= range.start; - return y; - } - - linear_lut(const spaced_lut_args& args) : - range({ - args.start, - args.stop, - args.num_elements - }), - transfer(args.transfer) {} - - linear_lut(const accel_args& args) : - linear_lut(args.spaced_args) {} - }; - - struct binlog_lut : lut_base { - fp_rep_range range; - double x_start; - bool transfer = false; - value_t data[capacity] = {}; - - double operator()(double x) const - { - int e = min(ilogb(x), range.stop - 1); - - if (e >= range.start) { - int idx_int_log_part = e - range.start; - double idx_frac_lin_part = scalbn(x, -e) - 1; - double idx_f = range.num * (idx_int_log_part + idx_frac_lin_part); - - unsigned idx = min(static_cast(idx_f), range.size() - 2); - - if (idx < capacity - 1) { - double y = lerp(data[idx], data[idx + 1], idx_f - idx); - if (transfer) y /= x; - return y; - } - } - - double y = data[0]; - if (transfer) y /= x_start; - return y; - } - - binlog_lut(const spaced_lut_args& args) : - range({ - static_cast(args.start), - static_cast(args.stop), - args.num_elements - }), - x_start(scalbn(1, range.start)), - transfer(args.transfer) {} - - binlog_lut(const accel_args& args) : - binlog_lut(args.spaced_args) {} - }; - - struct si_pair { + struct si_pair { float slope = 0; float intercept = 0; }; @@ -161,10 +44,11 @@ namespace rawaccel { si_pair slope_intercept = {}; }; - struct arbitrary_lut { - enum { capacity = ARB_LUT_CAPACITY }; + struct lookup { + enum { capacity = LUT_POINTS_CAPACITY }; fp_rep_range range; + bool velocity_points; arbitrary_lut_point data[capacity] = {}; int log_lookup[capacity] = {}; double first_point_speed; @@ -173,9 +57,8 @@ namespace rawaccel { int last_log_lookup_index; double last_log_lookup_speed; double first_log_lookup_speed; - bool velocity_points; - double operator()(double speed) const + double operator()(double speed, const accel_args&) const { int index = 0; int last_arb_index = last_arbitrary_index; @@ -247,8 +130,11 @@ namespace rawaccel { } } - void fill(const vec2* points, int length) + void fill(const float* raw_data, int raw_length) { + auto* points = reinterpret_cast*>(raw_data); + int length = raw_length / 2; + first_point_speed = points[0].x; last_arbitrary_index = length - 1; // -2 because the last index in the arbitrary array is used for slope-intercept only @@ -297,10 +183,11 @@ namespace rawaccel { } } - arbitrary_lut(const accel_args& args) + lookup(const accel_args& args) { - velocity_points = args.arb_args.velocity; - fill(args.arb_args.data, args.arb_args.length); + velocity_points = args.gain; + fill(args.data, args.length); } }; + } -- cgit v1.2.3 From 6a9272d3af202274dfbced245f0ba20b263fcd8b Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Fri, 3 Sep 2021 18:09:00 -0400 Subject: refactor vec2/math --- common/accel-lookup.hpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'common/accel-lookup.hpp') diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp index b7e8b68..b8c689a 100644 --- a/common/accel-lookup.hpp +++ b/common/accel-lookup.hpp @@ -3,8 +3,6 @@ #include "rawaccel-base.hpp" #include "utility.hpp" -#include - namespace rawaccel { // represents the range [2^start, 2^stop], with num - 1 -- cgit v1.2.3 From 83545569d958ecd157e20cb683b1d47a81996266 Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Sun, 5 Sep 2021 21:42:04 -0400 Subject: change lookup impl to use binary search less data, less code, and latency is good at 8, 128, and 1024 points --- common/accel-lookup.hpp | 184 +++++++++++------------------------------------- 1 file changed, 42 insertions(+), 142 deletions(-) (limited to 'common/accel-lookup.hpp') diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp index b8c689a..493a7a4 100644 --- a/common/accel-lookup.hpp +++ b/common/accel-lookup.hpp @@ -32,160 +32,60 @@ namespace rawaccel { } }; - struct si_pair { - float slope = 0; - float intercept = 0; - }; - - struct arbitrary_lut_point { - float applicable_speed = 0; - si_pair slope_intercept = {}; - }; - struct lookup { enum { capacity = LUT_POINTS_CAPACITY }; - fp_rep_range range; - bool velocity_points; - arbitrary_lut_point data[capacity] = {}; - int log_lookup[capacity] = {}; - double first_point_speed; - double last_point_speed; - int last_arbitrary_index; - int last_log_lookup_index; - double last_log_lookup_speed; - double first_log_lookup_speed; - - double operator()(double speed, const accel_args&) const - { - int index = 0; - int last_arb_index = last_arbitrary_index; - int last_log_index = last_log_lookup_index; - - if (speed <= 0) return 1; - - if (unsigned(last_arb_index) < capacity && - unsigned(last_log_index) < capacity && - speed > first_point_speed) - { - if (speed > last_point_speed) - { - index = last_arb_index; - } - else if (speed > last_log_lookup_speed) - { - int last_log = log_lookup[last_log_index]; - if (unsigned(last_log) >= capacity) return 1; - index = search_from(last_log, last_arb_index, speed); - } - else if (speed < first_log_lookup_speed) - { - index = search_from(0, last_arb_index, speed); - } - else - { - int log_index = get_log_index(speed); - if (unsigned(log_index) >= capacity) return 1; - int arbitrary_index = log_lookup[log_index]; - if (arbitrary_index < 0) return 1; - index = search_from(arbitrary_index, last_arb_index, speed); - } - - } - - return apply(index, speed); - } - - int inline get_log_index(double speed) const - { - double speed_log = log(speed) - range.start; - int index = (int)floor(speed_log * range.num); - return index; - } + int size; + bool velocity; - int inline search_from(int index, int last, double speed) const - { - do - { - index++; - } - while (index <= last && data[index].applicable_speed < speed); + lookup(const accel_args& args) : + size(args.length / 2), + velocity(args.gain) {} - return index - 1; - } - - double inline apply(int index, double speed) const + double operator()(double x, const accel_args& args) const { - auto [slope, intercept] = data[index].slope_intercept; - - if (velocity_points) - { - return slope + intercept / speed; - } - else - { - return slope * speed + intercept; - } - } + auto* points = reinterpret_cast*>(args.data); + + int lo = 0; + int hi = size - 2; + + if (x <= 0) return 0; + + if (hi < capacity - 1) { + + while (lo <= hi) { + int mid = (lo + hi) / 2; + auto p = points[mid]; + + if (x < p.x) { + hi = mid - 1; + } + else if (x > p.x) { + lo = mid + 1; + } + else { + double y = p.y; + if (velocity) y /= x; + return y; + } + } - void fill(const float* raw_data, int raw_length) - { - auto* points = reinterpret_cast*>(raw_data); - int length = raw_length / 2; - - first_point_speed = points[0].x; - last_arbitrary_index = length - 1; - // -2 because the last index in the arbitrary array is used for slope-intercept only - last_point_speed = points[length-2].x; - - int start = static_cast(floor(log(first_point_speed))); - first_log_lookup_speed = exp(start*1.0); - int end = static_cast(floor(log(last_point_speed))); - last_log_lookup_speed = exp(end*1.0); - int num = end > start ? static_cast(capacity / (end - start)) : 1; - range = fp_rep_range{ start, end, num }; - last_log_lookup_index = end > start ? num * (end - start) - 1 : 0; - - vec2 current = {0, velocity_points ? 0.0f : 1.0f }; - vec2 next; - int log_index = 0; - double log_inner_iterator = range.start; - double log_inner_slice = 1.0 / (range.num * 1.0); - double log_value = exp(log_inner_iterator); - - for (int i = 0; i < length; i++) - { - next = points[i]; - double slope = (next.y - current.y) / (next.x - current.x); - double intercept = next.y - slope * next.x; - si_pair current_si = { - static_cast(slope), - static_cast(intercept) - }; - arbitrary_lut_point current_lut_point = { - static_cast(current.x), - current_si - }; - - this->data[i] = current_lut_point; - - while (log_value < next.x && log_inner_iterator < end) - { - this->log_lookup[log_index] = i; - log_index++; - log_inner_iterator += log_inner_slice; - log_value = exp(log_inner_iterator); + if (lo > 0) { + auto& a = points[lo - 1]; + auto& b = points[lo]; + double t = (x - a.x) / (b.x - a.x); + double y = lerp(a.y, b.y, t); + if (velocity) y /= x; + return y; } - current = next; } - } - lookup(const accel_args& args) - { - velocity_points = args.gain; - fill(args.data, args.length); + double y = points[0].y; + if (velocity) y /= points[0].x; + return y; } }; + } -- cgit v1.2.3 From e1397f3edbc0921ec1ff6f8e3501f786231dd2fb Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Sat, 18 Sep 2021 06:31:14 -0400 Subject: inline lerp --- common/accel-lookup.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'common/accel-lookup.hpp') diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp index 493a7a4..920df1c 100644 --- a/common/accel-lookup.hpp +++ b/common/accel-lookup.hpp @@ -32,6 +32,16 @@ namespace rawaccel { } }; + __forceinline + constexpr double lerp(double a, double b, double t) + { + double x = a + t * (b - a); + if ((t > 1) == (a < b)) { + return maxsd(x, b); + } + return minsd(x, b); + } + struct lookup { enum { capacity = LUT_POINTS_CAPACITY }; -- cgit v1.2.3