You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2281 lines
115 KiB
2281 lines
115 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace com.rfilkov.kinect
|
|
{
|
|
/// <summary>
|
|
/// This interface needs to be implemented by all Kinect gesture listeners
|
|
/// </summary>
|
|
public interface GestureListenerInterface
|
|
{
|
|
/// <summary>
|
|
/// Invoked when a new user is detected. Here you can start gesture tracking by invoking KinectManager.DetectGesture()-function.
|
|
/// </summary>
|
|
/// <param name="userId">User ID</param>
|
|
/// <param name="userIndex">User index</param>
|
|
void UserDetected(ulong userId, int userIndex);
|
|
|
|
/// <summary>
|
|
/// Invoked when a user gets lost. All tracked gestures for this user are cleared automatically.
|
|
/// </summary>
|
|
/// <param name="userId">User ID</param>
|
|
/// <param name="userIndex">User index</param>
|
|
void UserLost(ulong userId, int userIndex);
|
|
|
|
/// <summary>
|
|
/// Invoked when a gesture is in progress.
|
|
/// </summary>
|
|
/// <param name="userId">User ID</param>
|
|
/// <param name="userIndex">User index</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
/// <param name="progress">Gesture progress [0..1]</param>
|
|
/// <param name="joint">Joint type</param>
|
|
/// <param name="screenPos">Normalized viewport position</param>
|
|
void GestureInProgress(ulong userId, int userIndex, GestureType gesture, float progress,
|
|
KinectInterop.JointType joint, Vector3 screenPos);
|
|
|
|
/// <summary>
|
|
/// Invoked if a gesture is completed.
|
|
/// </summary>
|
|
/// <returns><c>true</c>, if the gesture detection must be restarted, <c>false</c> otherwise.</returns>
|
|
/// <param name="userId">User ID</param>
|
|
/// <param name="userIndex">User index</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
/// <param name="joint">Joint type</param>
|
|
/// <param name="screenPos">Normalized viewport position</param>
|
|
bool GestureCompleted(ulong userId, int userIndex, GestureType gesture,
|
|
KinectInterop.JointType joint, Vector3 screenPos);
|
|
|
|
/// <summary>
|
|
/// Invoked if a gesture is cancelled.
|
|
/// </summary>
|
|
/// <returns><c>true</c>, if the gesture detection must be retarted, <c>false</c> otherwise.</returns>
|
|
/// <param name="userId">User ID</param>
|
|
/// <param name="userIndex">User index</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
/// <param name="joint">Joint type</param>
|
|
bool GestureCancelled(ulong userId, int userIndex, GestureType gesture,
|
|
KinectInterop.JointType joint);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Kinect gesture types.
|
|
/// </summary>
|
|
public enum GestureType
|
|
{
|
|
None = 0,
|
|
RaiseRightHand,
|
|
RaiseLeftHand,
|
|
Psi,
|
|
Tpose,
|
|
Stop,
|
|
Wave,
|
|
SwipeLeft,
|
|
SwipeRight,
|
|
SwipeUp,
|
|
SwipeDown,
|
|
ZoomIn,
|
|
ZoomOut,
|
|
Wheel,
|
|
Jump,
|
|
Squat,
|
|
Push,
|
|
Pull,
|
|
ShoulderLeftFront,
|
|
ShoulderRightFront,
|
|
LeanLeft,
|
|
LeanRight,
|
|
LeanForward,
|
|
LeanBack,
|
|
KickLeft,
|
|
KickRight,
|
|
Run,
|
|
|
|
RaisedRightHorizontalLeftHand, // by Andrzej W
|
|
RaisedLeftHorizontalRightHand,
|
|
|
|
TouchRightElbow, // suggested by Nayden N.
|
|
TouchLeftElbow,
|
|
|
|
MoveLeft, // suggested by Indra Adi D. C
|
|
MoveRight,
|
|
|
|
Apose, // suggested by avrxpert
|
|
|
|
UserGesture1 = 101,
|
|
UserGesture2 = 102,
|
|
UserGesture3 = 103,
|
|
UserGesture4 = 104,
|
|
UserGesture5 = 105,
|
|
UserGesture6 = 106,
|
|
UserGesture7 = 107,
|
|
UserGesture8 = 108,
|
|
UserGesture9 = 109,
|
|
UserGesture10 = 110,
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Kinect gesture manager is the component that tracks and processes the user gestures.
|
|
/// </summary>
|
|
public class KinectGestureManager : MonoBehaviour
|
|
{
|
|
|
|
/// <summary>
|
|
/// Programmatic gesture data container.
|
|
/// </summary>
|
|
public struct GestureData
|
|
{
|
|
public ulong userId;
|
|
public GestureType gesture;
|
|
public int state;
|
|
public float timestamp;
|
|
public int joint;
|
|
public Vector3 jointPos;
|
|
public Vector3 screenPos;
|
|
public float tagFloat;
|
|
public Vector3 tagVector;
|
|
public Vector3 tagVector2;
|
|
public float progress;
|
|
public bool complete;
|
|
public bool cancelled;
|
|
public List<GestureType> checkForGestures;
|
|
public float startTrackingAtTime;
|
|
}
|
|
|
|
|
|
[Tooltip("Minimum time between gesture detections (in seconds).")]
|
|
public float minTimeBetweenGestures = 0.7f;
|
|
|
|
[Tooltip("List of the gesture listeners in the scene. If the list is empty, the available gesture listeners will be detected at the scene start up.")]
|
|
public List<MonoBehaviour> gestureListeners = new List<MonoBehaviour>();
|
|
|
|
[Tooltip("UI-Text to display the status of the currently tracked gestures.")]
|
|
public UnityEngine.UI.Text gestureDebugText;
|
|
|
|
[Tooltip("Prefab used to display the joint positions on screen.")]
|
|
public GameObject jointDebugPrefab;
|
|
|
|
|
|
// Gesture related constants, variables and functions
|
|
protected int leftHandIndex;
|
|
protected int rightHandIndex;
|
|
|
|
protected int leftFingerIndex;
|
|
protected int rightFingerIndex;
|
|
|
|
protected int leftElbowIndex;
|
|
protected int rightElbowIndex;
|
|
|
|
protected int leftShoulderIndex;
|
|
protected int rightShoulderIndex;
|
|
|
|
protected int leftClavicleIndex;
|
|
protected int rightClavicleIndex;
|
|
|
|
protected int hipCenterIndex;
|
|
protected int neckIndex;
|
|
|
|
protected int leftHipIndex;
|
|
protected int rightHipIndex;
|
|
|
|
protected int leftKneeIndex;
|
|
protected int rightKneeIndex;
|
|
|
|
protected int leftAnkleIndex;
|
|
protected int rightAnkleIndex;
|
|
|
|
// gestures data and parameters
|
|
protected Dictionary<ulong, List<KinectGestureManager.GestureData>> playerGesturesData = new Dictionary<ulong, List<KinectGestureManager.GestureData>>();
|
|
protected Dictionary<ulong, float> gesturesTrackingAtTime = new Dictionary<ulong, float>();
|
|
|
|
// transformation matrix of the primary body sensor (used to apply the sensor orientation transformation)
|
|
//protected Matrix4x4 matBodySensor = Matrix4x4.identity;
|
|
|
|
// game objects used for joint debugging
|
|
private GameObject[] debugJoints = null;
|
|
|
|
/// <summary>
|
|
/// Adds a gesture to the list of detected gestures for the specified user.
|
|
/// </summary>
|
|
/// <param name="UserId">User ID</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
public void DetectGesture(ulong UserId, GestureType gesture)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : new List<GestureData>();
|
|
int index = GetGestureIndex(gesture, ref gesturesData);
|
|
|
|
if (index >= 0)
|
|
{
|
|
DeleteGesture(UserId, gesture);
|
|
}
|
|
|
|
GestureData gestureData = new GestureData();
|
|
|
|
gestureData.userId = UserId;
|
|
gestureData.gesture = gesture;
|
|
gestureData.state = 0;
|
|
gestureData.joint = 0;
|
|
gestureData.progress = 0f;
|
|
gestureData.complete = false;
|
|
gestureData.cancelled = false;
|
|
|
|
gestureData.checkForGestures = new List<GestureType>();
|
|
switch (gesture)
|
|
{
|
|
case GestureType.ZoomIn:
|
|
gestureData.checkForGestures.Add(GestureType.ZoomOut);
|
|
gestureData.checkForGestures.Add(GestureType.Wheel);
|
|
break;
|
|
|
|
case GestureType.ZoomOut:
|
|
gestureData.checkForGestures.Add(GestureType.ZoomIn);
|
|
gestureData.checkForGestures.Add(GestureType.Wheel);
|
|
break;
|
|
|
|
case GestureType.Wheel:
|
|
gestureData.checkForGestures.Add(GestureType.ZoomIn);
|
|
gestureData.checkForGestures.Add(GestureType.ZoomOut);
|
|
break;
|
|
}
|
|
|
|
gesturesData.Add(gestureData);
|
|
playerGesturesData[UserId] = gesturesData;
|
|
|
|
if (!gesturesTrackingAtTime.ContainsKey(UserId))
|
|
{
|
|
gesturesTrackingAtTime[UserId] = 0f;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets the gesture state for the given gesture of the specified user.
|
|
/// </summary>
|
|
/// <returns><c>true</c>, if gesture was reset, <c>false</c> otherwise.</returns>
|
|
/// <param name="UserId">User ID</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
public bool ResetGesture(ulong UserId, GestureType gesture)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
int index = gesturesData != null ? GetGestureIndex(gesture, ref gesturesData) : -1;
|
|
if (index < 0)
|
|
return false;
|
|
|
|
GestureData gestureData = gesturesData[index];
|
|
|
|
gestureData.state = 0;
|
|
gestureData.joint = 0;
|
|
gestureData.progress = 0f;
|
|
gestureData.complete = false;
|
|
gestureData.cancelled = false;
|
|
gestureData.startTrackingAtTime = Time.realtimeSinceStartup + KinectInterop.Constants.MinTimeBetweenSameGestures;
|
|
|
|
gesturesData[index] = gestureData;
|
|
playerGesturesData[UserId] = gesturesData;
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets the gesture states for all gestures of the specified user.
|
|
/// </summary>
|
|
/// <param name="UserId">User ID</param>
|
|
public void ResetPlayerGestures(ulong UserId)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
|
|
if (gesturesData != null)
|
|
{
|
|
int listSize = gesturesData.Count;
|
|
|
|
for (int i = 0; i < listSize; i++)
|
|
{
|
|
ResetGesture(UserId, gesturesData[i].gesture);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes the gesture for the specified user.
|
|
/// </summary>
|
|
/// <returns><c>true</c>, if gesture was deleted, <c>false</c> otherwise.</returns>
|
|
/// <param name="UserId">User ID</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
public bool DeleteGesture(ulong UserId, GestureType gesture)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
int index = gesturesData != null ? GetGestureIndex(gesture, ref gesturesData) : -1;
|
|
if (index < 0)
|
|
return false;
|
|
|
|
gesturesData.RemoveAt(index);
|
|
playerGesturesData[UserId] = gesturesData;
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes all gestures for the specified user.
|
|
/// </summary>
|
|
/// <param name="UserId">User ID</param>
|
|
public void ClearUserGestures(ulong UserId)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
|
|
if (gesturesData != null)
|
|
{
|
|
gesturesData.Clear();
|
|
playerGesturesData[UserId] = gesturesData;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the list of gestures for the specified user.
|
|
/// </summary>
|
|
/// <returns>The gestures list.</returns>
|
|
/// <param name="UserId">User ID</param>
|
|
public List<GestureType> GetGesturesList(ulong UserId)
|
|
{
|
|
List<GestureType> list = new List<GestureType>();
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
|
|
if (gesturesData != null)
|
|
{
|
|
foreach (GestureData data in gesturesData)
|
|
list.Add(data.gesture);
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the gestures count for the specified user.
|
|
/// </summary>
|
|
/// <returns>The gestures count.</returns>
|
|
/// <param name="UserId">User ID</param>
|
|
public int GetGesturesCount(ulong UserId)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
|
|
if (gesturesData != null)
|
|
{
|
|
return gesturesData.Count;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the gesture at the specified index for the given user.
|
|
/// </summary>
|
|
/// <returns>The gesture at specified index.</returns>
|
|
/// <param name="UserId">User ID</param>
|
|
/// <param name="i">Index</param>
|
|
public GestureType GetGestureAtIndex(ulong UserId, int i)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
|
|
if (gesturesData != null)
|
|
{
|
|
if (i >= 0 && i < gesturesData.Count)
|
|
{
|
|
return gesturesData[i].gesture;
|
|
}
|
|
}
|
|
|
|
return GestureType.None;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether the given gesture is in the list of gestures for the specified user.
|
|
/// </summary>
|
|
/// <returns><c>true</c> if the gesture is in the list of gestures for the specified user; otherwise, <c>false</c>.</returns>
|
|
/// <param name="UserId">User ID</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
public bool IsTrackingGesture(ulong UserId, GestureType gesture)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
int index = gesturesData != null ? GetGestureIndex(gesture, ref gesturesData) : -1;
|
|
|
|
return index >= 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether the given gesture for the specified user is complete.
|
|
/// </summary>
|
|
/// <returns><c>true</c> if the gesture is complete; otherwise, <c>false</c>.</returns>
|
|
/// <param name="UserId">User ID</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
/// <param name="bResetOnComplete">If set to <c>true</c>, resets the gesture state.</param>
|
|
public bool IsGestureComplete(ulong UserId, GestureType gesture, bool bResetOnComplete)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
int index = gesturesData != null ? GetGestureIndex(gesture, ref gesturesData) : -1;
|
|
|
|
if (index >= 0)
|
|
{
|
|
GestureData gestureData = gesturesData[index];
|
|
|
|
if (bResetOnComplete && gestureData.complete)
|
|
{
|
|
ResetPlayerGestures(UserId);
|
|
return true;
|
|
}
|
|
|
|
return gestureData.complete;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether the given gesture for the specified user is canceled.
|
|
/// </summary>
|
|
/// <returns><c>true</c> if the gesture is canceled; otherwise, <c>false</c>.</returns>
|
|
/// <param name="UserId">User ID</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
public bool IsGestureCancelled(ulong UserId, GestureType gesture)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
int index = gesturesData != null ? GetGestureIndex(gesture, ref gesturesData) : -1;
|
|
|
|
if (index >= 0)
|
|
{
|
|
GestureData gestureData = gesturesData[index];
|
|
return gestureData.cancelled;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the progress (in range [0, 1]) of the given gesture for the specified user.
|
|
/// </summary>
|
|
/// <returns>The gesture progress.</returns>
|
|
/// <param name="UserId">User ID</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
public float GetGestureProgress(ulong UserId, GestureType gesture)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
int index = gesturesData != null ? GetGestureIndex(gesture, ref gesturesData) : -1;
|
|
|
|
if (index >= 0)
|
|
{
|
|
GestureData gestureData = gesturesData[index];
|
|
return gestureData.progress;
|
|
}
|
|
|
|
return 0f;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the normalized screen position of the given gesture for the specified user.
|
|
/// </summary>
|
|
/// <returns>The normalized screen position.</returns>
|
|
/// <param name="UserId">User ID</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
public Vector3 GetGestureScreenPos(ulong UserId, GestureType gesture)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
int index = gesturesData != null ? GetGestureIndex(gesture, ref gesturesData) : -1;
|
|
|
|
if (index >= 0)
|
|
{
|
|
GestureData gestureData = gesturesData[index];
|
|
return gestureData.screenPos;
|
|
}
|
|
|
|
return Vector3.zero;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets latest gesture timestamp.
|
|
/// </summary>
|
|
/// <param name="UserId">User ID</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
/// <returns>Latest timestamp</returns>
|
|
public float GetGestureTimestamp(ulong UserId, GestureType gesture)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
int index = gesturesData != null ? GetGestureIndex(gesture, ref gesturesData) : -1;
|
|
|
|
if (index >= 0)
|
|
{
|
|
GestureData gestureData = gesturesData[index];
|
|
return gestureData.timestamp;
|
|
}
|
|
|
|
return 0f;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets current gesture state.
|
|
/// </summary>
|
|
/// <param name="UserId">User ID</param>
|
|
/// <param name="gesture">Gesture type</param>
|
|
/// <returns>Current gesture state</returns>
|
|
public int GetGestureState(ulong UserId, GestureType gesture)
|
|
{
|
|
List<GestureData> gesturesData = playerGesturesData.ContainsKey(UserId) ? playerGesturesData[UserId] : null;
|
|
int index = gesturesData != null ? GetGestureIndex(gesture, ref gesturesData) : -1;
|
|
|
|
if (index >= 0)
|
|
{
|
|
GestureData gestureData = gesturesData[index];
|
|
return gestureData.state;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Locate the available gesture listeners.
|
|
/// </summary>
|
|
public void RefreshGestureListeners()
|
|
{
|
|
gestureListeners.Clear();
|
|
|
|
MonoBehaviour[] monoScripts = FindObjectsOfType<MonoBehaviour>() as MonoBehaviour[];
|
|
foreach (MonoBehaviour monoScript in monoScripts)
|
|
{
|
|
if ((monoScript is GestureListenerInterface) && monoScript.enabled)
|
|
{
|
|
//GestureListenerInterface gl = (GestureListenerInterface)monoScript;
|
|
gestureListeners.Add(monoScript);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Invoked when a new user gets detected.
|
|
/// </summary>
|
|
/// <param name="userId">User ID</param>
|
|
/// <param name="userIndex">User index</param>
|
|
public void UserWasAdded(ulong userId, int userIndex)
|
|
{
|
|
//Debug.Log("GM - UserAdded: " + userId);
|
|
|
|
//// add the gestures to be detected by all users, if any
|
|
//foreach (GestureType gesture in playerCommonGestures)
|
|
//{
|
|
// DetectGesture(userId, gesture);
|
|
//}
|
|
|
|
// notify all gesture listeners of the newly detected user
|
|
foreach (GestureListenerInterface listener in gestureListeners)
|
|
{
|
|
if (listener != null)
|
|
{
|
|
listener.UserDetected(userId, userIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Invoked when user was removed.
|
|
/// </summary>
|
|
/// <param name="userId">User ID</param>
|
|
/// <param name="userIndex">User index</param>
|
|
public void UserWasRemoved(ulong userId, int userIndex)
|
|
{
|
|
//Debug.Log("GM - UserRemoved: " + userId);
|
|
|
|
// notify all gesture listeners for losing this user
|
|
foreach (GestureListenerInterface listener in gestureListeners)
|
|
{
|
|
if (listener != null)
|
|
{
|
|
listener.UserLost(userId, userIndex);
|
|
}
|
|
}
|
|
|
|
// clear the user gestures
|
|
ClearUserGestures(userId);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Updates the progress of the given user's gestures.
|
|
/// </summary>
|
|
/// <param name="userId">User ID</param>
|
|
/// <param name="kinectManager">Reference to the KinectManager</param>
|
|
public void UpdateUserGestures(ulong userId, KinectManager kinectManager)
|
|
{
|
|
if (!playerGesturesData.ContainsKey(userId))
|
|
return;
|
|
|
|
//Debug.Log("GM - UpdateGestures for user: " + userId);
|
|
|
|
// Check for player's gestures
|
|
CheckForGestures(userId, kinectManager);
|
|
|
|
// Check for complete gestures
|
|
List<GestureData> gesturesData = playerGesturesData[userId];
|
|
int userIndex = kinectManager.GetUserIndexById(userId);
|
|
|
|
for (int g = 0; g < gesturesData.Count; g++)
|
|
{
|
|
GestureData gestureData = gesturesData[g];
|
|
|
|
if (gestureData.complete)
|
|
{
|
|
foreach (GestureListenerInterface listener in gestureListeners)
|
|
{
|
|
if (listener != null && listener.GestureCompleted(userId, userIndex, gestureData.gesture, (KinectInterop.JointType)gestureData.joint, gestureData.screenPos))
|
|
{
|
|
ResetPlayerGestures(userId);
|
|
}
|
|
}
|
|
}
|
|
else if (gestureData.cancelled)
|
|
{
|
|
foreach (GestureListenerInterface listener in gestureListeners)
|
|
{
|
|
if (listener != null && listener.GestureCancelled(userId, userIndex, gestureData.gesture, (KinectInterop.JointType)gestureData.joint))
|
|
{
|
|
ResetGesture(userId, gestureData.gesture);
|
|
}
|
|
}
|
|
}
|
|
else if (gestureData.progress >= 0.1f)
|
|
{
|
|
foreach (GestureListenerInterface listener in gestureListeners)
|
|
{
|
|
if (listener != null)
|
|
{
|
|
listener.GestureInProgress(userId, userIndex, gestureData.gesture, gestureData.progress,
|
|
(KinectInterop.JointType)gestureData.joint, gestureData.screenPos);
|
|
}
|
|
}
|
|
}
|
|
|
|
//gesturesData[g] = gestureData;
|
|
}
|
|
}
|
|
|
|
|
|
protected void Start()
|
|
{
|
|
// locate the available gesture listeners
|
|
RefreshGestureListeners();
|
|
}
|
|
|
|
|
|
// Estimates the current state of the defined gestures
|
|
protected void CheckForGestures(ulong UserId, KinectManager kinectManager)
|
|
{
|
|
if (!playerGesturesData.ContainsKey(UserId) || !gesturesTrackingAtTime.ContainsKey(UserId))
|
|
return;
|
|
|
|
// check for gestures
|
|
if (Time.realtimeSinceStartup >= gesturesTrackingAtTime[UserId])
|
|
{
|
|
// get joint positions and tracking
|
|
int iAllJointsCount = (int)KinectInterop.JointType.Count;
|
|
bool[] playerJointsTracked = new bool[iAllJointsCount];
|
|
Vector3[] playerJointsPos = new Vector3[iAllJointsCount];
|
|
|
|
//// sensor orientation angle
|
|
//float orientAngle = kinectManager.GetPrimaryBodySensorOrientationAngle();
|
|
//Vector3 sensorOri = new Vector3(0f, 0f, orientAngle);
|
|
//matBodySensor.SetTRS(Vector3.zero, Quaternion.Euler(sensorOri), Vector3.one);
|
|
|
|
int[] aiNeededJointIndexes = GetNeededJointIndexes();
|
|
int iNeededJointsCount = aiNeededJointIndexes.Length;
|
|
|
|
if (jointDebugPrefab != null && debugJoints == null)
|
|
{
|
|
// array holding the skeleton joints
|
|
debugJoints = new GameObject[iNeededJointsCount];
|
|
|
|
for (int i = 0; i < iNeededJointsCount; i++)
|
|
{
|
|
debugJoints[i] = Instantiate(jointDebugPrefab) as GameObject;
|
|
debugJoints[i].transform.parent = transform;
|
|
debugJoints[i].name = ((KinectInterop.JointType)aiNeededJointIndexes[i]).ToString();
|
|
debugJoints[i].SetActive(false);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < iNeededJointsCount; i++)
|
|
{
|
|
int joint = aiNeededJointIndexes[i];
|
|
|
|
if (joint >= 0)
|
|
{
|
|
playerJointsTracked[joint] = kinectManager.IsJointTracked(UserId, joint);
|
|
playerJointsPos[joint] = kinectManager.GetJointPosition(UserId, joint);
|
|
//playerJointsPos[joint] = matBodySensor.MultiplyPoint3x4(playerJointsPos[joint]); // apply sensor orientation
|
|
|
|
if(debugJoints != null)
|
|
{
|
|
debugJoints[i].transform.position = playerJointsPos[joint];
|
|
debugJoints[i].SetActive(playerJointsTracked[joint]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check for gestures
|
|
List<GestureData> gesturesData = playerGesturesData[UserId];
|
|
|
|
int listGestureSize = gesturesData.Count;
|
|
float timestampNow = Time.realtimeSinceStartup;
|
|
string sDebugGestures = string.Empty; // "Tracked Gestures:\n";
|
|
|
|
for (int g = 0; g < listGestureSize; g++)
|
|
{
|
|
GestureData gestureData = gesturesData[g];
|
|
|
|
if ((timestampNow >= gestureData.startTrackingAtTime) &&
|
|
!IsConflictingGestureInProgress(gestureData, ref gesturesData))
|
|
{
|
|
CheckForGesture(UserId, ref gestureData, Time.realtimeSinceStartup, ref playerJointsPos, ref playerJointsTracked);
|
|
gesturesData[g] = gestureData;
|
|
|
|
if (gestureData.complete)
|
|
{
|
|
gesturesTrackingAtTime[UserId] = timestampNow + minTimeBetweenGestures;
|
|
}
|
|
|
|
if (gestureDebugText && (UserId == kinectManager.GetPrimaryUserID()))
|
|
{
|
|
sDebugGestures += string.Format("{0} - state: {1}, time: {2:F1}, progress: {3}%\n",
|
|
gestureData.gesture, gestureData.state,
|
|
gestureData.timestamp,
|
|
(int)(gestureData.progress * 100 + 0.5f));
|
|
}
|
|
}
|
|
}
|
|
|
|
playerGesturesData[UserId] = gesturesData;
|
|
|
|
if (gestureDebugText && (UserId == kinectManager.GetPrimaryUserID()))
|
|
{
|
|
for (int i = 0; i < iNeededJointsCount; i++)
|
|
{
|
|
int joint = aiNeededJointIndexes[i];
|
|
|
|
sDebugGestures += string.Format("\n {0}: {1}", (KinectInterop.JointType)joint,
|
|
playerJointsTracked[joint] ? playerJointsPos[joint].ToString() : "");
|
|
}
|
|
|
|
gestureDebugText.text = sDebugGestures;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private bool IsConflictingGestureInProgress(GestureData gestureData, ref List<GestureData> gesturesData)
|
|
{
|
|
foreach (GestureType gesture in gestureData.checkForGestures)
|
|
{
|
|
int index = GetGestureIndex(gesture, ref gesturesData);
|
|
|
|
if (index >= 0)
|
|
{
|
|
if (gesturesData[index].progress > 0f)
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
// return the index of gesture in the list, or -1 if not found
|
|
private int GetGestureIndex(GestureType gesture, ref List<GestureData> gesturesData)
|
|
{
|
|
int listSize = gesturesData.Count;
|
|
|
|
for (int i = 0; i < listSize; i++)
|
|
{
|
|
if (gesturesData[i].gesture == gesture)
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Gets the list of gesture joint indexes.
|
|
/// </summary>
|
|
/// <returns>The needed joint indexes.</returns>
|
|
public virtual int[] GetNeededJointIndexes()
|
|
{
|
|
leftHandIndex = (int)KinectInterop.JointType.HandLeft;
|
|
rightHandIndex = (int)KinectInterop.JointType.HandRight;
|
|
|
|
leftFingerIndex = (int)KinectInterop.JointType.HandtipLeft;
|
|
rightFingerIndex = (int)KinectInterop.JointType.HandtipRight;
|
|
|
|
leftElbowIndex = (int)KinectInterop.JointType.ElbowLeft;
|
|
rightElbowIndex = (int)KinectInterop.JointType.ElbowRight;
|
|
|
|
leftShoulderIndex = (int)KinectInterop.JointType.ShoulderLeft;
|
|
rightShoulderIndex = (int)KinectInterop.JointType.ShoulderRight;
|
|
|
|
leftClavicleIndex = (int)KinectInterop.JointType.ClavicleLeft;
|
|
rightClavicleIndex = (int)KinectInterop.JointType.ClavicleRight;
|
|
|
|
hipCenterIndex = (int)KinectInterop.JointType.Pelvis;
|
|
neckIndex = (int)KinectInterop.JointType.Neck;
|
|
|
|
leftHipIndex = (int)KinectInterop.JointType.HipLeft;
|
|
rightHipIndex = (int)KinectInterop.JointType.HipRight;
|
|
|
|
leftKneeIndex = (int)KinectInterop.JointType.KneeLeft;
|
|
rightKneeIndex = (int)KinectInterop.JointType.KneeRight;
|
|
|
|
leftAnkleIndex = (int)KinectInterop.JointType.AnkleLeft;
|
|
rightAnkleIndex = (int)KinectInterop.JointType.AnkleRight;
|
|
|
|
int[] neededJointIndexes = {
|
|
leftHandIndex, rightHandIndex, leftFingerIndex, rightFingerIndex, leftElbowIndex, rightElbowIndex, leftShoulderIndex, rightShoulderIndex,
|
|
leftClavicleIndex, rightClavicleIndex, hipCenterIndex, neckIndex,
|
|
leftHipIndex, rightHipIndex, leftKneeIndex, rightKneeIndex, leftAnkleIndex, rightAnkleIndex
|
|
};
|
|
|
|
return neededJointIndexes;
|
|
}
|
|
|
|
|
|
// sets basic parameters of the gesture data
|
|
protected void SetGestureJoint(ref GestureData gestureData, float timestamp, int joint, Vector3 jointPos)
|
|
{
|
|
gestureData.joint = joint;
|
|
gestureData.jointPos = jointPos;
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.state++;
|
|
}
|
|
|
|
|
|
// marks the gesture data as cancelled gesture
|
|
protected void SetGestureCancelled(ref GestureData gestureData)
|
|
{
|
|
gestureData.state = 0;
|
|
gestureData.progress = 0f;
|
|
gestureData.cancelled = true;
|
|
}
|
|
|
|
|
|
// checks if the pose persists for the whole duration set
|
|
protected void CheckPoseComplete(ref GestureData gestureData, float timestamp, Vector3 jointPos, bool isInPose, float durationToComplete)
|
|
{
|
|
if (isInPose)
|
|
{
|
|
float timeLeft = timestamp - gestureData.timestamp;
|
|
gestureData.progress = durationToComplete > 0f ? Mathf.Clamp01(timeLeft / durationToComplete) : 1.0f;
|
|
|
|
if (timeLeft >= durationToComplete)
|
|
{
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.jointPos = jointPos;
|
|
gestureData.state++;
|
|
gestureData.complete = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
}
|
|
|
|
|
|
// sets gesture data current screen coords (useful for many gestures)
|
|
protected void SetScreenPos(ulong userId, ref GestureData gestureData, ref Vector3[] jointsPos, ref bool[] jointsTracked)
|
|
{
|
|
Vector3 handPos = jointsPos[rightHandIndex];
|
|
bool calculateCoords = false;
|
|
|
|
if (gestureData.joint == rightHandIndex)
|
|
{
|
|
if (jointsTracked[rightHandIndex] /**&& jointsTracked[rightElbowIndex] && jointsTracked[rightShoulderIndex]*/)
|
|
{
|
|
calculateCoords = true;
|
|
}
|
|
}
|
|
else if (gestureData.joint == leftHandIndex)
|
|
{
|
|
if (jointsTracked[leftHandIndex] /**&& jointsTracked[leftElbowIndex] && jointsTracked[leftShoulderIndex]*/)
|
|
{
|
|
handPos = jointsPos[leftHandIndex];
|
|
calculateCoords = true;
|
|
}
|
|
}
|
|
|
|
if (calculateCoords)
|
|
{
|
|
if (jointsTracked[hipCenterIndex] && jointsTracked[leftClavicleIndex] && jointsTracked[rightClavicleIndex] &&
|
|
jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex])
|
|
{
|
|
Vector3 shoulderCenterPos = (jointsPos[leftClavicleIndex] + jointsPos[rightClavicleIndex]) / 2f;
|
|
Vector3 shoulderToHips = shoulderCenterPos - jointsPos[hipCenterIndex];
|
|
Vector3 rightToLeft = jointsPos[rightShoulderIndex] - jointsPos[leftShoulderIndex];
|
|
|
|
gestureData.tagVector2.x = rightToLeft.x; // * 1.2f;
|
|
gestureData.tagVector2.y = shoulderToHips.y; // * 1.2f;
|
|
|
|
if (gestureData.joint == rightHandIndex)
|
|
{
|
|
gestureData.tagVector.x = jointsPos[rightShoulderIndex].x - gestureData.tagVector2.x / 2f;
|
|
gestureData.tagVector.y = jointsPos[hipCenterIndex].y;
|
|
}
|
|
else
|
|
{
|
|
gestureData.tagVector.x = jointsPos[leftShoulderIndex].x - gestureData.tagVector2.x / 2f;
|
|
gestureData.tagVector.y = jointsPos[hipCenterIndex].y;
|
|
}
|
|
}
|
|
|
|
if (gestureData.tagVector2.x != 0 && gestureData.tagVector2.y != 0)
|
|
{
|
|
Vector3 relHandPos = handPos - gestureData.tagVector;
|
|
gestureData.screenPos.x = Mathf.Clamp01(relHandPos.x / gestureData.tagVector2.x);
|
|
gestureData.screenPos.y = Mathf.Clamp01(relHandPos.y / gestureData.tagVector2.y);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
// sets the zoom factor value as screenPos.z (for zoom-in and zoom-out gestures)
|
|
protected void SetZoomFactor(ulong userId, ref GestureData gestureData, float initialZoom, ref Vector3[] jointsPos, ref bool[] jointsTracked)
|
|
{
|
|
Vector3 vectorZooming = jointsPos[rightHandIndex] - jointsPos[leftHandIndex];
|
|
|
|
if (gestureData.tagFloat == 0f || gestureData.userId != userId)
|
|
{
|
|
gestureData.tagFloat = 0.5f; // this is 100%
|
|
}
|
|
|
|
float distZooming = vectorZooming.magnitude;
|
|
gestureData.screenPos.z = initialZoom + (distZooming / gestureData.tagFloat);
|
|
}
|
|
|
|
|
|
// sets the wheel rotation value as screenPos.z (for wheel-gesture)
|
|
protected void SetWheelRotation(ulong userId, ref GestureData gestureData, Vector3 initialPos, Vector3 currentPos)
|
|
{
|
|
float angle = Vector3.Angle(initialPos, currentPos) * Mathf.Sign(currentPos.y - initialPos.y);
|
|
gestureData.screenPos.z = angle;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Estimate the state and progress of the given gesture.
|
|
/// </summary>
|
|
/// <param name="userId">User ID</param>
|
|
/// <param name="gestureData">Gesture-data structure</param>
|
|
/// <param name="timestamp">Current time</param>
|
|
/// <param name="jointsPos">Joints-position array</param>
|
|
/// <param name="jointsTracked">Joints-tracked array</param>
|
|
public virtual void CheckForGesture(ulong userId, ref GestureData gestureData, float timestamp, ref Vector3[] jointsPos, ref bool[] jointsTracked)
|
|
{
|
|
if (gestureData.complete)
|
|
return;
|
|
|
|
float bandTopY = jointsPos[rightShoulderIndex].y > jointsPos[leftShoulderIndex].y ? jointsPos[rightShoulderIndex].y : jointsPos[leftShoulderIndex].y;
|
|
float bandBotY = jointsPos[rightHipIndex].y < jointsPos[leftHipIndex].y ? jointsPos[rightHipIndex].y : jointsPos[leftHipIndex].y;
|
|
|
|
float bandCenter = (bandTopY + bandBotY) / 2f;
|
|
float bandSize = (bandTopY - bandBotY);
|
|
|
|
float gestureTop = bandCenter + bandSize * 1.2f / 2f;
|
|
float gestureBottom = bandCenter - bandSize * 1.3f / 4f;
|
|
float gestureRight = jointsPos[rightHipIndex].x;
|
|
float gestureLeft = jointsPos[leftHipIndex].x;
|
|
|
|
switch (gestureData.gesture)
|
|
{
|
|
// check for RaiseRightHand
|
|
case GestureType.RaiseRightHand:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[leftShoulderIndex].y) > 0.1f &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) < 0f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture complete
|
|
bool isInPose = jointsTracked[rightHandIndex] && jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[leftShoulderIndex].y) > 0.1f &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) < 0f;
|
|
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for RaiseLeftHand
|
|
case GestureType.RaiseLeftHand:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection
|
|
if (jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[rightShoulderIndex].y) > 0.1f &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) < 0f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture complete
|
|
bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[rightShoulderIndex].y) > 0.1f &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) < 0f;
|
|
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for Psi
|
|
case GestureType.Psi:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[leftHandIndex] && jointsTracked[leftClavicleIndex] && jointsTracked[rightClavicleIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[rightClavicleIndex].y) > 0.1f &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[leftClavicleIndex].y) > 0.1f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture complete
|
|
bool isInPose = jointsTracked[rightHandIndex] && jointsTracked[leftHandIndex] && jointsTracked[leftClavicleIndex] && jointsTracked[rightClavicleIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[rightClavicleIndex].y) > 0.1f &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[leftClavicleIndex].y) > 0.1f;
|
|
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for Tpose
|
|
case GestureType.Tpose:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[rightShoulderIndex] &&
|
|
Mathf.Abs(jointsPos[rightElbowIndex].y - jointsPos[rightShoulderIndex].y) < 0.1f && // 0.07f
|
|
Mathf.Abs(jointsPos[rightHandIndex].y - jointsPos[rightElbowIndex].y) < 0.1f && // 0.7f
|
|
(jointsPos[rightElbowIndex].x - jointsPos[rightShoulderIndex].x) > 0.05f &&
|
|
jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[leftShoulderIndex] &&
|
|
Mathf.Abs(jointsPos[leftElbowIndex].y - jointsPos[leftShoulderIndex].y) < 0.1f &&
|
|
Mathf.Abs(jointsPos[leftHandIndex].y - jointsPos[leftElbowIndex].y) < 0.1f &&
|
|
(jointsPos[leftElbowIndex].x - jointsPos[leftShoulderIndex].x) < 0.05f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture complete
|
|
bool isInPose = jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[rightShoulderIndex] &&
|
|
Mathf.Abs(jointsPos[rightElbowIndex].y - jointsPos[rightShoulderIndex].y) < 0.1f && // 0.7f
|
|
Mathf.Abs(jointsPos[rightHandIndex].y - jointsPos[rightElbowIndex].y) < 0.1f && // 0.7f
|
|
(jointsPos[rightElbowIndex].x - jointsPos[rightShoulderIndex].x) > 0.05f &&
|
|
jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[leftShoulderIndex] &&
|
|
Mathf.Abs(jointsPos[leftElbowIndex].y - jointsPos[leftShoulderIndex].y) < 0.1f &&
|
|
Mathf.Abs(jointsPos[leftHandIndex].y - jointsPos[leftElbowIndex].y) < 0.1f &&
|
|
(jointsPos[leftElbowIndex].x - jointsPos[leftShoulderIndex].x) < -0.05f;
|
|
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for Apose
|
|
case GestureType.Apose:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[rightHipIndex] &&
|
|
Mathf.Abs(jointsPos[rightHandIndex].y - jointsPos[rightHipIndex].y) < 0.2f &&
|
|
(jointsPos[rightHandIndex].x - jointsPos[rightHipIndex].x) >= 0.3f &&
|
|
(jointsTracked[leftHandIndex] && jointsTracked[leftHipIndex] &&
|
|
Mathf.Abs(jointsPos[leftHandIndex].y - jointsPos[leftHipIndex].y) < 0.2f &&
|
|
(jointsPos[leftHandIndex].x - jointsPos[leftHipIndex].x) <= -0.3f))
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture complete
|
|
bool isInPose = (jointsTracked[rightHandIndex] && jointsTracked[rightHipIndex] &&
|
|
Mathf.Abs(jointsPos[rightHandIndex].y - jointsPos[rightHipIndex].y) < 0.2f &&
|
|
(jointsPos[rightHandIndex].x - jointsPos[rightHipIndex].x) >= 0.3f &&
|
|
(jointsTracked[leftHandIndex] && jointsTracked[leftHipIndex] &&
|
|
Mathf.Abs(jointsPos[leftHandIndex].y - jointsPos[leftHipIndex].y) < 0.2f &&
|
|
(jointsPos[leftHandIndex].x - jointsPos[leftHipIndex].x) <= -0.3f));
|
|
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for Stop
|
|
case GestureType.Stop:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[rightHipIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[rightHipIndex].y) < 0.2f &&
|
|
(jointsPos[rightHandIndex].x - jointsPos[rightHipIndex].x) >= 0.4f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
}
|
|
else if (jointsTracked[leftHandIndex] && jointsTracked[leftHipIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[leftHipIndex].y) < 0.2f &&
|
|
(jointsPos[leftHandIndex].x - jointsPos[leftHipIndex].x) <= -0.4f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture complete
|
|
bool isInPose = (gestureData.joint == rightHandIndex) ?
|
|
(jointsTracked[rightHandIndex] && jointsTracked[rightHipIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[rightHipIndex].y) < 0.2f &&
|
|
(jointsPos[rightHandIndex].x - jointsPos[rightHipIndex].x) >= 0.4f) :
|
|
(jointsTracked[leftHandIndex] && jointsTracked[leftHipIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[leftHipIndex].y) < 0.2f &&
|
|
(jointsPos[leftHandIndex].x - jointsPos[leftHipIndex].x) <= -0.4f);
|
|
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for raised right hand & horizontal left hand
|
|
case GestureType.RaisedRightHorizontalLeftHand:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] && // check right hand is straight up
|
|
(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) > 0.5f && // ensure right hand is higher than shoulder
|
|
Mathf.Abs(jointsPos[rightHandIndex].z - jointsPos[rightShoulderIndex].z) < 0.35f && // ensue hand is vertical straight enough
|
|
Mathf.Abs(jointsPos[rightHandIndex].x - jointsPos[rightShoulderIndex].x) < 0.35f && // ensue hand is vertical straight enough
|
|
jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] && // check left hand is straight flat
|
|
Mathf.Abs(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) < 0.25f && // ensure hand and shoulder are on close height
|
|
(jointsPos[leftHandIndex] - jointsPos[leftShoulderIndex]).sqrMagnitude > 0.25f) // ensure hand and shoulder are horizontal straight enough
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
}
|
|
break;
|
|
|
|
|
|
case 1: // gesture complete
|
|
bool isInPose = jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] && // check right hand is straight up
|
|
(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) > 0.5f && // ensure right hand is higher than shoulder
|
|
Mathf.Abs(jointsPos[rightHandIndex].z - jointsPos[rightShoulderIndex].z) < 0.35f && // ensue hand is vertical straight enough
|
|
Mathf.Abs(jointsPos[rightHandIndex].x - jointsPos[rightShoulderIndex].x) < 0.35f && // ensue hand is vertical straight enough
|
|
jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] && // check left hand is straight flat
|
|
Mathf.Abs(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) < 0.25f && // ensure hand and shoulder are on close height
|
|
(jointsPos[leftHandIndex] - jointsPos[leftShoulderIndex]).sqrMagnitude > 0.25f; // ensure hand and shoulder are horizontal straight enough
|
|
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for raised left hand & horizontal right hand
|
|
case GestureType.RaisedLeftHorizontalRightHand:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection
|
|
if (jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] && // check left hand is straight up
|
|
(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) > 0.5f && // ensure left hand is higher than shoulder
|
|
Mathf.Abs(jointsPos[leftHandIndex].z - jointsPos[leftShoulderIndex].z) < 0.35f && // ensue hand is vertical straight enough
|
|
Mathf.Abs(jointsPos[leftHandIndex].x - jointsPos[leftShoulderIndex].x) < 0.35f && // ensue hand is vertical straight enough
|
|
jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] && // check right hand is straight flat
|
|
Mathf.Abs(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) < 0.25f && // ensure hand and shoulder are on close height
|
|
(jointsPos[rightHandIndex] - jointsPos[rightShoulderIndex]).sqrMagnitude > 0.25f) // ensure hand and shoulder are horizontal straight enough
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture complete
|
|
bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] && // check left hand is straight up
|
|
(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) > 0.5f && // ensure left hand is higher than shoulder
|
|
Mathf.Abs(jointsPos[leftHandIndex].z - jointsPos[leftShoulderIndex].z) < 0.35f && // ensue hand is vertical straight enough
|
|
Mathf.Abs(jointsPos[leftHandIndex].x - jointsPos[leftShoulderIndex].x) < 0.35f && // ensue hand is vertical straight enough
|
|
jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] && // check right hand is straight flat
|
|
Mathf.Abs(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) < 0.25f && // ensure hand and shoulder are on close height
|
|
(jointsPos[rightHandIndex] - jointsPos[rightShoulderIndex]).sqrMagnitude > 0.25f; // ensure hand and shoulder are horizontal straight enough
|
|
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for TouchedRightElbow
|
|
case GestureType.TouchRightElbow:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection
|
|
if (jointsTracked[leftFingerIndex] && jointsTracked[rightElbowIndex] &&
|
|
Vector3.Distance(jointsPos[leftFingerIndex], jointsPos[rightElbowIndex]) <= 0.12f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftFingerIndex, jointsPos[leftFingerIndex]);
|
|
}
|
|
|
|
//Debug.Log ("TRE0 - Distance: " + Vector3.Distance(jointsPos[leftFingerIndex], jointsPos[rightElbowIndex]));
|
|
break;
|
|
|
|
case 1: // gesture complete
|
|
bool isInPose = jointsTracked[leftFingerIndex] && jointsTracked[rightElbowIndex] &&
|
|
Vector3.Distance(jointsPos[leftFingerIndex], jointsPos[rightElbowIndex]) <= 0.12f;
|
|
|
|
//Debug.Log ("TRE1 - Distance: " + Vector3.Distance(jointsPos[leftFingerIndex], jointsPos[rightElbowIndex]) + ", progress: " + gestureData.progress);
|
|
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 1.5f /**KinectInterop.Constants.PoseCompleteDuration*/);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for TouchedLeftElbow
|
|
case GestureType.TouchLeftElbow:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection
|
|
if (jointsTracked[rightFingerIndex] && jointsTracked[leftElbowIndex] &&
|
|
Vector3.Distance(jointsPos[rightFingerIndex], jointsPos[leftElbowIndex]) <= 0.12f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightFingerIndex, jointsPos[rightFingerIndex]);
|
|
}
|
|
|
|
//Debug.Log ("TLE0 - Distance: " + Vector3.Distance(jointsPos[rightFingerIndex], jointsPos[leftElbowIndex]));
|
|
break;
|
|
|
|
case 1: // gesture complete
|
|
bool isInPose = jointsTracked[rightFingerIndex] && jointsTracked[leftElbowIndex] &&
|
|
Vector3.Distance(jointsPos[rightFingerIndex], jointsPos[leftElbowIndex]) <= 0.12f;
|
|
|
|
//Debug.Log ("TLE1- Distance: " + Vector3.Distance(jointsPos[rightFingerIndex], jointsPos[leftElbowIndex]));
|
|
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 1.5f /**KinectInterop.Constants.PoseCompleteDuration*/);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for Wave
|
|
case GestureType.Wave:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[rightElbowIndex].y) > 0.1f &&
|
|
(jointsPos[rightHandIndex].x - jointsPos[rightElbowIndex].x) > 0.05f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
gestureData.progress = 0.3f;
|
|
}
|
|
else if (jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[leftElbowIndex].y) > 0.1f &&
|
|
(jointsPos[leftHandIndex].x - jointsPos[leftElbowIndex].x) < -0.05f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
|
|
gestureData.progress = 0.3f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture - phase 2
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = gestureData.joint == rightHandIndex ?
|
|
jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[rightElbowIndex].y) > 0.1f &&
|
|
(jointsPos[rightHandIndex].x - jointsPos[rightElbowIndex].x) < -0.05f :
|
|
jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[leftElbowIndex].y) > 0.1f &&
|
|
(jointsPos[leftHandIndex].x - jointsPos[leftElbowIndex].x) > 0.05f;
|
|
|
|
if (isInPose)
|
|
{
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.state++;
|
|
gestureData.progress = 0.7f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
|
|
case 2: // gesture phase 3 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = gestureData.joint == rightHandIndex ?
|
|
jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[rightElbowIndex].y) > 0.1f &&
|
|
(jointsPos[rightHandIndex].x - jointsPos[rightElbowIndex].x) > 0.05f :
|
|
jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[leftElbowIndex].y) > 0.1f &&
|
|
(jointsPos[leftHandIndex].x - jointsPos[leftElbowIndex].x) < -0.05f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for SwipeLeft
|
|
case GestureType.SwipeLeft:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] &&
|
|
jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
|
|
jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
|
|
jointsPos[rightHandIndex].x >= gestureRight /**&& jointsPos[rightHandIndex].x > gestureLeft*/)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
gestureData.progress = 0.1f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) <= 1.0f)
|
|
{
|
|
bool isInPose = jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] &&
|
|
jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
|
|
jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
|
|
jointsPos[rightHandIndex].x <= gestureLeft;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
else if (jointsPos[rightHandIndex].x <= gestureRight)
|
|
{
|
|
float gestureSize = gestureRight - gestureLeft;
|
|
gestureData.progress = gestureSize > 0.01f ? (gestureRight - jointsPos[rightHandIndex].x) / gestureSize : 0f;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for SwipeRight
|
|
case GestureType.SwipeRight:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] &&
|
|
jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
|
|
jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
|
|
jointsPos[leftHandIndex].x <= gestureLeft /**&& jointsPos[leftHandIndex].x < gestureRight*/)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
|
|
gestureData.progress = 0.1f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) <= 1.0f)
|
|
{
|
|
bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] &&
|
|
jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
|
|
jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
|
|
jointsPos[leftHandIndex].x >= gestureRight;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
else if (jointsPos[leftHandIndex].x >= gestureLeft)
|
|
{
|
|
float gestureSize = gestureRight - gestureLeft;
|
|
gestureData.progress = gestureSize > 0.01f ? (jointsPos[leftHandIndex].x - gestureLeft) / gestureSize : 0f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for SwipeUp
|
|
case GestureType.SwipeUp:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[leftShoulderIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) < 0f &&
|
|
(jointsPos[rightHandIndex].y - (jointsPos[leftElbowIndex].y + jointsPos[leftHandIndex].y) / 2f) > 0f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
else if (jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[rightShoulderIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) < 0f &&
|
|
(jointsPos[leftHandIndex].y -( jointsPos[rightElbowIndex].y + jointsPos[rightHandIndex].y) / 2f) > 0f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = gestureData.joint == rightHandIndex ?
|
|
jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[leftShoulderIndex].y) > -0.05f &&
|
|
Mathf.Abs(jointsPos[rightHandIndex].x - gestureData.jointPos.x) <= 0.15f :
|
|
jointsTracked[leftHandIndex] && jointsTracked[rightShoulderIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[rightShoulderIndex].y) > -0.05f &&
|
|
Mathf.Abs(jointsPos[leftHandIndex].x - gestureData.jointPos.x) <= 0.15f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for SwipeDown
|
|
case GestureType.SwipeDown:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[leftShoulderIndex].y) >= -0.05f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
else if (jointsTracked[leftHandIndex] && jointsTracked[rightShoulderIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[rightShoulderIndex].y) >= -0.05f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = gestureData.joint == rightHandIndex ?
|
|
jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) < 0f &&
|
|
Mathf.Abs(jointsPos[rightHandIndex].x - gestureData.jointPos.x) <= 0.15f :
|
|
jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) < 0f &&
|
|
Mathf.Abs(jointsPos[leftHandIndex].x - gestureData.jointPos.x) <= 0.15f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for ZoomIn
|
|
case GestureType.ZoomIn:
|
|
Vector3 vectorZoomOut = (Vector3)jointsPos[rightHandIndex] - jointsPos[leftHandIndex];
|
|
float distZoomOut = vectorZoomOut.magnitude;
|
|
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] &&
|
|
jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
|
|
jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
|
|
jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
|
|
distZoomOut < 0.3f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
gestureData.tagVector = Vector3.right;
|
|
gestureData.tagFloat = 0f;
|
|
gestureData.progress = 0.3f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = zooming
|
|
if ((timestamp - gestureData.timestamp) < 1.0f)
|
|
{
|
|
float angleZoomOut = Vector3.Angle(gestureData.tagVector, vectorZoomOut) * Mathf.Sign(vectorZoomOut.y - gestureData.tagVector.y);
|
|
bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] &&
|
|
jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
|
|
jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
|
|
jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
|
|
distZoomOut < 1.5f && Mathf.Abs(angleZoomOut) < 20f;
|
|
|
|
if (isInPose)
|
|
{
|
|
SetZoomFactor(userId, ref gestureData, 1.0f, ref jointsPos, ref jointsTracked);
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.progress = 0.7f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for ZoomOut
|
|
case GestureType.ZoomOut:
|
|
Vector3 vectorZoomIn = (Vector3)jointsPos[rightHandIndex] - jointsPos[leftHandIndex];
|
|
float distZoomIn = vectorZoomIn.magnitude;
|
|
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] &&
|
|
jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
|
|
jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
|
|
jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
|
|
distZoomIn >= 0.7f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
gestureData.tagVector = Vector3.right;
|
|
gestureData.tagFloat = distZoomIn;
|
|
gestureData.progress = 0.3f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = zooming
|
|
if ((timestamp - gestureData.timestamp) < 1.0f)
|
|
{
|
|
float angleZoomIn = Vector3.Angle(gestureData.tagVector, vectorZoomIn) * Mathf.Sign(vectorZoomIn.y - gestureData.tagVector.y);
|
|
bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] &&
|
|
jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
|
|
jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
|
|
jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
|
|
distZoomIn >= 0.2f && Mathf.Abs(angleZoomIn) < 20f;
|
|
|
|
if (isInPose)
|
|
{
|
|
SetZoomFactor(userId, ref gestureData, 0.0f, ref jointsPos, ref jointsTracked);
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.progress = 0.7f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for Wheel
|
|
case GestureType.Wheel:
|
|
Vector3 vectorWheel = (Vector3)jointsPos[rightHandIndex] - jointsPos[leftHandIndex];
|
|
float distWheel = vectorWheel.magnitude;
|
|
|
|
// Debug.Log(string.Format("{0}. Dist: {1:F1}, Tag: {2:F1}, Diff: {3:F1}", gestureData.state,
|
|
// distWheel, gestureData.tagFloat, Mathf.Abs(distWheel - gestureData.tagFloat)));
|
|
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] &&
|
|
jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
|
|
jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
|
|
jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
|
|
distWheel >= 0.3f && distWheel < 0.7f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
gestureData.tagVector = Vector3.right;
|
|
gestureData.tagFloat = distWheel;
|
|
gestureData.progress = 0.3f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = rotating
|
|
if ((timestamp - gestureData.timestamp) < 0.5f)
|
|
{
|
|
float angle = Vector3.Angle(gestureData.tagVector, vectorWheel) * Mathf.Sign(vectorWheel.y - gestureData.tagVector.y);
|
|
bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] &&
|
|
jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
|
|
jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
|
|
jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
|
|
distWheel >= 0.3f && distWheel < 0.7f &&
|
|
Mathf.Abs(distWheel - gestureData.tagFloat) < 0.1f;
|
|
|
|
if (isInPose)
|
|
{
|
|
//SetWheelRotation(userId, ref gestureData, gestureData.tagVector, vectorWheel);
|
|
gestureData.screenPos.z = angle; // wheel angle
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.tagFloat = distWheel;
|
|
gestureData.progress = 0.7f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for Jump
|
|
case GestureType.Jump:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[hipCenterIndex] &&
|
|
(jointsPos[hipCenterIndex].y > 0.6f) && (jointsPos[hipCenterIndex].y < 1.2f))
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, hipCenterIndex, jointsPos[hipCenterIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = jointsTracked[hipCenterIndex] &&
|
|
(jointsPos[hipCenterIndex].y - gestureData.jointPos.y) > 0.15f &&
|
|
Mathf.Abs(jointsPos[hipCenterIndex].x - gestureData.jointPos.x) < 0.2f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for Squat
|
|
case GestureType.Squat:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[hipCenterIndex] &&
|
|
(jointsPos[hipCenterIndex].y <= 0.7f))
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, hipCenterIndex, jointsPos[hipCenterIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = jointsTracked[hipCenterIndex] &&
|
|
(jointsPos[hipCenterIndex].y - gestureData.jointPos.y) < -0.15f &&
|
|
Mathf.Abs(jointsPos[hipCenterIndex].x - gestureData.jointPos.x) < 0.2f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for Push
|
|
case GestureType.Push:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[rightShoulderIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) > -0.1f &&
|
|
Mathf.Abs(jointsPos[rightHandIndex].x - jointsPos[rightShoulderIndex].x) < 0.2f &&
|
|
(jointsPos[rightHandIndex].z - jointsPos[leftElbowIndex].z) < -0.2f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
else if (jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[leftShoulderIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) > -0.1f &&
|
|
Mathf.Abs(jointsPos[leftHandIndex].x - jointsPos[leftShoulderIndex].x) < 0.2f &&
|
|
(jointsPos[leftHandIndex].z - jointsPos[rightElbowIndex].z) < -0.2f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = gestureData.joint == rightHandIndex ?
|
|
jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[rightShoulderIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) > -0.1f &&
|
|
Mathf.Abs(jointsPos[rightHandIndex].x - gestureData.jointPos.x) < 0.2f &&
|
|
(jointsPos[rightHandIndex].z - gestureData.jointPos.z) < -0.2f :
|
|
jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[leftShoulderIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) > -0.1f &&
|
|
Mathf.Abs(jointsPos[leftHandIndex].x - gestureData.jointPos.x) < 0.2f &&
|
|
(jointsPos[leftHandIndex].z - gestureData.jointPos.z) < -0.2f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for Pull
|
|
case GestureType.Pull:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[rightShoulderIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) > -0.1f &&
|
|
Mathf.Abs(jointsPos[rightHandIndex].x - jointsPos[rightShoulderIndex].x) < 0.2f &&
|
|
(jointsPos[rightHandIndex].z - jointsPos[leftElbowIndex].z) < -0.3f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
else if (jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[leftShoulderIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) > -0.1f &&
|
|
Mathf.Abs(jointsPos[leftHandIndex].x - jointsPos[leftShoulderIndex].x) < 0.2f &&
|
|
(jointsPos[leftHandIndex].z - jointsPos[rightElbowIndex].z) < -0.3f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = gestureData.joint == rightHandIndex ?
|
|
jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[rightShoulderIndex] &&
|
|
(jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) > -0.1f &&
|
|
Mathf.Abs(jointsPos[rightHandIndex].x - gestureData.jointPos.x) < 0.2f &&
|
|
(jointsPos[rightHandIndex].z - gestureData.jointPos.z) > 0.25f :
|
|
jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[leftShoulderIndex] &&
|
|
(jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) > -0.1f &&
|
|
Mathf.Abs(jointsPos[leftHandIndex].x - gestureData.jointPos.x) < 0.2f &&
|
|
(jointsPos[leftHandIndex].z - gestureData.jointPos.z) > 0.25f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for ShoulderLeftFron
|
|
case GestureType.ShoulderLeftFront:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] && jointsTracked[leftHipIndex] &&
|
|
(jointsPos[rightShoulderIndex].z - jointsPos[leftHipIndex].z) < 0f &&
|
|
(jointsPos[rightShoulderIndex].z - jointsPos[leftShoulderIndex].z) > -0.15f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightShoulderIndex, jointsPos[rightShoulderIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] && jointsTracked[leftHipIndex] &&
|
|
(jointsPos[rightShoulderIndex].z - jointsPos[leftShoulderIndex].z) < -0.2f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for ShoulderRightFront
|
|
case GestureType.ShoulderRightFront:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] && jointsTracked[rightHipIndex] &&
|
|
(jointsPos[leftShoulderIndex].z - jointsPos[rightHipIndex].z) < 0f &&
|
|
(jointsPos[leftShoulderIndex].z - jointsPos[rightShoulderIndex].z) > -0.15f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftShoulderIndex, jointsPos[leftShoulderIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] && jointsTracked[rightHipIndex] &&
|
|
(jointsPos[leftShoulderIndex].z - jointsPos[rightShoulderIndex].z) < -0.2f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for LeanLeft
|
|
case GestureType.LeanLeft:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1 (right shoulder is left of the right hip, means leaning left)
|
|
if (jointsTracked[rightShoulderIndex] && jointsTracked[rightHipIndex] && jointsTracked[neckIndex] &&
|
|
(jointsPos[rightShoulderIndex].x - jointsPos[rightHipIndex].x) < 0f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightShoulderIndex, jointsPos[rightShoulderIndex]);
|
|
gestureData.progress = 0.3f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 0.5f)
|
|
{
|
|
// check if right shoulder is still left of the right hip (leaning left)
|
|
bool isInPose = jointsTracked[rightShoulderIndex] && jointsTracked[rightHipIndex] && jointsTracked[neckIndex] &&
|
|
(jointsPos[rightShoulderIndex].x - jointsPos[rightHipIndex].x) < 0f;
|
|
|
|
if (isInPose)
|
|
{
|
|
// calculate lean angle
|
|
Vector3 vSpineLL = jointsPos[neckIndex] - jointsPos[hipCenterIndex];
|
|
gestureData.screenPos.z = Vector3.Angle(Vector3.up, vSpineLL);
|
|
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.progress = 0.7f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for LeanRight
|
|
case GestureType.LeanRight:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1 (left shoulder is right of the left hip, means leaning right)
|
|
if (jointsTracked[leftShoulderIndex] && jointsTracked[leftHipIndex] && jointsTracked[neckIndex] &&
|
|
(jointsPos[leftShoulderIndex].x - jointsPos[leftHipIndex].x) > 0f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftShoulderIndex, jointsPos[leftShoulderIndex]);
|
|
gestureData.progress = 0.3f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 0.5f)
|
|
{
|
|
// check if left shoulder is still right of the left hip (leaning right)
|
|
bool isInPose = jointsTracked[leftShoulderIndex] && jointsTracked[leftHipIndex] && jointsTracked[neckIndex] &&
|
|
(jointsPos[leftShoulderIndex].x - jointsPos[leftHipIndex].x) > 0f;
|
|
|
|
if (isInPose)
|
|
{
|
|
// calculate lean angle
|
|
Vector3 vSpineLR = jointsPos[neckIndex] - jointsPos[hipCenterIndex];
|
|
gestureData.screenPos.z = Vector3.Angle(Vector3.up, vSpineLR);
|
|
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.progress = 0.7f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for LeanForward
|
|
case GestureType.LeanForward:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1 (shoulder center in front of hip center, means leaning forward)
|
|
if (jointsTracked[neckIndex] && jointsTracked[hipCenterIndex] &&
|
|
(jointsPos[neckIndex].z - jointsPos[hipCenterIndex].z) < -0.1f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, neckIndex, jointsPos[neckIndex]);
|
|
gestureData.progress = 0.3f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 0.5f)
|
|
{
|
|
// check if shoulder center is still in front of the hip center (leaning forward)
|
|
bool isInPose = jointsTracked[neckIndex] && jointsTracked[hipCenterIndex] &&
|
|
(jointsPos[neckIndex].z - jointsPos[leftHipIndex].z) < -0.1f;
|
|
|
|
if (isInPose)
|
|
{
|
|
// calculate lean angle
|
|
Vector3 vSpineLL = jointsPos[neckIndex] - jointsPos[hipCenterIndex];
|
|
gestureData.screenPos.z = Vector3.Angle(Vector3.up, vSpineLL);
|
|
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.progress = 0.7f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for LeanBack
|
|
case GestureType.LeanBack:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1 (shoulder center behind hip center, means leaning back)
|
|
if (jointsTracked[neckIndex] && jointsTracked[hipCenterIndex] &&
|
|
(jointsPos[neckIndex].z - jointsPos[hipCenterIndex].z) > 0.1f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, neckIndex, jointsPos[neckIndex]);
|
|
gestureData.progress = 0.3f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 0.5f)
|
|
{
|
|
// check if shoulder center is still behind of the hip center (leaning back)
|
|
bool isInPose = jointsTracked[neckIndex] && jointsTracked[hipCenterIndex] &&
|
|
(jointsPos[neckIndex].z - jointsPos[leftHipIndex].z) > 0.1f;
|
|
|
|
if (isInPose)
|
|
{
|
|
// calculate lean angle
|
|
Vector3 vSpineLR = jointsPos[neckIndex] - jointsPos[hipCenterIndex];
|
|
gestureData.screenPos.z = Vector3.Angle(Vector3.up, vSpineLR);
|
|
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.progress = 0.7f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for KickLeft
|
|
case GestureType.KickLeft:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[leftAnkleIndex] && jointsTracked[rightAnkleIndex] && jointsTracked[leftHipIndex] &&
|
|
(jointsPos[leftAnkleIndex].z - jointsPos[leftHipIndex].z) < 0f &&
|
|
(jointsPos[leftAnkleIndex].z - jointsPos[rightAnkleIndex].z) > -0.2f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftAnkleIndex, jointsPos[leftAnkleIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = jointsTracked[leftAnkleIndex] && jointsTracked[rightAnkleIndex] && jointsTracked[leftHipIndex] &&
|
|
(jointsPos[leftAnkleIndex].z - jointsPos[rightAnkleIndex].z) < -0.4f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for KickRight
|
|
case GestureType.KickRight:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[leftAnkleIndex] && jointsTracked[rightAnkleIndex] && jointsTracked[rightHipIndex] &&
|
|
(jointsPos[rightAnkleIndex].z - jointsPos[rightHipIndex].z) < 0f &&
|
|
(jointsPos[rightAnkleIndex].z - jointsPos[leftAnkleIndex].z) > -0.2f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, rightAnkleIndex, jointsPos[rightAnkleIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = jointsTracked[leftAnkleIndex] && jointsTracked[rightAnkleIndex] && jointsTracked[rightHipIndex] &&
|
|
(jointsPos[rightAnkleIndex].z - jointsPos[leftAnkleIndex].z) < -0.4f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case GestureType.Run:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
// check if the left knee is up
|
|
if (jointsTracked[leftKneeIndex] && jointsTracked[rightKneeIndex] &&
|
|
(jointsPos[leftKneeIndex].y - jointsPos[rightKneeIndex].y) > 0.1f)
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, leftKneeIndex, jointsPos[leftKneeIndex]);
|
|
gestureData.progress = 0.3f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture complete
|
|
if ((timestamp - gestureData.timestamp) < 1.0f)
|
|
{
|
|
// check if the right knee is up
|
|
bool isInPose = jointsTracked[rightKneeIndex] && jointsTracked[leftKneeIndex] &&
|
|
(jointsPos[rightKneeIndex].y - jointsPos[leftKneeIndex].y) > 0.1f;
|
|
|
|
if (isInPose)
|
|
{
|
|
// go to state 2
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.progress = 0.7f;
|
|
gestureData.state = 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
|
|
case 2: // gesture complete
|
|
if ((timestamp - gestureData.timestamp) < 1.0f)
|
|
{
|
|
// check if the left knee is up again
|
|
bool isInPose = jointsTracked[leftKneeIndex] && jointsTracked[rightKneeIndex] &&
|
|
(jointsPos[leftKneeIndex].y - jointsPos[rightKneeIndex].y) > 0.1f;
|
|
|
|
if (isInPose)
|
|
{
|
|
// go back to state 1
|
|
gestureData.timestamp = timestamp;
|
|
gestureData.progress = 0.8f;
|
|
gestureData.state = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for MoveLeft
|
|
case GestureType.MoveLeft:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[hipCenterIndex])
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, hipCenterIndex, jointsPos[hipCenterIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = jointsTracked[hipCenterIndex] &&
|
|
(jointsPos[hipCenterIndex].x - gestureData.jointPos.x) < -0.25f &&
|
|
Mathf.Abs(jointsPos[hipCenterIndex].z - gestureData.jointPos.z) < 0.1f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// check for MoveRight
|
|
case GestureType.MoveRight:
|
|
switch (gestureData.state)
|
|
{
|
|
case 0: // gesture detection - phase 1
|
|
if (jointsTracked[hipCenterIndex])
|
|
{
|
|
SetGestureJoint(ref gestureData, timestamp, hipCenterIndex, jointsPos[hipCenterIndex]);
|
|
gestureData.progress = 0.5f;
|
|
}
|
|
break;
|
|
|
|
case 1: // gesture phase 2 = complete
|
|
if ((timestamp - gestureData.timestamp) < 1.5f)
|
|
{
|
|
bool isInPose = jointsTracked[hipCenterIndex] &&
|
|
(jointsPos[hipCenterIndex].x - gestureData.jointPos.x) > 0.25f &&
|
|
Mathf.Abs(jointsPos[hipCenterIndex].z - gestureData.jointPos.z) < 0.1f;
|
|
|
|
if (isInPose)
|
|
{
|
|
Vector3 jointPos = jointsPos[gestureData.joint];
|
|
CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// cancel the gesture
|
|
SetGestureCancelled(ref gestureData);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// here come more gesture-cases
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|