Skip to content
This repository has been archived by the owner on Jan 1, 2024. It is now read-only.

Commit

Permalink
Add gyro mouse smoothing routine
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryochan7 committed Jun 29, 2017
1 parent 86816db commit 484337f
Show file tree
Hide file tree
Showing 6 changed files with 327 additions and 40 deletions.
86 changes: 80 additions & 6 deletions DS4Windows/DS4Control/MouseCursor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,20 @@ public enum Direction { Negative, Neutral, Positive }
private Direction horizontalDirection = Direction.Neutral, verticalDirection = Direction.Neutral;
private Direction hDirection = Direction.Neutral, vDirection = Direction.Neutral;

private double GYRO_MOUSE_COEFFICIENT = 0.0095;
private int GYRO_MOUSE_DEADZONE = 12;
private double GYRO_MOUSE_OFFSET = 0.1463;
private double GYRO_SMOOTH_MOUSE_OFFSET = 0.14698;

private const int SMOOTH_BUFFER_LEN = 3;
private double[] xSmoothBuffer = new double[SMOOTH_BUFFER_LEN];
private double[] ySmoothBuffer = new double[SMOOTH_BUFFER_LEN];
private int smoothBufferTail = 0;

double coefficient = 0.0;
double verticalScale = 0.0;
bool gyroSmooth = false;
//double gyroSmoothWeight = 0.0;

public virtual void sixaxisMoved(SixAxisEventArgs arg)
{
Expand All @@ -27,8 +40,20 @@ public virtual void sixaxisMoved(SixAxisEventArgs arg)
deltaY = -arg.sixAxis.gyroYFull;
//Console.WriteLine(arg.sixAxis.deltaX);

double coefficient = (Global.getGyroSensitivity(deviceNumber) * 0.01) * 0.0095;
double offset = 0.1463;
gyroSmooth = Global.getGyroSmoothing(deviceNumber);
double gyroSmoothWeight = 0.0;

coefficient = (Global.getGyroSensitivity(deviceNumber) * 0.01) * GYRO_MOUSE_COEFFICIENT;
double offset = GYRO_MOUSE_OFFSET;
if (gyroSmooth)
{
gyroSmoothWeight = Global.getGyroSmoothingWeight(deviceNumber);
if (gyroSmoothWeight > 0.0)
{
offset = GYRO_SMOOTH_MOUSE_OFFSET;
}
}

double tempAngle = System.Math.Atan2(-deltaY, deltaX);
double normX = System.Math.Abs(System.Math.Cos(tempAngle));
double normY = System.Math.Abs(System.Math.Sin(tempAngle));
Expand All @@ -45,7 +70,7 @@ public virtual void sixaxisMoved(SixAxisEventArgs arg)
vRemainder = 0.0;
}

int deadzone = 12;
int deadzone = GYRO_MOUSE_DEADZONE;
//int deadzone = 0;
int deadzoneX = (int)System.Math.Abs(normX * deadzone);
int deadzoneY = (int)System.Math.Abs(normY * deadzone);
Expand Down Expand Up @@ -73,12 +98,12 @@ public virtual void sixaxisMoved(SixAxisEventArgs arg)
if (xMotion != 0.0)
{
xMotion += hRemainder;
xAction = (int)xMotion;
hRemainder = xMotion - xAction;
//xAction = (int)xMotion;
//hRemainder = xMotion - xAction;
}
else
{
hRemainder = 0.0;
//hRemainder = 0.0;
}

//hRemainder -= (int)hRemainder;
Expand All @@ -88,6 +113,51 @@ public virtual void sixaxisMoved(SixAxisEventArgs arg)
if (yMotion != 0.0)
{
yMotion += vRemainder;
//yAction = (int)yMotion;
//vRemainder = yMotion - yAction;
}
else
{
//vRemainder = 0.0;
}

