Created
November 28, 2014 10:18
-
-
Save Bradshaw/6bbe0059f39c50393577 to your computer and use it in GitHub Desktop.
Unity Implementation of the 1€ filter for input smoothing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
public struct FloatOneEuroData | |
{ | |
public float dx; | |
public float edx; | |
public float cutoff; | |
public float filthatxprev; | |
public float dfilthatxprev; | |
public bool firstTime; | |
} | |
public struct V2OneEuroData | |
{ | |
public Vector2 dx; | |
public Vector2 edx; | |
public float cutoff; | |
public Vector2 filthatxprev; | |
public Vector2 dfilthatxprev; | |
public bool firstTime; | |
} | |
public struct V3OneEuroData | |
{ | |
public Vector3 dx; | |
public Vector3 edx; | |
public float cutoff; | |
public Vector3 filthatxprev; | |
public Vector3 dfilthatxprev; | |
public bool firstTime; | |
} | |
public static class OneEuroExtensions { | |
public static Vector3 identity(this Vector3 v) | |
{ | |
return v; | |
} | |
static float alpha(float rate, float cutoff) | |
{ | |
float tau = 1 / (2 * Mathf.PI * cutoff); | |
float te = 1 / rate; | |
return 1 / (1 + tau / te); | |
} | |
public static float oneEuro(this float input, ref FloatOneEuroData euroData, float minCutoff = 1, float beta = 0.007f, float dCutoff = 1, float rate = 50) | |
{ | |
if (euroData.firstTime) | |
{ | |
euroData.dx = 0; | |
euroData.filthatxprev = input; | |
euroData.dfilthatxprev = 0; | |
euroData.firstTime = false; | |
} | |
else | |
{ | |
euroData.dx = (input - euroData.filthatxprev) * rate; | |
} | |
euroData.edx = euroData.dx.filter(alpha(rate, dCutoff), ref euroData.dfilthatxprev); | |
euroData.cutoff = minCutoff + beta * Mathf.Abs(euroData.edx); | |
return input.filter(alpha(rate, euroData.cutoff), ref euroData.filthatxprev); | |
} | |
public static Vector2 oneEuro(this Vector2 input, ref V2OneEuroData euroData, float minCutoff = 1, float beta = 0.007f, float dCutoff = 1, float rate = 50) | |
{ | |
if (euroData.firstTime) | |
{ | |
euroData.dx = Vector2.zero; | |
euroData.filthatxprev = input; | |
euroData.dfilthatxprev = Vector2.zero; | |
euroData.firstTime = false; | |
} | |
else | |
{ | |
euroData.dx = (input - euroData.filthatxprev) * rate; | |
} | |
euroData.edx = euroData.dx.filter(alpha(rate, dCutoff), ref euroData.dfilthatxprev); | |
euroData.cutoff = minCutoff + beta * euroData.edx.magnitude; | |
return input.filter(alpha(rate, euroData.cutoff), ref euroData.filthatxprev); | |
} | |
public static Vector3 oneEuro(this Vector3 input, ref V3OneEuroData euroData, float minCutoff = 1, float beta = 0.007f, float dCutoff = 1, float rate = 50) | |
{ | |
if (euroData.firstTime) | |
{ | |
euroData.dx = Vector3.zero; | |
euroData.filthatxprev = input; | |
euroData.dfilthatxprev = Vector3.zero; | |
euroData.firstTime = false; | |
} | |
else | |
{ | |
euroData.dx = (input - euroData.filthatxprev) * rate; | |
} | |
euroData.edx = euroData.dx.filter(alpha(rate, dCutoff), ref euroData.dfilthatxprev); | |
euroData.cutoff = minCutoff + beta * euroData.edx.magnitude; | |
return input.filter(alpha(rate, euroData.cutoff), ref euroData.filthatxprev); | |
} | |
static float filter(this float input, float alpha, ref float hatxprev) | |
{ | |
float hatx = input * alpha + hatxprev * (1 - alpha); | |
hatxprev = hatx; | |
return hatx; | |
} | |
static Vector2 filter(this Vector2 input, float alpha, ref Vector2 hatxprev) | |
{ | |
Vector2 hatx = input * alpha + hatxprev * (1 - alpha); | |
hatxprev = hatx; | |
return hatx; | |
} | |
static Vector3 filter(this Vector3 input, float alpha, ref Vector3 hatxprev) | |
{ | |
Vector3 hatx = input * alpha + hatxprev * (1 - alpha); | |
hatxprev = hatx; | |
return hatx; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
public class Wobbly : MonoBehaviour { | |
public GameObject go; | |
V3OneEuroData euroData; | |
// Use this for initialization | |
void Start () { | |
euroData.firstTime = true; | |
} | |
// Update is called once per frame | |
void Update () { | |
this.transform.position = go.transform.position.oneEuro(ref euroData); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment