Skip to content

Commit 4a5f508

Browse files
authored
Merge pull request #7 from InfinityGhost/interp
Migrate to Interpolator and make use of SIMD
2 parents d52c43d + 4a02caa commit 4a5f508

3 files changed

Lines changed: 87 additions & 72 deletions

File tree

.modules/OpenTabletDriver

Submodule OpenTabletDriver updated 47 files

DevocubFilters/AntiChatter.cs

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,80 @@
22
using System.Numerics;
33
using OpenTabletDriver.Plugin.Attributes;
44
using OpenTabletDriver.Plugin.Tablet;
5+
using OpenTabletDriver.Plugin.Tablet.Interpolator;
6+
using OpenTabletDriver.Plugin.Timers;
57

68
namespace 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")]

HawkuFilters/Smoothing.cs

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,70 @@
22
using System.Numerics;
33
using OpenTabletDriver.Plugin.Attributes;
44
using OpenTabletDriver.Plugin.Tablet;
5+
using OpenTabletDriver.Plugin.Tablet.Interpolator;
6+
using OpenTabletDriver.Plugin.Timers;
57

68
namespace TabletDriverFilters.Hawku
79
{
810
using static Math;
911

1012
[PluginName("TabletDriver Smoothing Filter")]
11-
public class Smoothing : IFilter
13+
public class Smoothing : Interpolator
1214
{
13-
private DateTime? _lastFilterTime;
14-
private Vector2 _lastPos;
15-
private float _timerInterval;
16-
private const float _threshold = 0.63f;
15+
public Smoothing(ITimer scheduler) : base(scheduler) { }
1716

18-
public Vector2 Filter(Vector2 point)
17+
private DateTime? lastFilterTime;
18+
private Vector3 targetPos;
19+
private Vector3 lastPos;
20+
private SyntheticTabletReport report;
21+
private const float threshold = 0.63f;
22+
23+
public override void UpdateState(SyntheticTabletReport report)
24+
{
25+
this.targetPos = new Vector3(report.Position, report.Pressure);
26+
this.report = report;
27+
}
28+
29+
public override SyntheticTabletReport Interpolate()
30+
{
31+
var newPoint = Filter(this.targetPos);
32+
report.Position = new Vector2(newPoint.X, newPoint.Y);
33+
report.Pressure = (uint)newPoint.Z;
34+
return report;
35+
}
36+
37+
public Vector3 Filter(Vector3 point)
1938
{
20-
var timeDelta = DateTime.Now - _lastFilterTime;
39+
var timeDelta = DateTime.Now - this.lastFilterTime;
2140
// If a time difference hasn't been established or it has been 100 milliseconds since the last filter
22-
if (timeDelta == null || timeDelta.Value.TotalMilliseconds > 100 || _lastPos == null)
41+
if (timeDelta == null || timeDelta.Value.TotalMilliseconds > 100)
2342
{
24-
SetPreviousState(point);
43+
this.lastPos = point;
44+
this.lastFilterTime = DateTime.Now;
2545
return point;
2646
}
2747
else
2848
{
29-
Vector2 pos = new Vector2(_lastPos.X, _lastPos.Y);
30-
float deltaX = point.X - _lastPos.X;
31-
float deltaY = point.Y - _lastPos.Y;
49+
Vector3 delta = point - this.lastPos;
3250

3351
double stepCount = Latency / TimerInterval;
34-
double target = 1 - _threshold;
52+
double target = 1 - threshold;
3553
double weight = 1.0 - (1.0 / Pow(1.0 / target, 1.0 / stepCount));
3654

37-
pos.X += (float)(deltaX * weight);
38-
pos.Y += (float)(deltaY * weight);
39-
SetPreviousState(pos);
40-
return pos;
55+
this.lastPos += delta * (float)weight;
56+
this.lastFilterTime = DateTime.Now;
57+
return this.lastPos;
4158
}
4259
}
4360

44-
private void SetPreviousState(Vector2 lastPosition)
45-
{
46-
_lastPos = lastPosition;
47-
_lastFilterTime = DateTime.Now;
48-
}
49-
50-
public FilterStage FilterStage => FilterStage.PostTranspose;
61+
public static FilterStage FilterStage => FilterStage.PostTranspose;
5162

52-
[SliderProperty("Latency", 0f, 5f, 2f)]
53-
public float Latency { set; get; }
63+
[SliderProperty("Latency", 0f, 1000f, 2f)]
64+
public float Latency { set; get; } = 2f;
5465

55-
[Property("Timer Interval"), Unit("hz")]
5666
public float TimerInterval
5767
{
58-
set => _timerInterval = 1000f / value;
59-
get => _timerInterval;
68+
get => 1000 / Hertz;
6069
}
6170
}
6271
}

0 commit comments

Comments
 (0)