if (gyroSmooth)
{
int iIndex = smoothBufferTail % SMOOTH_BUFFER_LEN;
xSmoothBuffer[iIndex] = xMotion;
ySmoothBuffer[iIndex] = yMotion;
smoothBufferTail = iIndex + 1;

double currentWeight = 1.0;
double finalWeight = 0.0;
double x_out = 0.0, y_out = 0.0;
for (int i = 0; i < SMOOTH_BUFFER_LEN; i++)
{
int idx = System.Math.Abs(smoothBufferTail - i - 1) % SMOOTH_BUFFER_LEN;
x_out += xSmoothBuffer[idx] * currentWeight;
y_out += ySmoothBuffer[idx] * currentWeight;
finalWeight += currentWeight;
currentWeight *= gyroSmoothWeight;
}

x_out /= finalWeight;
xMotion = x_out;
y_out /= finalWeight;
yMotion = y_out;
}

if (xMotion != 0.0)
{
xAction = (int)xMotion;
hRemainder = xMotion - xAction;
}
else
{
hRemainder = 0.0;
}

if (yMotion != 0.0)
{
yAction = (int)yMotion;
vRemainder = yMotion - yAction;
}
Expand Down Expand Up @@ -115,6 +185,10 @@ public virtual void sixaxisMoved(SixAxisEventArgs arg)
public void mouseRemainderReset()
{
hRemainder = vRemainder = 0.0;
int iIndex = smoothBufferTail % SMOOTH_BUFFER_LEN;
xSmoothBuffer[iIndex] = 0.0;
ySmoothBuffer[iIndex] = 0.0;
smoothBufferTail = iIndex + 1;
}

public void touchesBegan(TouchpadEventArgs arg)
Expand Down
26 changes: 25 additions & 1 deletion DS4Windows/DS4Control/ScpUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,18 @@ public static bool getGyroTriggerTurns(int index)
return m_Config.gyroTriggerTurns[index];
}

public static bool[] GyroSmoothing => m_Config.gyroSmoothing;
public static bool getGyroSmoothing(int index)
{
return m_Config.gyroSmoothing[index];
}

public static double[] GyroSmoothingWeight => m_Config.gyroSmoothWeight;
public static double getGyroSmoothingWeight(int index)
{
return m_Config.gyroSmoothWeight[index];
}

