22using System . Numerics ;
33using OpenTabletDriver . Plugin . Attributes ;
44using OpenTabletDriver . Plugin . Tablet ;
5+ using OpenTabletDriver . Plugin . Tablet . Interpolator ;
6+ using OpenTabletDriver . Plugin . Timers ;
57
68namespace TabletDriverFilters . Devocub
79{
810 using static MathF ;
911
1012 [ PluginName ( "TabletDriver AntiChatter Filter" ) ]
11- public class AntiChatter : IFilter
13+ public class AntiChatter : Interpolator
1214 {
13- private Vector2 _lastPos ;
14- private float _timerInterval ;
15- private const float _threshold = 0.9f ;
16- private float _latency = 2.0f ;
15+ public AntiChatter ( ITimer scheduler ) : base ( scheduler ) { }
1716
18- public Vector2 Filter ( Vector2 point )
19- {
20- Vector2 calcTarget = new Vector2 ( ) ;
21- float deltaX , deltaY , distance , weightModifier , predictionModifier ;
17+ private bool isReady ;
18+ private Vector2 position ;
19+ private Vector2 prevTargetPos , targetPos , calcTarget ;
20+ private SyntheticTabletReport report ;
21+ private const float threshold = 0.9f ;
22+ private float latency = 2.0f ;
2223
23- if ( _lastPos == null )
24- {
25- _lastPos = point ;
26- return point ;
27- }
24+ public override void UpdateState ( SyntheticTabletReport report )
25+ {
26+ this . targetPos = report . Position ;
2827
2928 if ( PredictionEnabled )
3029 {
3130 // Calculate predicted position onNewPacket
32- if ( _lastPos . X != point . X || _lastPos . Y != point . Y )
31+ if ( this . prevTargetPos . X != this . targetPos . X || this . prevTargetPos . Y != this . targetPos . Y )
3332 {
3433 // Calculate distance between last 2 packets and prediction
35- deltaX = point . X - _lastPos . X ;
36- deltaY = point . Y - _lastPos . Y ;
37- distance = Sqrt ( deltaX * deltaX + deltaY * deltaY ) ;
38- predictionModifier = 1 / Cosh ( ( distance - PredictionOffsetX ) * PredictionSharpness ) * PredictionStrength + PredictionOffsetY ;
34+ var delta = this . targetPos - this . prevTargetPos ;
35+ var distance = Vector2 . Distance ( this . prevTargetPos , this . targetPos ) ;
36+ var predictionModifier = 1 / Cosh ( ( distance - PredictionOffsetX ) * PredictionSharpness ) * PredictionStrength + PredictionOffsetY ;
3937
4038 // Apply prediction
41- deltaX *= predictionModifier ;
42- deltaY *= predictionModifier ;
39+ delta *= predictionModifier ;
4340
4441 // Update predicted position
45- calcTarget . X = ( float ) ( point . X + deltaX ) ;
46- calcTarget . Y = ( float ) ( point . Y + deltaY ) ;
42+ this . calcTarget = this . targetPos + delta ;
4743
4844 // Update old position for further prediction
49- _lastPos . X = point . X ;
50- _lastPos . Y = point . Y ;
45+ this . prevTargetPos = this . targetPos ;
5146 }
5247 }
5348 else
49+ calcTarget = targetPos ;
50+
51+ this . report = report ;
52+ }
53+
54+ public override SyntheticTabletReport Interpolate ( )
55+ {
56+ this . report . Position = Filter ( this . calcTarget ) ;
57+ return this . report ;
58+ }
59+
60+ public Vector2 Filter ( Vector2 calcTarget )
61+ {
62+ if ( ! this . isReady )
5463 {
55- calcTarget . X = point . X ;
56- calcTarget . Y = point . Y ;
64+ this . position = calcTarget ;
65+ this . isReady = true ;
66+ return calcTarget ;
5767 }
5868
59- deltaX = calcTarget . X - _lastPos . X ;
60- deltaY = calcTarget . Y - _lastPos . Y ;
61- distance = Sqrt ( deltaX * deltaX + deltaY * deltaY ) ;
69+ var delta = calcTarget - this . position ;
70+ var distance = Vector2 . Distance ( this . position , calcTarget ) ;
6271
6372 float stepCount = Latency / TimerInterval ;
64- float target = 1 - _threshold ;
73+ float target = 1 - threshold ;
6574 float weight = ( float ) ( 1.0 - ( 1.0 / Pow ( ( float ) ( 1.0 / target ) , ( float ) ( 1.0 / stepCount ) ) ) ) ;
6675
6776 // Devocub smoothing
6877 // Increase weight of filter in {formula} times
69- weightModifier = ( float ) ( Pow ( distance + AntichatterOffsetX , AntichatterStrength * - 1 ) * AntichatterMultiplier ) ;
78+ var weightModifier = ( float ) ( Pow ( distance + AntichatterOffsetX , AntichatterStrength * - 1 ) * AntichatterMultiplier ) ;
7079
7180 // Limit minimum
7281 if ( weightModifier + AntichatterOffsetY < 0 )
@@ -76,26 +85,23 @@ public Vector2 Filter(Vector2 point)
7685
7786 weightModifier = weight / weightModifier ;
7887 weightModifier = Math . Clamp ( weightModifier , 0 , 1 ) ;
79- _lastPos . X += ( float ) ( deltaX * weightModifier ) ;
80- _lastPos . Y += ( float ) ( deltaY * weightModifier ) ;
88+ this . position += delta * weightModifier ;
8189
82- return _lastPos ;
90+ return this . position ;
8391 }
8492
85- public FilterStage FilterStage => FilterStage . PostTranspose ;
93+ public static FilterStage FilterStage => FilterStage . PostTranspose ;
8694
87- [ SliderProperty ( "Latency" , 0f , 5f , 2f ) ]
95+ [ SliderProperty ( "Latency" , 0f , 1000f , 2f ) ]
8896 public float Latency
8997 {
90- set => _latency = Math . Clamp ( value , 0 , 1000 ) ;
91- get => _latency ;
98+ set => this . latency = Math . Clamp ( value , 0 , 1000 ) ;
99+ get => this . latency ;
92100 }
93101
94- [ Property ( "Timer Interval" ) , Unit ( "hz" ) ]
95102 public float TimerInterval
96103 {
97- set => _timerInterval = 1000f / value ;
98- get => _timerInterval ;
104+ get => 1000 / Hertz ;
99105 }
100106
101107 [ Property ( "Antichatter Strength" ) ]
0 commit comments