1+ using System ;
2+ using TabletDriverPlugin ;
3+ using TabletDriverPlugin . Attributes ;
4+ using TabletDriverPlugin . Tablet ;
5+
6+ namespace TabletDriverFilters
7+ {
8+ using static Math ;
9+
10+ [ PluginName ( "TabletDriver AntiChatterFilter" ) ]
11+ public class TabletFilterAntiChatter : IFilter
12+ {
13+ private Point _lastPos ;
14+ private float _timerInterval ;
15+ private const float _threshold = 0.63f ;
16+ private float _latency ;
17+
18+ public Point Filter ( Point point )
19+ {
20+ Point calcTarget = new Point ( ) ;
21+ double deltaX , deltaY , distance , weightModifier , predictionModifier ;
22+
23+ if ( _lastPos == null )
24+ {
25+ _lastPos = point ;
26+ return point ;
27+ }
28+
29+ if ( PredictionEnabled )
30+ {
31+ // Calculate predicted position onNewPacket
32+ if ( _lastPos . X != point . X || _lastPos . Y != point . Y )
33+ {
34+ // 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 ;
39+
40+ // Apply prediction
41+ deltaX *= predictionModifier ;
42+ deltaY *= predictionModifier ;
43+
44+ // Update predicted position
45+ calcTarget . X = ( float ) ( point . X + deltaX ) ;
46+ calcTarget . Y = ( float ) ( point . Y + deltaY ) ;
47+
48+ // Update old position for further prediction
49+ _lastPos . X = point . X ;
50+ _lastPos . Y = point . Y ;
51+ }
52+ }
53+ else
54+ {
55+ calcTarget . X = point . X ;
56+ calcTarget . Y = point . Y ;
57+ }
58+
59+ deltaX = calcTarget . X - _lastPos . X ;
60+ deltaY = calcTarget . Y - _lastPos . Y ;
61+ distance = Sqrt ( deltaX * deltaX + deltaY * deltaY ) ;
62+
63+ double stepCount = Latency / TimerInterval ;
64+ double target = 1 - _threshold ;
65+ double weight = 1.0 - ( 1.0 / Pow ( 1.0 / target , 1.0 / stepCount ) ) ;
66+
67+ // Devocub smoothing
68+ // Increase weight of filter in {formula} times
69+ weightModifier = ( float ) ( Pow ( distance + AntichatterOffsetX , AntichatterStrength * - 1 ) * AntichatterMultiplier ) ;
70+
71+ // Limit minimum
72+ if ( weightModifier + AntichatterOffsetY < 0 )
73+ weightModifier = 0 ;
74+ else
75+ weightModifier += AntichatterOffsetY ;
76+
77+ weightModifier = weight / weightModifier ;
78+ weightModifier = Clamp ( weightModifier , 0 , 1 ) ;
79+ _lastPos . X += ( float ) ( deltaX * weightModifier ) ;
80+ _lastPos . Y += ( float ) ( deltaY * weightModifier ) ;
81+
82+ // OTDPlugin 0.3.2 feature
83+ // TabletDriverPlugin.Log.Write("Antichatter", $"orig: ({point}) new: ({_lastPos}) dist: ({point.DistanceFrom(_lastPos)})", LogLevel.Debug);
84+ return _lastPos ;
85+ }
86+
87+ public FilterStage FilterStage => FilterStage . PostTranspose ;
88+
89+ [ SliderProperty ( "Latency" , 0f , 5f , 2f ) ]
90+ public float Latency
91+ {
92+ set => _latency = Clamp ( value , 0 , 1000 ) ;
93+ get => _latency ;
94+ }
95+
96+ [ UnitProperty ( "Timer Interval" , "hz" ) ]
97+ public float TimerInterval
98+ {
99+ set => _timerInterval = 1000f / value ;
100+ get => _timerInterval ;
101+ }
102+
103+ [ Property ( "Antichatter Strength" ) ]
104+ public float AntichatterStrength { set ; get ; } = 3 ;
105+
106+ [ Property ( "Antichatter Multiplier" ) ]
107+ public float AntichatterMultiplier { set ; get ; } = 1 ;
108+
109+ [ Property ( "Antichatter Offset X" ) ]
110+ public float AntichatterOffsetX { set ; get ; }
111+
112+ [ Property ( "Antichatter Offset Y" ) ]
113+ public float AntichatterOffsetY { set ; get ; }
114+
115+ [ BooleanProperty ( "Prediction" , "" ) ]
116+ public bool PredictionEnabled { set ; get ; }
117+
118+ [ Property ( "Prediction Strength" ) ]
119+ public float PredictionStrength { set ; get ; } = 1.1f ;
120+
121+ [ Property ( "Prediction Sharpness" ) ]
122+ public float PredictionSharpness { set ; get ; } = 1 ;
123+
124+ [ Property ( "Prediction Offset X" ) ]
125+ public float PredictionOffsetX { set ; get ; } = 3 ;
126+
127+ [ Property ( "Prediction Offset Y" ) ]
128+ public float PredictionOffsetY { set ; get ; } = 0.3f ;
129+ }
130+ }
0 commit comments