public static DS4Color[] MainColor => m_Config.m_Leds;
public static DS4Color getMainColor(int index)
{
Expand Down Expand Up @@ -1240,6 +1252,8 @@ public class BackingStore
public int[] gyroSensVerticalScale = { 100, 100, 100, 100, 100 };
public int[] gyroInvert = { 0, 0, 0, 0, 0 };
public bool[] gyroTriggerTurns = { true, true, true, true, true };
public bool[] gyroSmoothing = { false, false, false, false, false };
public double[] gyroSmoothWeight = { 0.5, 0.5, 0.5, 0.5, 0.5 };

public BackingStore()
{
Expand Down Expand Up @@ -1450,6 +1464,8 @@ public bool SaveProfile(int device, string propath)
XmlNode xmlGyroSensVerticalScale = m_Xdoc.CreateNode(XmlNodeType.Element, "GyroSensVerticalScale", null); xmlGyroSensVerticalScale.InnerText = gyroSensVerticalScale[device].ToString(); Node.AppendChild(xmlGyroSensVerticalScale);
XmlNode xmlGyroInvert = m_Xdoc.CreateNode(XmlNodeType.Element, "GyroInvert", null); xmlGyroInvert.InnerText = gyroInvert[device].ToString(); Node.AppendChild(xmlGyroInvert);
XmlNode xmlGyroTriggerTurns = m_Xdoc.CreateNode(XmlNodeType.Element, "GyroTriggerTurns", null); xmlGyroTriggerTurns.InnerText = gyroTriggerTurns[device].ToString(); Node.AppendChild(xmlGyroTriggerTurns);
XmlNode xmlGyroSmoothWeight = m_Xdoc.CreateNode(XmlNodeType.Element, "GyroSmoothingWeight", null); xmlGyroSmoothWeight.InnerText = Convert.ToInt32(gyroSmoothWeight[device] * 100).ToString(); Node.AppendChild(xmlGyroSmoothWeight);
XmlNode xmlGyroSmoothing = m_Xdoc.CreateNode(XmlNodeType.Element, "GyroSmoothing", null); xmlGyroSmoothing.InnerText = gyroSmoothing[device].ToString(); Node.AppendChild(xmlGyroSmoothing);
XmlNode xmlLSC = m_Xdoc.CreateNode(XmlNodeType.Element, "LSCurve", null); xmlLSC.InnerText = lsCurve[device].ToString(); Node.AppendChild(xmlLSC);
XmlNode xmlRSC = m_Xdoc.CreateNode(XmlNodeType.Element, "RSCurve", null); xmlRSC.InnerText = rsCurve[device].ToString(); Node.AppendChild(xmlRSC);
XmlNode xmlProfileActions = m_Xdoc.CreateNode(XmlNodeType.Element, "ProfileActions", null); xmlProfileActions.InnerText = string.Join("/", profileActions[device]); Node.AppendChild(xmlProfileActions);
Expand Down Expand Up @@ -2368,6 +2384,12 @@ public bool LoadProfile(int device, bool launchprogram, ControlService control,
try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/GyroTriggerTurns"); bool.TryParse(Item.InnerText, out gyroTriggerTurns[device]); }
catch { gyroTriggerTurns[device] = true; missingSetting = true; }

try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/GyroSmoothing"); bool.TryParse(Item.InnerText, out gyroSmoothing[device]); }
catch { gyroSmoothing[device] = false; missingSetting = true; }

try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/GyroSmoothingWeight"); int temp = 0; int.TryParse(Item.InnerText, out temp); gyroSmoothWeight[device] = Convert.ToDouble(temp * 0.01); }
catch { gyroSmoothWeight[device] = 0.5; missingSetting = true; }

try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/LSCurve"); int.TryParse(Item.InnerText, out lsCurve[device]); }
catch { lsCurve[device] = 0; missingSetting = true; }

Expand Down Expand Up @@ -3419,9 +3441,11 @@ private void ResetProfile(int device)
gyroSensitivity[device] = 100;
gyroSensVerticalScale[device] = 100;
gyroInvert[device] = 0;
gyroTriggerTurns[device] = true;
gyroSmoothing[device] = false;
gyroSmoothWeight[device] = 0.5;
lsOutCurveMode[device] = 0;
rsOutCurveMode[device] = 0;
gyroTriggerTurns[device] = true;
}
}

Expand Down
56 changes: 52 additions & 4 deletions DS4Windows/DS4Forms/Options.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions DS4Windows/DS4Forms/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,9 @@ public void Reload(int deviceNum, string name)
cBGyroInvertY.Checked = invert == 1 || invert == 3;
if (s.Count > 0)
btnGyroTriggers.Text = string.Join(", ", s);

cBGyroSmooth.Checked = nUDGyroSmoothWeight.Enabled = GyroSmoothing[device];
nUDGyroSmoothWeight.Value = (decimal)(GyroSmoothingWeight[device]);
}
else
{
Expand Down Expand Up @@ -667,6 +670,8 @@ public void Reload(int deviceNum, string name)
gyroTriggerBehavior.Checked = true;
cBGyroInvertX.Checked = false;
cBGyroInvertY.Checked = false;
cBGyroSmooth.Checked = false;
nUDGyroSmoothWeight.Value = 0.5m;
Set();
}

Expand Down Expand Up @@ -1324,6 +1329,8 @@ public void Set()
GyroSensitivity[device] = (int)Math.Round(nUDGyroSensitivity.Value, 0);
GyroTriggerTurns[device] = gyroTriggerBehavior.Checked;
GyroSensVerticalScale[device] = (int)nUDGyroMouseVertScale.Value;
GyroSmoothing[device] = cBGyroSmooth.Checked;
GyroSmoothingWeight[device] = (double)nUDGyroSmoothWeight.Value;

int invert = 0;
if (cBGyroInvertX.Checked)
Expand Down Expand Up @@ -2828,6 +2835,24 @@ private void nUDGyroMouseVertScale_ValueChanged(object sender, EventArgs e)
}
}

private void nUDGyroSmoothWeight_ValueChanged(object sender, EventArgs e)
{
if (!loading)
{
GyroSmoothingWeight[device] = (double)nUDGyroSmoothWeight.Value;
}
}

private void cBGyroSmooth_CheckedChanged(object sender, EventArgs e)
{
bool value = cBGyroSmooth.Checked;
nUDGyroSmoothWeight.Enabled = value;
if (!loading)
{
GyroSmoothing[device] = value;
}
}

private void Options_Resize(object sender, EventArgs e)
{
fLPSettings.AutoScroll = false;
Expand Down
Loading

0 comments on commit 484337f

Please sign in to comment.