3
3
#include " rawaccel-base.hpp"
4
4
#include " utility.hpp"
5
5
6
- #include < math.h>
7
6
#include < float.h>
8
7
9
8
namespace rawaccel {
10
9
11
10
// / <summary> Struct to hold "classic" (linear raised to power) acceleration implementation. </summary>
12
11
struct classic_base {
13
- double offset;
14
- double power;
15
- double accel_raised;
16
-
17
- classic_base (const accel_args& args) :
18
- offset (args.offset),
19
- power (args.power),
20
- accel_raised (pow(args.accel_classic, power - 1 )) {}
12
+ double base_fn (double x, double accel_raised, const accel_args& args) const
13
+ {
14
+ return accel_raised * pow (x - args.input_offset , args.exponent_classic ) / x;
15
+ }
21
16
22
- double base_fn (double x) const
17
+ static double base_accel (double x, double y, const accel_args& args)
23
18
{
24
- return accel_raised * pow (x - offset, power) / x;
19
+ auto power = args.exponent_classic ;
20
+ return pow (x * y * pow (x - args.input_offset , -power), 1 / (power - 1 ));
25
21
}
26
22
};
27
23
28
- struct classic_legacy : classic_base {
29
- double sens_cap = DBL_MAX;
24
+ template <bool Gain> struct classic ;
25
+
26
+ template <>
27
+ struct classic <LEGACY> : classic_base {
28
+ double accel_raised;
29
+ double cap = DBL_MAX;
30
30
double sign = 1 ;
31
31
32
- classic_legacy (const accel_args& args) :
33
- classic_base (args)
32
+ classic (const accel_args& args)
34
33
{
35
- if (args.cap > 0 ) {
36
- sens_cap = args.cap - 1 ;
34
+ switch (args.cap_mode ) {
35
+ case cap_mode::io:
36
+ cap = args.cap .y - 1 ;
37
37
38
- if (sens_cap < 0 ) {
39
- sens_cap = -sens_cap ;
38
+ if (cap < 0 ) {
39
+ cap = -cap ;
40
40
sign = -sign;
41
41
}
42
+
43
+ {
44
+ double a = base_accel (args.cap .x , cap, args);
45
+ accel_raised = pow (a, args.exponent_classic - 1 );
46
+ }
47
+ break ;
48
+ case cap_mode::in:
49
+ accel_raised = pow (args.acceleration , args.exponent_classic - 1 );
50
+ if (args.cap .x > 0 ) {
51
+ cap = base_fn (args.cap .x , accel_raised, args);
52
+ }
53
+ break ;
54
+ case cap_mode::out:
55
+ default :
56
+ accel_raised = pow (args.acceleration , args.exponent_classic - 1 );
57
+
58
+ if (args.cap .y > 0 ) {
59
+ cap = args.cap .y - 1 ;
60
+
61
+ if (cap < 0 ) {
62
+ cap = -cap;
63
+ sign = -sign;
64
+ }
65
+ }
66
+
67
+ break ;
42
68
}
43
69
}
44
70
45
- double operator ()(double x) const
71
+ double operator ()(double x, const accel_args& args) const
46
72
{
47
- if (x <= offset) return 1 ;
48
- return sign * minsd (base_fn (x), sens_cap) + 1 ;
49
- }
73
+ if (x <= args.input_offset ) return 1 ;
74
+ return sign * minsd (base_fn (x, accel_raised, args), cap) + 1 ;
75
+ }
76
+
50
77
};
51
78
52
- struct classic : classic_base {
53
- vec2d gain_cap = { DBL_MAX, DBL_MAX };
79
+ template <>
80
+ struct classic <GAIN> : classic_base {
81
+ double accel_raised;
82
+ vec2d cap = { DBL_MAX, DBL_MAX };
54
83
double constant = 0 ;
55
84
double sign = 1 ;
56
85
57
- classic (const accel_args& args) :
58
- classic_base (args)
86
+ classic (const accel_args& args)
59
87
{
60
- if (args.cap > 0 ) {
61
- gain_cap.y = args.cap - 1 ;
88
+ switch (args.cap_mode ) {
89
+ case cap_mode::io:
90
+ cap.x = args.cap .x ;
91
+ cap.y = args.cap .y - 1 ;
62
92
63
- if (gain_cap .y < 0 ) {
64
- gain_cap .y = -gain_cap .y ;
93
+ if (cap .y < 0 ) {
94
+ cap .y = -cap .y ;
65
95
sign = -sign;
66
96
}
67
97
68
- gain_cap.x = gain_inverse (gain_cap.y , args.accel_classic , power, offset);
69
- constant = (base_fn (gain_cap.x ) - gain_cap.y ) * gain_cap.x ;
98
+ {
99
+ double a = gain_accel (cap.x , cap.y , args.exponent_classic , args.input_offset );
100
+ accel_raised = pow (a, args.exponent_classic - 1 );
101
+ }
102
+ constant = (base_fn (cap.x , accel_raised, args) - cap.y ) * cap.x ;
103
+ break ;
104
+ case cap_mode::in:
105
+ accel_raised = pow (args.acceleration , args.exponent_classic - 1 );
106
+ if (args.cap .x > 0 ) {
107
+ cap.x = args.cap .x ;
108
+ cap.y = gain (cap.x , args.acceleration , args.exponent_classic , args.input_offset );
109
+ constant = (base_fn (cap.x , accel_raised, args) - cap.y ) * cap.x ;
110
+ }
111
+ break ;
112
+ case cap_mode::out:
113
+ default :
114
+ accel_raised = pow (args.acceleration , args.exponent_classic - 1 );
115
+
116
+ if (args.cap .y > 0 ) {
117
+ cap.y = args.cap .y - 1 ;
118
+
119
+ if (cap.y < 0 ) {
120
+ cap.y = -cap.y ;
121
+ sign = -sign;
122
+ }
123
+
124
+ cap.x = gain_inverse (cap.y , args.acceleration , args.exponent_classic , args.input_offset );
125
+ constant = (base_fn (cap.x , accel_raised, args) - cap.y ) * cap.x ;
126
+ }
127
+ break ;
70
128
}
71
129
}
72
130
73
- double operator ()(double x) const
131
+ double operator ()(double x, const accel_args& args) const
74
132
{
75
133
double output;
76
134
77
- if (x <= offset ) return 1 ;
135
+ if (x <= args. input_offset ) return 1 ;
78
136
79
- if (x < gain_cap .x ) {
80
- output = base_fn (x);
137
+ if (x < cap .x ) {
138
+ output = base_fn (x, accel_raised, args );
81
139
}
82
140
else {
83
- output = constant / x + gain_cap .y ;
141
+ output = constant / x + cap .y ;
84
142
}
85
143
86
144
return sign * output + 1 ;
@@ -100,6 +158,7 @@ namespace rawaccel {
100
158
{
101
159
return -pow (y / power, 1 / (power - 1 )) / (offset - x);
102
160
}
161
+
103
162
};
104
163
105
164
}
0 commit comments