Skip to content

Instantly share code, notes, and snippets.

@provencher
Created May 22, 2020 16:57
Show Gist options
  • Select an option

  • Save provencher/84788ebd878e72144193e331150a652c to your computer and use it in GitHub Desktop.

Select an option

Save provencher/84788ebd878e72144193e331150a652c to your computer and use it in GitHub Desktop.
Hand data processing to determine finger curls
public class HandDataProcessor : MonoBehaviour
{
private const float cThumbLength = 0.05f;
private const float cIndexLength = 0.08f;
private const float cMiddleLength = 0.09f;
[Header("Left Hand")]
[SerializeField]
private BoolReader _isLeftHandTracked = null;
[SerializeField]
private Vector3Reader _leftIndexPos = null;
[SerializeField]
private Vector3Reader _leftHandPalmPos = null;
[SerializeField]
private Vector3Reader _leftHandMiddleTipPos = null;
[SerializeField]
private Vector3Reader _leftHandThumbTipPos = null;
[Header("Right Hand")]
[SerializeField]
private BoolReader _isRightHandTracked = null;
[SerializeField]
private Vector3Reader _rightIndexPos = null;
[SerializeField]
private Vector3Reader _rightHandPalmPos = null;
[SerializeField]
private Vector3Reader _rightHandMiddleTipPos = null;
[SerializeField]
private Vector3Reader _rightHandThumbTipPos = null;
[Header("Curl Data Holders")]
[SerializeField]
private FloatWriter _leftIndexCurl = null;
[SerializeField]
private FloatWriter _lefThumbCurl = null;
[SerializeField]
private FloatWriter _leftMiddleCurl = null;
[Space]
[SerializeField]
private FloatWriter _rightIndexCurl = null;
[SerializeField]
private FloatWriter _rightThumbCurl = null;
[SerializeField]
private FloatWriter _rightMiddleCurl = null;
[Header("Curl Values")]
public bool ShouldUpdateLeftHand = true;
[Range(0f, 1f)]
public float LeftThumbRatio;
[Range(0f, 1f)]
public float LeftIndexRatio;
[Range(0f, 1f)]
public float LeftMiddleRatio;
[Space]
public bool ShouldUpdateRightHand = true;
[Range(0f, 1f)]
public float RightThumbRatio;
[Range(0f, 1f)]
public float RightIndexRatio;
[Range(0f, 1f)]
public float RightMiddleRatio;
void Update()
{
UpdateLeftHand();
UpdateRightHand();
UpdateCurls();
}
private void UpdateCurls()
{
// Left
if (ShouldUpdateLeftHand)
{
if (!Mathf.Approximately(_lefThumbCurl.value, LeftThumbRatio))
{
_lefThumbCurl.value = LeftThumbRatio;
}
if (!Mathf.Approximately(_leftIndexCurl.value, LeftIndexRatio))
{
_leftIndexCurl.value = LeftIndexRatio;
}
if (!Mathf.Approximately(_leftMiddleCurl.value, LeftMiddleRatio))
{
_leftMiddleCurl.value = LeftMiddleRatio;
}
}
// Right
if (ShouldUpdateRightHand)
{
if (!Mathf.Approximately(_rightThumbCurl.value, RightThumbRatio))
{
_rightThumbCurl.value = RightThumbRatio;
}
if (!Mathf.Approximately(_rightIndexCurl.value, RightIndexRatio))
{
_rightIndexCurl.value = RightIndexRatio;
}
if (!Mathf.Approximately(_rightMiddleCurl.value, RightMiddleRatio))
{
_rightMiddleCurl.value = RightMiddleRatio;
}
}
}
private void UpdateLeftHand()
{
if (!_isLeftHandTracked.value) return;
LeftThumbRatio = GetFingerToPalmRatio(_leftHandThumbTipPos.value, _leftHandPalmPos.value, cThumbLength);
LeftIndexRatio = GetFingerToPalmRatio(_leftIndexPos.value, _leftHandPalmPos.value, cIndexLength);
LeftMiddleRatio = GetFingerToPalmRatio(_leftHandMiddleTipPos.value, _leftHandPalmPos.value, cMiddleLength);
}
private void UpdateRightHand()
{
if (!_isRightHandTracked.value) return;
RightThumbRatio = GetFingerToPalmRatio(_rightHandThumbTipPos.value, _rightHandPalmPos.value, cThumbLength);
RightIndexRatio = GetFingerToPalmRatio(_rightIndexPos.value, _rightHandPalmPos.value, cIndexLength);
RightMiddleRatio = GetFingerToPalmRatio(_rightHandMiddleTipPos.value, _rightHandPalmPos.value, cMiddleLength);
}
/// <summary>
/// Converts finger position relative to palm as approximate curl value
/// </summary>
/// <param name="finger">Position of finger to check curl value of</param>
/// <param name="palm">Position of palm to compute approximate curl from</param>
/// <param name="fingerLength">Approximate length of finger to estimate accurate curl</param>
/// <param name="bias">Approximate value used to zero the fully closed finger</param>
/// <returns></returns>
private float GetFingerToPalmRatio(Vector3 finger, Vector3 palm, float fingerLength, float bias = 0.03f)
{
return Mathf.Clamp01((Vector3.Distance(finger, palm) - bias) / fingerLength);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment