using UnityEngine;
using System.Collections;
public class HandsWave : MonoBehaviour {
public GameObject leftHand;
public GameObject rightHand;
public GameObject rightElbow;
public KinectPointController kpc;
private SkeletonWrapper sw;
private Vector3 leftPos;
private Vector3 rightPos;
private Vector3 elbowRightPos;
int player = 0;
private const int WAVE_MOVEMENT_TIMEOUT = 5000;
private const float WAVE_THRESHOLD = 0.1f;
private const int REQUIRED_ITERATIONS = 1;
private Kinect.KinectInterface kinect;
public DeviceOrEmulator devOrEmu;
WaveGestureTracker tracker = new WaveGestureTracker();
//
private enum WavePosition
{
None = 0,
Left = 1,
Right = 2,
Neutral = 3
}
private enum WaveGestureState
{
None = 0,
Success = 1,
Failure = 2,
InProgress = 3
}
private struct WaveGestureTracker
{
public int IterationCount;
public WaveGestureState State;
public long Timestamp;
public WavePosition StartPosition;
public WavePosition CurrentPosition;
public void UpdateState(WaveGestureState state, long timestamp)
{
State = state;
Timestamp = timestamp;
}
public void Reset()
{
IterationCount = 0;
State = WaveGestureState.None;
Timestamp = 0;
StartPosition = WavePosition.None;
CurrentPosition = WavePosition.None;
}
public void UpdatePosition(WavePosition position, long timestamp)
{
if (CurrentPosition != position)
{
if (position == WavePosition.Left || position == WavePosition.Right)
{
if (State != WaveGestureState.InProgress)
{
State = WaveGestureState.InProgress;
IterationCount = 0;
StartPosition = position;
}
IterationCount++;
}
CurrentPosition = position;
Timestamp = timestamp;
}
}
}
//
// Use this for initialization
void Start()
{
sw = kpc.sw;
kinect = devOrEmu.getKinect();
StartCoroutine(LoopCheck());
}
// Update is called once per frame
void Update () {
}
IEnumerator LoopCheck()
{
while (true)
{
CheckHands();
yield return new WaitForSeconds(0.1f);
}
}
void CheckHands()
{
leftPos = leftHand.transform.position;
rightPos = rightHand.transform.position;
elbowRightPos = rightElbow.transform.position;
long timestamp = kinect.getSkeleton().liTimeStamp;
if (sw.boneState[player, (int)Kinect.NuiSkeletonPositionIndex.HandLeft] != Kinect.NuiSkeletonPositionTrackingState.NotTracked || sw.boneState[player, (int)Kinect.NuiSkeletonPositionIndex.HandRight] != Kinect.NuiSkeletonPositionTrackingState.NotTracked)
{
if (tracker.State == WaveGestureState.InProgress && tracker.Timestamp + WAVE_MOVEMENT_TIMEOUT < timestamp)
{
tracker.UpdateState(WaveGestureState.Failure, timestamp);
Debug.Log("Fail!");
}
else if (leftPos.x < rightPos.x && rightPos.y > elbowRightPos.y)// 双手未交叉
{
//使用 (0, 0) 作为屏幕的中心. 从用户的视角看, X轴左负右正.
if (rightPos.x <= elbowRightPos.x - WAVE_THRESHOLD)
{
tracker.UpdatePosition(WavePosition.Left, timestamp);
}
else if (rightPos.x >= elbowRightPos.x + WAVE_THRESHOLD)
{
tracker.UpdatePosition(WavePosition.Right, timestamp);
}
else
{
tracker.UpdatePosition(WavePosition.Neutral, timestamp);
}
if (tracker.State != WaveGestureState.Success && tracker.IterationCount == REQUIRED_ITERATIONS)
{
tracker.UpdateState(WaveGestureState.Success, timestamp);
Debug.Log("Success" + tracker.CurrentPosition);
//if (GestureDetected != null)
//{
// GestureDetected(this, new EventArgs());
//}
}
}
else
{
if (tracker.State == WaveGestureState.InProgress)
{
tracker.UpdateState(WaveGestureState.Failure, timestamp);
System.Diagnostics.Debug.WriteLine("Fail!");
}
else
{
tracker.Reset();
}
}
}
else
{
tracker.Reset();
//Debug.Log("NotTracked");
}
}
}