프로젝트

일반

사용자정보

통계
| 개정판:

t1 / TFDContents / Assets / KinectScripts / KinectGestures.cs @ 3

이력 | 보기 | 이력해설 | 다운로드 (64.9 KB)

1
using UnityEngine;
2
//using Windows.Kinect;
3

    
4
using System.Collections;
5
using System.Collections.Generic;
6

    
7

    
8
/// <summary>
9
/// This interface needs to be implemented by the Kinect gesture managers, like KinectGestures-class itself
10
/// </summary>
11
public interface GestureManagerInterface
12
{
13
	/// <summary>
14
	/// Gets the list of gesture joint indexes.
15
	/// </summary>
16
	/// <returns>The needed joint indexes.</returns>
17
	/// <param name="manager">The KinectManager instance</param>
18
	int[] GetNeededJointIndexes (KinectManager manager);
19

    
20

    
21
	/// <summary>
22
	/// Estimate the state and progress of the given gesture.
23
	/// </summary>
24
	/// <param name="userId">User ID</param>
25
	/// <param name="gestureData">Gesture-data structure</param>
26
	/// <param name="timestamp">Current time</param>
27
	/// <param name="jointsPos">Joints-position array</param>
28
	/// <param name="jointsTracked">Joints-tracked array</param>
29
	void CheckForGesture (long userId, ref KinectGestures.GestureData gestureData, float timestamp, ref Vector3[] jointsPos, ref bool[] jointsTracked);
30
}
31

    
32

    
33
/// <summary>
34
/// KinectGestures is utility class that processes programmatic Kinect gestures
35
/// </summary>
36
public class KinectGestures : MonoBehaviour, GestureManagerInterface
37
{
38

    
39
	/// <summary>
40
	/// This interface needs to be implemented by all Kinect gesture listeners
41
	/// </summary>
42
	public interface GestureListenerInterface
43
	{
44
		/// <summary>
45
		/// Invoked when a new user is detected. Here you can start gesture tracking by invoking KinectManager.DetectGesture()-function.
46
		/// </summary>
47
		/// <param name="userId">User ID</param>
48
		/// <param name="userIndex">User index</param>
49
		void UserDetected(long userId, int userIndex);
50
		
51
		/// <summary>
52
		/// Invoked when a user gets lost. All tracked gestures for this user are cleared automatically.
53
		/// </summary>
54
		/// <param name="userId">User ID</param>
55
		/// <param name="userIndex">User index</param>
56
		void UserLost(long userId, int userIndex);
57
		
58
		/// <summary>
59
		/// Invoked when a gesture is in progress.
60
		/// </summary>
61
		/// <param name="userId">User ID</param>
62
		/// <param name="userIndex">User index</param>
63
		/// <param name="gesture">Gesture type</param>
64
		/// <param name="progress">Gesture progress [0..1]</param>
65
		/// <param name="joint">Joint type</param>
66
		/// <param name="screenPos">Normalized viewport position</param>
67
		void GestureInProgress(long userId, int userIndex, Gestures gesture, float progress, 
68
		                       KinectInterop.JointType joint, Vector3 screenPos);
69

    
70
		/// <summary>
71
		/// Invoked if a gesture is completed.
72
		/// </summary>
73
		/// <returns><c>true</c>, if the gesture detection must be restarted, <c>false</c> otherwise.</returns>
74
		/// <param name="userId">User ID</param>
75
		/// <param name="userIndex">User index</param>
76
		/// <param name="gesture">Gesture type</param>
77
		/// <param name="joint">Joint type</param>
78
		/// <param name="screenPos">Normalized viewport position</param>
79
		bool GestureCompleted(long userId, int userIndex, Gestures gesture,
80
		                      KinectInterop.JointType joint, Vector3 screenPos);
81

    
82
		/// <summary>
83
		/// Invoked if a gesture is cancelled.
84
		/// </summary>
85
		/// <returns><c>true</c>, if the gesture detection must be retarted, <c>false</c> otherwise.</returns>
86
		/// <param name="userId">User ID</param>
87
		/// <param name="userIndex">User index</param>
88
		/// <param name="gesture">Gesture type</param>
89
		/// <param name="joint">Joint type</param>
90
		bool GestureCancelled(long userId, int userIndex, Gestures gesture, 
91
		                      KinectInterop.JointType joint);
92
	}
93

    
94

    
95
	/// <summary>
96
	/// The gesture types.
97
	/// </summary>
98
	public enum Gestures
99
	{
100
		None = 0,
101
		RaiseRightHand,
102
		RaiseLeftHand,
103
		Psi,
104
		Tpose,
105
		Stop,
106
		Wave,
107
//		Click,
108
		SwipeLeft,
109
		SwipeRight,
110
		SwipeUp,
111
		SwipeDown,
112
//		RightHandCursor,
113
//		LeftHandCursor,
114
		ZoomIn,
115
		ZoomOut,
116
		Wheel,
117
		Jump,
118
		Squat,
119
		Push,
120
		Pull,
121
		ShoulderLeftFront,
122
		ShoulderRightFront,
123
		LeanLeft,
124
		LeanRight,
125
		LeanForward,
126
		LeanBack,
127
		KickLeft,
128
		KickRight,
129
		Run,
130

    
131
        RaisedRightHorizontalLeftHand,   // by Andrzej W
132
        RaisedLeftHorizontalRightHand, 
133

    
134
		UserGesture1 = 101,
135
		UserGesture2 = 102,
136
		UserGesture3 = 103,
137
		UserGesture4 = 104,
138
		UserGesture5 = 105,
139
		UserGesture6 = 106,
140
		UserGesture7 = 107,
141
		UserGesture8 = 108,
142
		UserGesture9 = 109,
143
		UserGesture10 = 110,
144
	}
145
	
146
	
147
	/// <summary>
148
	/// Programmatic gesture data container.
149
	/// </summary>
150
	public struct GestureData
151
	{
152
		public long userId;
153
		public Gestures gesture;
154
		public int state;
155
		public float timestamp;
156
		public int joint;
157
		public Vector3 jointPos;
158
		public Vector3 screenPos;
159
		public float tagFloat;
160
		public Vector3 tagVector;
161
		public Vector3 tagVector2;
162
		public float progress;
163
		public bool complete;
164
		public bool cancelled;
165
		public List<Gestures> checkForGestures;
166
		public float startTrackingAtTime;
167
	}
168
	
169

    
170
	// Gesture related constants, variables and functions
171
	protected int leftHandIndex;
172
	protected int rightHandIndex;
173
		
174
	protected int leftElbowIndex;
175
	protected int rightElbowIndex;
176
		
177
	protected int leftShoulderIndex;
178
	protected int rightShoulderIndex;
179
	
180
	protected int hipCenterIndex;
181
	protected int shoulderCenterIndex;
182

    
183
	protected int leftHipIndex;
184
	protected int rightHipIndex;
185

    
186
	protected int leftKneeIndex;
187
	protected int rightKneeIndex;
188
	
189
	protected int leftAnkleIndex;
190
	protected int rightAnkleIndex;
191

    
192

    
193
	/// <summary>
194
	/// Gets the list of gesture joint indexes.
195
	/// </summary>
196
	/// <returns>The needed joint indexes.</returns>
197
	/// <param name="manager">The KinectManager instance</param>
198
	public virtual int[] GetNeededJointIndexes(KinectManager manager)
199
	{
200
		leftHandIndex = manager.GetJointIndex(KinectInterop.JointType.HandLeft);
201
		rightHandIndex = manager.GetJointIndex(KinectInterop.JointType.HandRight);
202
		
203
		leftElbowIndex = manager.GetJointIndex(KinectInterop.JointType.ElbowLeft);
204
		rightElbowIndex = manager.GetJointIndex(KinectInterop.JointType.ElbowRight);
205
		
206
		leftShoulderIndex = manager.GetJointIndex(KinectInterop.JointType.ShoulderLeft);
207
		rightShoulderIndex = manager.GetJointIndex(KinectInterop.JointType.ShoulderRight);
208
		
209
		hipCenterIndex = manager.GetJointIndex(KinectInterop.JointType.SpineBase);
210
		shoulderCenterIndex = manager.GetJointIndex(KinectInterop.JointType.SpineShoulder);
211

    
212
		leftHipIndex = manager.GetJointIndex(KinectInterop.JointType.HipLeft);
213
		rightHipIndex = manager.GetJointIndex(KinectInterop.JointType.HipRight);
214

    
215
		leftKneeIndex = manager.GetJointIndex(KinectInterop.JointType.KneeLeft);
216
		rightKneeIndex = manager.GetJointIndex(KinectInterop.JointType.KneeRight);
217
		
218
		leftAnkleIndex = manager.GetJointIndex(KinectInterop.JointType.AnkleLeft);
219
		rightAnkleIndex = manager.GetJointIndex(KinectInterop.JointType.AnkleRight);
220
		
221
		int[] neededJointIndexes = {
222
			leftHandIndex, rightHandIndex, leftElbowIndex, rightElbowIndex, leftShoulderIndex, rightShoulderIndex,
223
			hipCenterIndex, shoulderCenterIndex, leftHipIndex, rightHipIndex, leftKneeIndex, rightKneeIndex, 
224
			leftAnkleIndex, rightAnkleIndex
225
		};
226

    
227
		return neededJointIndexes;
228
	}
229
	
230

    
231
	protected void SetGestureJoint(ref GestureData gestureData, float timestamp, int joint, Vector3 jointPos)
232
	{
233
		gestureData.joint = joint;
234
		gestureData.jointPos = jointPos;
235
		gestureData.timestamp = timestamp;
236
		gestureData.state++;
237
	}
238
	
239
	protected void SetGestureCancelled(ref GestureData gestureData)
240
	{
241
		gestureData.state = 0;
242
		gestureData.progress = 0f;
243
		gestureData.cancelled = true;
244
	}
245
	
246
	protected void CheckPoseComplete(ref GestureData gestureData, float timestamp, Vector3 jointPos, bool isInPose, float durationToComplete)
247
	{
248
		if(isInPose)
249
		{
250
			float timeLeft = timestamp - gestureData.timestamp;
251
			gestureData.progress = durationToComplete > 0f ? Mathf.Clamp01(timeLeft / durationToComplete) : 1.0f;
252
	
253
			if(timeLeft >= durationToComplete)
254
			{
255
				gestureData.timestamp = timestamp;
256
				gestureData.jointPos = jointPos;
257
				gestureData.state++;
258
				gestureData.complete = true;
259
			}
260
		}
261
		else
262
		{
263
			SetGestureCancelled(ref gestureData);
264
		}
265
	}
266
	
267
	protected void SetScreenPos(long userId, ref GestureData gestureData, ref Vector3[] jointsPos, ref bool[] jointsTracked)
268
	{
269
		Vector3 handPos = jointsPos[rightHandIndex];
270
		bool calculateCoords = false;
271
		
272
		if(gestureData.joint == rightHandIndex)
273
		{
274
			if(jointsTracked[rightHandIndex] /**&& jointsTracked[rightElbowIndex] && jointsTracked[rightShoulderIndex]*/)
275
			{
276
				calculateCoords = true;
277
			}
278
		}
279
		else if(gestureData.joint == leftHandIndex)
280
		{
281
			if(jointsTracked[leftHandIndex] /**&& jointsTracked[leftElbowIndex] && jointsTracked[leftShoulderIndex]*/)
282
			{
283
				handPos = jointsPos[leftHandIndex];
284
				calculateCoords = true;
285
			}
286
		}
287
		
288
		if(calculateCoords)
289
		{
290
			if(jointsTracked[hipCenterIndex] && jointsTracked[shoulderCenterIndex] && 
291
				jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex])
292
			{
293
				Vector3 shoulderToHips = jointsPos[shoulderCenterIndex] - jointsPos[hipCenterIndex];
294
				Vector3 rightToLeft = jointsPos[rightShoulderIndex] - jointsPos[leftShoulderIndex];
295
				
296
				gestureData.tagVector2.x = rightToLeft.x; // * 1.2f;
297
				gestureData.tagVector2.y = shoulderToHips.y; // * 1.2f;
298
				
299
				if(gestureData.joint == rightHandIndex)
300
				{
301
					gestureData.tagVector.x = jointsPos[rightShoulderIndex].x - gestureData.tagVector2.x / 2;
302
					gestureData.tagVector.y = jointsPos[hipCenterIndex].y;
303
				}
304
				else
305
				{
306
					gestureData.tagVector.x = jointsPos[leftShoulderIndex].x - gestureData.tagVector2.x / 2;
307
					gestureData.tagVector.y = jointsPos[hipCenterIndex].y;
308
				}
309
			}
310
	
311
			if(gestureData.tagVector2.x != 0 && gestureData.tagVector2.y != 0)
312
			{
313
				Vector3 relHandPos = handPos - gestureData.tagVector;
314
				gestureData.screenPos.x = Mathf.Clamp01(relHandPos.x / gestureData.tagVector2.x);
315
				gestureData.screenPos.y = Mathf.Clamp01(relHandPos.y / gestureData.tagVector2.y);
316
			}
317
			
318
		}
319
	}
320
	
321
	protected void SetZoomFactor(long userId, ref GestureData gestureData, float initialZoom, ref Vector3[] jointsPos, ref bool[] jointsTracked)
322
	{
323
		Vector3 vectorZooming = jointsPos[rightHandIndex] - jointsPos[leftHandIndex];
324
		
325
		if(gestureData.tagFloat == 0f || gestureData.userId != userId)
326
		{
327
			gestureData.tagFloat = 0.5f; // this is 100%
328
		}
329

    
330
		float distZooming = vectorZooming.magnitude;
331
		gestureData.screenPos.z = initialZoom + (distZooming / gestureData.tagFloat);
332
	}
333
	
334
	protected void SetWheelRotation(long userId, ref GestureData gestureData, Vector3 initialPos, Vector3 currentPos)
335
	{
336
		float angle = Vector3.Angle(initialPos, currentPos) * Mathf.Sign(currentPos.y - initialPos.y);
337
		gestureData.screenPos.z = angle;
338
	}
339

    
340
	
341
	/// <summary>
342
	/// Estimate the state and progress of the given gesture.
343
	/// </summary>
344
	/// <param name="userId">User ID</param>
345
	/// <param name="gestureData">Gesture-data structure</param>
346
	/// <param name="timestamp">Current time</param>
347
	/// <param name="jointsPos">Joints-position array</param>
348
	/// <param name="jointsTracked">Joints-tracked array</param>
349
	public virtual void CheckForGesture(long userId, ref GestureData gestureData, float timestamp, ref Vector3[] jointsPos, ref bool[] jointsTracked)
350
	{
351
		if(gestureData.complete)
352
			return;
353

    
354
		float bandTopY = jointsPos[rightShoulderIndex].y > jointsPos[leftShoulderIndex].y ? jointsPos[rightShoulderIndex].y : jointsPos[leftShoulderIndex].y;
355
		float bandBotY = jointsPos[rightHipIndex].y < jointsPos[leftHipIndex].y ? jointsPos[rightHipIndex].y : jointsPos[leftHipIndex].y;
356

    
357
		float bandCenter = (bandTopY + bandBotY) / 2f;
358
		float bandSize = (bandTopY - bandBotY);
359

    
360
		float gestureTop = bandCenter + bandSize * 1.2f / 2f;
361
		float gestureBottom = bandCenter - bandSize * 1.3f / 4f;
362
		float gestureRight = jointsPos[rightHipIndex].x;
363
		float gestureLeft = jointsPos[leftHipIndex].x;
364
		
365
		switch(gestureData.gesture)
366
		{
367
			// check for RaiseRightHand
368
			case Gestures.RaiseRightHand:
369
				switch(gestureData.state)
370
				{
371
					case 0:  // gesture detection
372
						if(jointsTracked[rightHandIndex] && jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] &&
373
							(jointsPos[rightHandIndex].y - jointsPos[leftShoulderIndex].y) > 0.1f &&
374
				   			(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) < 0f)
375
						{
376
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
377
						}
378
						break;
379
							
380
					case 1:  // gesture complete
381
						bool isInPose = jointsTracked[rightHandIndex] && jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] &&
382
							(jointsPos[rightHandIndex].y - jointsPos[leftShoulderIndex].y) > 0.1f &&
383
							(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) < 0f;
384

    
385
						Vector3 jointPos = jointsPos[gestureData.joint];
386
						CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
387
						break;
388
				}
389
				break;
390

    
391
			// check for RaiseLeftHand
392
			case Gestures.RaiseLeftHand:
393
				switch(gestureData.state)
394
				{
395
					case 0:  // gesture detection
396
						if(jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] &&
397
							(jointsPos[leftHandIndex].y - jointsPos[rightShoulderIndex].y) > 0.1f &&
398
				   			(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) < 0f)
399
						{
400
							SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
401
						}
402
						break;
403
							
404
					case 1:  // gesture complete
405
						bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] &&
406
							(jointsPos[leftHandIndex].y - jointsPos[rightShoulderIndex].y) > 0.1f &&
407
							(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) < 0f;
408

    
409
						Vector3 jointPos = jointsPos[gestureData.joint];
410
						CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
411
						break;
412
				}
413
				break;
414

    
415
			// check for Psi
416
			case Gestures.Psi:
417
				switch(gestureData.state)
418
				{
419
					case 0:  // gesture detection
420
						if(jointsTracked[rightHandIndex] && jointsTracked[leftHandIndex] && jointsTracked[shoulderCenterIndex] &&
421
					       (jointsPos[rightHandIndex].y - jointsPos[shoulderCenterIndex].y) > 0.1f &&
422
					       (jointsPos[leftHandIndex].y - jointsPos[shoulderCenterIndex].y) > 0.1f)
423
						{
424
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
425
						}
426
						break;
427
							
428
					case 1:  // gesture complete
429
						bool isInPose = jointsTracked[rightHandIndex] && jointsTracked[leftHandIndex] && jointsTracked[shoulderCenterIndex] &&
430
							(jointsPos[rightHandIndex].y - jointsPos[shoulderCenterIndex].y) > 0.1f &&
431
							(jointsPos[leftHandIndex].y - jointsPos[shoulderCenterIndex].y) > 0.1f;
432

    
433
						Vector3 jointPos = jointsPos[gestureData.joint];
434
						CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
435
						break;
436
				}
437
				break;
438

    
439
			// check for Tpose
440
			case Gestures.Tpose:
441
				switch(gestureData.state)
442
				{
443
					case 0:  // gesture detection
444
						if(jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[rightShoulderIndex] &&
445
                            Mathf.Abs(jointsPos[rightElbowIndex].y - jointsPos[rightShoulderIndex].y) < 0.1f &&  // 0.07f
446
                            Mathf.Abs(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) < 0.1f &&  // 0.7f
447
                            jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[leftShoulderIndex] &&
448
                            Mathf.Abs(jointsPos[leftElbowIndex].y - jointsPos[leftShoulderIndex].y) < 0.1f &&
449
                            Mathf.Abs(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) < 0.1f)
450
						{
451
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
452
						}
453
						break;
454
						
455
					case 1:  // gesture complete
456
						bool isInPose = jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[rightShoulderIndex] &&
457
							Mathf.Abs(jointsPos[rightElbowIndex].y - jointsPos[rightShoulderIndex].y) < 0.1f &&  // 0.7f
458
							Mathf.Abs(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) < 0.1f &&  // 0.7f
459
							jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[leftShoulderIndex] &&
460
							Mathf.Abs(jointsPos[leftElbowIndex].y - jointsPos[leftShoulderIndex].y) < 0.1f &&
461
							Mathf.Abs(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) < 0.1f;
462
						
463
						Vector3 jointPos = jointsPos[gestureData.joint];
464
						CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
465
						break;
466
				}
467
				break;
468
				
469
			// check for Stop
470
			case Gestures.Stop:
471
				switch(gestureData.state)
472
				{
473
					case 0:  // gesture detection
474
						if(jointsTracked[rightHandIndex] && jointsTracked[rightHipIndex] &&
475
					       (jointsPos[rightHandIndex].y - jointsPos[rightHipIndex].y) < 0.2f &&
476
				   		   (jointsPos[rightHandIndex].x - jointsPos[rightHipIndex].x) >= 0.4f)
477
						{
478
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
479
						}
480
						else if(jointsTracked[leftHandIndex] && jointsTracked[leftHipIndex] &&
481
					       (jointsPos[leftHandIndex].y - jointsPos[leftHipIndex].y) < 0.2f &&
482
				           (jointsPos[leftHandIndex].x - jointsPos[leftHipIndex].x) <= -0.4f)
483
						{
484
							SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
485
						}
486
						break;
487
							
488
					case 1:  // gesture complete
489
						bool isInPose = (gestureData.joint == rightHandIndex) ?
490
							(jointsTracked[rightHandIndex] && jointsTracked[rightHipIndex] &&
491
							(jointsPos[rightHandIndex].y - jointsPos[rightHipIndex].y) < 0.2f &&
492
				 			(jointsPos[rightHandIndex].x - jointsPos[rightHipIndex].x) >= 0.4f) :
493
							(jointsTracked[leftHandIndex] && jointsTracked[leftHipIndex] &&
494
							(jointsPos[leftHandIndex].y - jointsPos[leftHipIndex].y) < 0.2f &&
495
						 	(jointsPos[leftHandIndex].x - jointsPos[leftHipIndex].x) <= -0.4f);
496

    
497
						Vector3 jointPos = jointsPos[gestureData.joint];
498
						CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
499
						break;
500
				}
501
				break;
502

    
503
			// check for raised right hand & horizontal left hand 
504
			case Gestures.RaisedRightHorizontalLeftHand:
505
				switch(gestureData.state)
506
				{
507
					case 0:  // gesture detection
508
						if( jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] && // check right hand is straight up 
509
						   (jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) > 0.5f &&  // ensure right hand is higher than shoulder 
510
                           Mathf.Abs(jointsPos[rightHandIndex].z - jointsPos[rightShoulderIndex].z) < 0.35f &&   // ensue hand is vertical straight enough 
511
                           Mathf.Abs(jointsPos[rightHandIndex].x - jointsPos[rightShoulderIndex].x) < 0.35f &&   // ensue hand is vertical straight enough                             
512
					   	   jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] &&  // check left hand is straight flat 
513
					       Mathf.Abs(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) < 0.25f &&       // ensure hand and shoulder are on close height 
514
					       (jointsPos[leftHandIndex] - jointsPos[leftShoulderIndex]).sqrMagnitude > 0.25f )  // ensure hand and shoulder are horizontal straight enough 						
515
                        {
516
                            SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
517
                        }
518
                        break;
519

    
520
						
521
					case 1:  // gesture complete
522
						bool isInPose = jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] && // check right hand is straight up 
523
						   (jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) > 0.5f &&  // ensure right hand is higher than shoulder 
524
                           Mathf.Abs(jointsPos[rightHandIndex].z - jointsPos[rightShoulderIndex].z) < 0.35f &&   // ensue hand is vertical straight enough 
525
                           Mathf.Abs(jointsPos[rightHandIndex].x - jointsPos[rightShoulderIndex].x) < 0.35f &&   // ensue hand is vertical straight enough                             
526
					   	   jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] &&  // check left hand is straight flat 
527
					       Mathf.Abs(jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) < 0.25f &&       // ensure hand and shoulder are on close height 
528
					       (jointsPos[leftHandIndex] - jointsPos[leftShoulderIndex]).sqrMagnitude > 0.25f;  // ensure hand and shoulder are horizontal straight enough
529
				
530
						Vector3 jointPos = jointsPos[gestureData.joint];
531
						CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
532
						break;
533
				}
534
				break;
535
				
536
			// check for raised left hand & horizontal right hand 
537
			case Gestures.RaisedLeftHorizontalRightHand:
538
				switch(gestureData.state)
539
				{
540
					case 0:  // gesture detection
541
						if( jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] && // check left hand is straight up 
542
						   (jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) > 0.5f &&  // ensure left hand is higher than shoulder 
543
                           Mathf.Abs(jointsPos[leftHandIndex].z - jointsPos[leftShoulderIndex].z) < 0.35f &&   // ensue hand is vertical straight enough 
544
                           Mathf.Abs(jointsPos[leftHandIndex].x - jointsPos[leftShoulderIndex].x) < 0.35f &&   // ensue hand is vertical straight enough                             
545
					   	   jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] &&  // check right hand is straight flat 
546
					       Mathf.Abs(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) < 0.25f &&       // ensure hand and shoulder are on close height 
547
						   (jointsPos[rightHandIndex] - jointsPos[rightShoulderIndex]).sqrMagnitude > 0.25f )  // ensure hand and shoulder are horizontal straight enough 
548
						{
549
							SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
550
						}
551
						break;
552
						
553
					case 1:  // gesture complete
554
						bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[leftShoulderIndex] && // check left hand is straight up 
555
					       (jointsPos[leftHandIndex].y - jointsPos[leftShoulderIndex].y) > 0.5f &&  // ensure left hand is higher than shoulder 
556
                           Mathf.Abs(jointsPos[leftHandIndex].z - jointsPos[leftShoulderIndex].z) < 0.35f &&   // ensue hand is vertical straight enough 
557
                           Mathf.Abs(jointsPos[leftHandIndex].x - jointsPos[leftShoulderIndex].x) < 0.35f &&   // ensue hand is vertical straight enough                             
558
					   	   jointsTracked[rightHandIndex] && jointsTracked[rightShoulderIndex] &&  // check right hand is straight flat 
559
					       Mathf.Abs(jointsPos[rightHandIndex].y - jointsPos[rightShoulderIndex].y) < 0.25f &&       // ensure hand and shoulder are on close height 
560
					       (jointsPos[rightHandIndex] - jointsPos[rightShoulderIndex]).sqrMagnitude > 0.25f;  // ensure hand and shoulder are horizontal straight enough
561
				
562
						Vector3 jointPos = jointsPos[gestureData.joint];
563
						CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.PoseCompleteDuration);
564
						break;
565
				}
566
				break;
567

    
568
			// check for Wave
569
			case Gestures.Wave:
570
				switch(gestureData.state)
571
				{
572
					case 0:  // gesture detection - phase 1
573
						if(jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] &&
574
					       (jointsPos[rightHandIndex].y - jointsPos[rightElbowIndex].y) > 0.1f &&
575
					       (jointsPos[rightHandIndex].x - jointsPos[rightElbowIndex].x) > 0.05f)
576
						{
577
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
578
							gestureData.progress = 0.3f;
579
						}
580
						else if(jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] &&
581
					            (jointsPos[leftHandIndex].y - jointsPos[leftElbowIndex].y) > 0.1f &&
582
					            (jointsPos[leftHandIndex].x - jointsPos[leftElbowIndex].x) < -0.05f)
583
						{
584
							SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
585
							gestureData.progress = 0.3f;
586
						}
587
						break;
588
				
589
					case 1:  // gesture - phase 2
590
						if((timestamp - gestureData.timestamp) < 1.5f)
591
						{
592
							bool isInPose = gestureData.joint == rightHandIndex ?
593
								jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] &&
594
								(jointsPos[rightHandIndex].y - jointsPos[rightElbowIndex].y) > 0.1f && 
595
								(jointsPos[rightHandIndex].x - jointsPos[rightElbowIndex].x) < -0.05f :
596
								jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] &&
597
								(jointsPos[leftHandIndex].y - jointsPos[leftElbowIndex].y) > 0.1f &&
598
								(jointsPos[leftHandIndex].x - jointsPos[leftElbowIndex].x) > 0.05f;
599
				
600
							if(isInPose)
601
							{
602
								gestureData.timestamp = timestamp;
603
								gestureData.state++;
604
								gestureData.progress = 0.7f;
605
							}
606
						}
607
						else
608
						{
609
							// cancel the gesture
610
							SetGestureCancelled(ref gestureData);
611
						}
612
						break;
613
									
614
					case 2:  // gesture phase 3 = complete
615
						if((timestamp - gestureData.timestamp) < 1.5f)
616
						{
617
							bool isInPose = gestureData.joint == rightHandIndex ?
618
								jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] &&
619
								(jointsPos[rightHandIndex].y - jointsPos[rightElbowIndex].y) > 0.1f && 
620
								(jointsPos[rightHandIndex].x - jointsPos[rightElbowIndex].x) > 0.05f :
621
								jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] &&
622
								(jointsPos[leftHandIndex].y - jointsPos[leftElbowIndex].y) > 0.1f &&
623
								(jointsPos[leftHandIndex].x - jointsPos[leftElbowIndex].x) < -0.05f;
624

    
625
							if(isInPose)
626
							{
627
								Vector3 jointPos = jointsPos[gestureData.joint];
628
								CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
629
							}
630
						}
631
						else
632
						{
633
							// cancel the gesture
634
							SetGestureCancelled(ref gestureData);
635
						}
636
						break;
637
				}
638
				break;
639

    
640
//			// check for Click
641
//			case Gestures.Click:
642
//				switch(gestureData.state)
643
//				{
644
//					case 0:  // gesture detection - phase 1
645
//						if(jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] &&
646
//					       (jointsPos[rightHandIndex].y - jointsPos[rightElbowIndex].y) > -0.1f)
647
//						{
648
//							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
649
//							gestureData.progress = 0.3f;
650
//
651
//							// set screen position at the start, because this is the most accurate click position
652
//							SetScreenPos(userId, ref gestureData, ref jointsPos, ref jointsTracked);
653
//						}
654
//						else if(jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] &&
655
//					            (jointsPos[leftHandIndex].y - jointsPos[leftElbowIndex].y) > -0.1f)
656
//						{
657
//							SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
658
//							gestureData.progress = 0.3f;
659
//
660
//							// set screen position at the start, because this is the most accurate click position
661
//							SetScreenPos(userId, ref gestureData, ref jointsPos, ref jointsTracked);
662
//						}
663
//						break;
664
//				
665
//					case 1:  // gesture - phase 2
666
////						if((timestamp - gestureData.timestamp) < 1.0f)
667
////						{
668
////							bool isInPose = gestureData.joint == rightHandIndex ?
669
////								jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] &&
670
////								//(jointsPos[rightHandIndex].y - jointsPos[rightElbowIndex].y) > -0.1f && 
671
////								Mathf.Abs(jointsPos[rightHandIndex].x - gestureData.jointPos.x) < 0.08f &&
672
////								(jointsPos[rightHandIndex].z - gestureData.jointPos.z) < -0.05f :
673
////								jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] &&
674
////								//(jointsPos[leftHandIndex].y - jointsPos[leftElbowIndex].y) > -0.1f &&
675
////								Mathf.Abs(jointsPos[leftHandIndex].x - gestureData.jointPos.x) < 0.08f &&
676
////								(jointsPos[leftHandIndex].z - gestureData.jointPos.z) < -0.05f;
677
////				
678
////							if(isInPose)
679
////							{
680
////								gestureData.timestamp = timestamp;
681
////								gestureData.jointPos = jointsPos[gestureData.joint];
682
////								gestureData.state++;
683
////								gestureData.progress = 0.7f;
684
////							}
685
////							else
686
////							{
687
////								// check for stay-in-place
688
////								Vector3 distVector = jointsPos[gestureData.joint] - gestureData.jointPos;
689
////								isInPose = distVector.magnitude < 0.05f;
690
////
691
////								Vector3 jointPos = jointsPos[gestureData.joint];
692
////								CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, Constants.ClickStayDuration);
693
////							}
694
////						}
695
////						else
696
//						{
697
//							// check for stay-in-place
698
//							Vector3 distVector = jointsPos[gestureData.joint] - gestureData.jointPos;
699
//							bool isInPose = distVector.magnitude < 0.05f;
700
//
701
//							Vector3 jointPos = jointsPos[gestureData.joint];
702
//							CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, KinectInterop.Constants.ClickStayDuration);
703
////							SetGestureCancelled(gestureData);
704
//						}
705
//						break;
706
//									
707
////					case 2:  // gesture phase 3 = complete
708
////						if((timestamp - gestureData.timestamp) < 1.0f)
709
////						{
710
////							bool isInPose = gestureData.joint == rightHandIndex ?
711
////								jointsTracked[rightHandIndex] && jointsTracked[rightElbowIndex] &&
712
////								//(jointsPos[rightHandIndex].y - jointsPos[rightElbowIndex].y) > -0.1f && 
713
////								Mathf.Abs(jointsPos[rightHandIndex].x - gestureData.jointPos.x) < 0.08f &&
714
////								(jointsPos[rightHandIndex].z - gestureData.jointPos.z) > 0.05f :
715
////								jointsTracked[leftHandIndex] && jointsTracked[leftElbowIndex] &&
716
////								//(jointsPos[leftHandIndex].y - jointsPos[leftElbowIndex].y) > -0.1f &&
717
////								Mathf.Abs(jointsPos[leftHandIndex].x - gestureData.jointPos.x) < 0.08f &&
718
////								(jointsPos[leftHandIndex].z - gestureData.jointPos.z) > 0.05f;
719
////
720
////							if(isInPose)
721
////							{
722
////								Vector3 jointPos = jointsPos[gestureData.joint];
723
////								CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
724
////							}
725
////						}
726
////						else
727
////						{
728
////							// cancel the gesture
729
////							SetGestureCancelled(ref gestureData);
730
////						}
731
////						break;
732
//				}
733
//				break;
734

    
735
			// check for SwipeLeft
736
			case Gestures.SwipeLeft:
737
				switch(gestureData.state)
738
				{
739
					case 0:  // gesture detection - phase 1
740
						if(jointsTracked[rightHandIndex] && jointsTracked[hipCenterIndex] && jointsTracked[shoulderCenterIndex] && jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
741
						   jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
742
				   			jointsPos[rightHandIndex].x >= gestureRight /**&& jointsPos[rightHandIndex].x > gestureLeft*/)
743
						{
744
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
745
							gestureData.progress = 0.1f;
746
						}
747
						break;
748
				
749
					case 1:  // gesture phase 2 = complete
750
						if((timestamp - gestureData.timestamp) <= 1.0f)
751
						{
752
							bool isInPose = jointsTracked[rightHandIndex] && jointsTracked[hipCenterIndex] && jointsTracked[shoulderCenterIndex] && jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
753
									jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
754
									jointsPos[rightHandIndex].x <= gestureLeft;
755
							
756
							if(isInPose)
757
							{
758
								Vector3 jointPos = jointsPos[gestureData.joint];
759
								CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
760
							}
761
							else if(jointsPos[rightHandIndex].x <= gestureRight)
762
							{
763
								float gestureSize = gestureRight - gestureLeft;
764
								gestureData.progress = gestureSize > 0.01f ? (gestureRight - jointsPos[rightHandIndex].x) / gestureSize : 0f;
765
							}
766

    
767
						}
768
						else
769
						{
770
							// cancel the gesture
771
							SetGestureCancelled(ref gestureData);
772
						}
773
						break;
774
				}
775
				break;
776

    
777
			// check for SwipeRight
778
			case Gestures.SwipeRight:
779
				switch(gestureData.state)
780
				{
781
					case 0:  // gesture detection - phase 1
782
						if(jointsTracked[leftHandIndex] && jointsTracked[hipCenterIndex] && jointsTracked[shoulderCenterIndex] && jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
783
						   jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
784
				   			jointsPos[leftHandIndex].x <= gestureLeft /**&& jointsPos[leftHandIndex].x < gestureRight*/)
785
						{
786
							SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
787
							gestureData.progress = 0.1f;
788
						}
789
						break;
790
				
791
					case 1:  // gesture phase 2 = complete
792
						if((timestamp - gestureData.timestamp) <= 1.0f)
793
						{
794
							bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[hipCenterIndex] && jointsTracked[shoulderCenterIndex] && jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
795
									jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
796
									jointsPos[leftHandIndex].x >= gestureRight;
797
							
798
							if(isInPose)
799
							{
800
								Vector3 jointPos = jointsPos[gestureData.joint];
801
								CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
802
							}
803
							else if(jointsPos[leftHandIndex].x >= gestureLeft)
804
							{
805
								float gestureSize = gestureRight - gestureLeft;
806
								gestureData.progress = gestureSize > 0.01f ? (jointsPos[leftHandIndex].x - gestureLeft) / gestureSize : 0f;
807
							}
808
						}
809
						else
810
						{
811
							// cancel the gesture
812
							SetGestureCancelled(ref gestureData);
813
						}
814
						break;
815
				}
816
				break;
817

    
818
			// check for SwipeUp
819
			case Gestures.SwipeUp:
820
				switch(gestureData.state)
821
				{
822
					case 0:  // gesture detection - phase 1
823
						if(jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] &&
824
					       (jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) < -0.0f &&
825
					       (jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) > -0.15f)
826
						{
827
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
828
							gestureData.progress = 0.5f;
829
						}
830
						else if(jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] &&
831
					            (jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) < -0.0f &&
832
					            (jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) > -0.15f)
833
						{
834
							SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
835
							gestureData.progress = 0.5f;
836
						}
837
						break;
838
				
839
					case 1:  // gesture phase 2 = complete
840
						if((timestamp - gestureData.timestamp) < 1.5f)
841
						{
842
							bool isInPose = gestureData.joint == rightHandIndex ?
843
								jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] &&
844
								(jointsPos[rightHandIndex].y - jointsPos[leftShoulderIndex].y) > 0.05f && 
845
								Mathf.Abs(jointsPos[rightHandIndex].x - gestureData.jointPos.x) <= 0.15f :
846
								jointsTracked[leftHandIndex] && jointsTracked[rightShoulderIndex] &&
847
								(jointsPos[leftHandIndex].y - jointsPos[rightShoulderIndex].y) > 0.05f && 
848
								Mathf.Abs(jointsPos[leftHandIndex].x - gestureData.jointPos.x) <= 0.15f;
849

    
850
							if(isInPose)
851
							{
852
								Vector3 jointPos = jointsPos[gestureData.joint];
853
								CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
854
							}
855
						}
856
						else
857
						{
858
							// cancel the gesture
859
							SetGestureCancelled(ref gestureData);
860
						}
861
						break;
862
				}
863
				break;
864

    
865
			// check for SwipeDown
866
			case Gestures.SwipeDown:
867
				switch(gestureData.state)
868
				{
869
					case 0:  // gesture detection - phase 1
870
						if(jointsTracked[rightHandIndex] && jointsTracked[leftShoulderIndex] &&
871
					       (jointsPos[rightHandIndex].y - jointsPos[leftShoulderIndex].y) >= 0.05f)
872
						{
873
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
874
							gestureData.progress = 0.5f;
875
						}
876
						else if(jointsTracked[leftHandIndex] && jointsTracked[rightShoulderIndex] &&
877
					            (jointsPos[leftHandIndex].y - jointsPos[rightShoulderIndex].y) >= 0.05f)
878
						{
879
							SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
880
							gestureData.progress = 0.5f;
881
						}
882
						break;
883
				
884
					case 1:  // gesture phase 2 = complete
885
						if((timestamp - gestureData.timestamp) < 1.5f)
886
						{
887
							bool isInPose = gestureData.joint == rightHandIndex ?
888
								jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] &&
889
								(jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) < -0.15f && 
890
								Mathf.Abs(jointsPos[rightHandIndex].x - gestureData.jointPos.x) <= 0.15f :
891
								jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] &&
892
								(jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) < -0.15f &&
893
								Mathf.Abs(jointsPos[leftHandIndex].x - gestureData.jointPos.x) <= 0.15f;
894

    
895
							if(isInPose)
896
							{
897
								Vector3 jointPos = jointsPos[gestureData.joint];
898
								CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
899
							}
900
						}
901
						else
902
						{
903
							// cancel the gesture
904
							SetGestureCancelled(ref gestureData);
905
						}
906
						break;
907
				}
908
				break;
909

    
910
//			// check for RightHandCursor
911
//			case Gestures.RightHandCursor:
912
//				switch(gestureData.state)
913
//				{
914
//					case 0:  // gesture detection - phase 1 (perpetual)
915
//						if(jointsTracked[rightHandIndex] && jointsTracked[rightHipIndex] &&
916
//							//(jointsPos[rightHandIndex].y - jointsPos[rightHipIndex].y) > -0.1f)
917
//				   			(jointsPos[rightHandIndex].y - jointsPos[hipCenterIndex].y) >= 0f)
918
//						{
919
//							gestureData.joint = rightHandIndex;
920
//							gestureData.timestamp = timestamp;
921
//							gestureData.jointPos = jointsPos[rightHandIndex];
922
//
923
//							SetScreenPos(userId, ref gestureData, ref jointsPos, ref jointsTracked);
924
//							gestureData.progress = 0.7f;
925
//						}
926
//						else
927
//						{
928
//							// cancel the gesture
929
//							//SetGestureCancelled(ref gestureData);
930
//							gestureData.progress = 0f;
931
//						}
932
//						break;
933
//				
934
//				}
935
//				break;
936
//
937
//			// check for LeftHandCursor
938
//			case Gestures.LeftHandCursor:
939
//				switch(gestureData.state)
940
//				{
941
//					case 0:  // gesture detection - phase 1 (perpetual)
942
//						if(jointsTracked[leftHandIndex] && jointsTracked[leftHipIndex] &&
943
//							//(jointsPos[leftHandIndex].y - jointsPos[leftHipIndex].y) > -0.1f)
944
//							(jointsPos[leftHandIndex].y - jointsPos[hipCenterIndex].y) >= 0f)
945
//						{
946
//							gestureData.joint = leftHandIndex;
947
//							gestureData.timestamp = timestamp;
948
//							gestureData.jointPos = jointsPos[leftHandIndex];
949
//
950
//							SetScreenPos(userId, ref gestureData, ref jointsPos, ref jointsTracked);
951
//							gestureData.progress = 0.7f;
952
//						}
953
//						else
954
//						{
955
//							// cancel the gesture
956
//							//SetGestureCancelled(ref gestureData);
957
//							gestureData.progress = 0f;
958
//						}
959
//						break;
960
//				
961
//				}
962
//				break;
963

    
964
			// check for ZoomIn
965
			case Gestures.ZoomIn:
966
				Vector3 vectorZoomOut = (Vector3)jointsPos[rightHandIndex] - jointsPos[leftHandIndex];
967
				float distZoomOut = vectorZoomOut.magnitude;
968
			
969
				switch(gestureData.state)
970
				{
971
					case 0:  // gesture detection - phase 1
972
						if(jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[hipCenterIndex] && jointsTracked[shoulderCenterIndex] && jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
973
				   			jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
974
				   			jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
975
						   distZoomOut < 0.3f)
976
						{
977
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
978
							gestureData.tagVector = Vector3.right;
979
							gestureData.tagFloat = 0f;
980
							gestureData.progress = 0.3f;
981
						}
982
						break;
983
				
984
					case 1:  // gesture phase 2 = zooming
985
						if((timestamp - gestureData.timestamp) < 1.0f)
986
						{
987
							float angleZoomOut = Vector3.Angle(gestureData.tagVector, vectorZoomOut) * Mathf.Sign(vectorZoomOut.y - gestureData.tagVector.y);
988
							bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[hipCenterIndex] && jointsTracked[shoulderCenterIndex] && jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
989
									jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
990
									jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
991
								distZoomOut < 1.5f && Mathf.Abs(angleZoomOut) < 20f;
992

    
993
							if(isInPose)
994
							{
995
								SetZoomFactor(userId, ref gestureData, 1.0f, ref jointsPos, ref jointsTracked);
996
								gestureData.timestamp = timestamp;
997
								gestureData.progress = 0.7f;
998
							}
999
//							else
1000
//							{
1001
//								// cancel the gesture
1002
//								SetGestureCancelled(ref gestureData);
1003
//							}
1004
						}
1005
						else
1006
						{
1007
							// cancel the gesture
1008
							SetGestureCancelled(ref gestureData);
1009
						}
1010
						break;
1011
				}
1012
				break;
1013

    
1014
			// check for ZoomOut
1015
			case Gestures.ZoomOut:
1016
				Vector3 vectorZoomIn = (Vector3)jointsPos[rightHandIndex] - jointsPos[leftHandIndex];
1017
				float distZoomIn = vectorZoomIn.magnitude;
1018
				
1019
				switch(gestureData.state)
1020
				{
1021
					case 0:  // gesture detection - phase 1
1022
						if(jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[hipCenterIndex] && jointsTracked[shoulderCenterIndex] && jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
1023
						   jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
1024
						   jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
1025
						   distZoomIn >= 0.7f)
1026
						{
1027
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
1028
							gestureData.tagVector = Vector3.right;
1029
							gestureData.tagFloat = distZoomIn;
1030
							gestureData.progress = 0.3f;
1031
						}
1032
						break;
1033
				
1034
					case 1:  // gesture phase 2 = zooming
1035
						if((timestamp - gestureData.timestamp) < 1.0f)
1036
						{
1037
							float angleZoomIn = Vector3.Angle(gestureData.tagVector, vectorZoomIn) * Mathf.Sign(vectorZoomIn.y - gestureData.tagVector.y);
1038
							bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[hipCenterIndex] && jointsTracked[shoulderCenterIndex] && jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
1039
									jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
1040
									jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
1041
								distZoomIn >= 0.2f && Mathf.Abs(angleZoomIn) < 20f;
1042

    
1043
							if(isInPose)
1044
							{
1045
								SetZoomFactor(userId, ref gestureData, 0.0f, ref jointsPos, ref jointsTracked);
1046
								gestureData.timestamp = timestamp;
1047
								gestureData.progress = 0.7f;
1048
							}
1049
//							else
1050
//							{
1051
//								// cancel the gesture
1052
//								SetGestureCancelled(ref gestureData);
1053
//							}
1054
						}
1055
						else
1056
						{
1057
							// cancel the gesture
1058
							SetGestureCancelled(ref gestureData);
1059
						}
1060
						break;
1061
				}
1062
				break;
1063

    
1064
			// check for Wheel
1065
			case Gestures.Wheel:
1066
				Vector3 vectorWheel = (Vector3)jointsPos[rightHandIndex] - jointsPos[leftHandIndex];
1067
				float distWheel = vectorWheel.magnitude;
1068

    
1069
//				Debug.Log(string.Format("{0}. Dist: {1:F1}, Tag: {2:F1}, Diff: {3:F1}", gestureData.state,
1070
//				                        distWheel, gestureData.tagFloat, Mathf.Abs(distWheel - gestureData.tagFloat)));
1071

    
1072
				switch(gestureData.state)
1073
				{
1074
					case 0:  // gesture detection - phase 1
1075
						if(jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[hipCenterIndex] && jointsTracked[shoulderCenterIndex] && jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
1076
						   jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
1077
						   jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
1078
						   distWheel >= 0.3f && distWheel < 0.7f)
1079
						{
1080
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
1081
							gestureData.tagVector = Vector3.right;
1082
							gestureData.tagFloat = distWheel;
1083
							gestureData.progress = 0.3f;
1084
						}
1085
						break;
1086
				
1087
					case 1:  // gesture phase 2 = zooming
1088
						if((timestamp - gestureData.timestamp) < 0.5f)
1089
						{
1090
							float angle = Vector3.Angle(gestureData.tagVector, vectorWheel) * Mathf.Sign(vectorWheel.y - gestureData.tagVector.y);
1091
							bool isInPose = jointsTracked[leftHandIndex] && jointsTracked[rightHandIndex] && jointsTracked[hipCenterIndex] && jointsTracked[shoulderCenterIndex] && jointsTracked[leftHipIndex] && jointsTracked[rightHipIndex] &&
1092
								jointsPos[leftHandIndex].y >= gestureBottom && jointsPos[leftHandIndex].y <= gestureTop &&
1093
								jointsPos[rightHandIndex].y >= gestureBottom && jointsPos[rightHandIndex].y <= gestureTop &&
1094
								distWheel >= 0.3f && distWheel < 0.7f && 
1095
								Mathf.Abs(distWheel - gestureData.tagFloat) < 0.1f;
1096

    
1097
							if(isInPose)
1098
							{
1099
								//SetWheelRotation(userId, ref gestureData, gestureData.tagVector, vectorWheel);
1100
								gestureData.screenPos.z = angle;  // wheel angle
1101
								gestureData.timestamp = timestamp;
1102
								gestureData.tagFloat = distWheel;
1103
								gestureData.progress = 0.7f;
1104
							}
1105
//							else
1106
//							{
1107
//								// cancel the gesture
1108
//								SetGestureCancelled(ref gestureData);
1109
//							}
1110
						}
1111
						else
1112
						{
1113
							// cancel the gesture
1114
							SetGestureCancelled(ref gestureData);
1115
						}
1116
						break;
1117
				}
1118
				break;
1119
			
1120
			// check for Jump
1121
			case Gestures.Jump:
1122
				switch(gestureData.state)
1123
				{
1124
					case 0:  // gesture detection - phase 1
1125
						if(jointsTracked[hipCenterIndex] && 
1126
							(jointsPos[hipCenterIndex].y > 0.6f) && (jointsPos[hipCenterIndex].y < 1.2f))
1127
						{
1128
							SetGestureJoint(ref gestureData, timestamp, hipCenterIndex, jointsPos[hipCenterIndex]);
1129
							gestureData.progress = 0.5f;
1130
						}
1131
						break;
1132
				
1133
					case 1:  // gesture phase 2 = complete
1134
						if((timestamp - gestureData.timestamp) < 1.5f)
1135
						{
1136
							bool isInPose = jointsTracked[hipCenterIndex] &&
1137
								(jointsPos[hipCenterIndex].y - gestureData.jointPos.y) > 0.15f && 
1138
								Mathf.Abs(jointsPos[hipCenterIndex].x - gestureData.jointPos.x) < 0.2f;
1139

    
1140
							if(isInPose)
1141
							{
1142
								Vector3 jointPos = jointsPos[gestureData.joint];
1143
								CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
1144
							}
1145
						}
1146
						else
1147
						{
1148
							// cancel the gesture
1149
							SetGestureCancelled(ref gestureData);
1150
						}
1151
						break;
1152
				}
1153
				break;
1154

    
1155
			// check for Squat
1156
			case Gestures.Squat:
1157
				switch(gestureData.state)
1158
				{
1159
					case 0:  // gesture detection - phase 1
1160
						if(jointsTracked[hipCenterIndex] && 
1161
							(jointsPos[hipCenterIndex].y <= 0.7f))
1162
						{
1163
							SetGestureJoint(ref gestureData, timestamp, hipCenterIndex, jointsPos[hipCenterIndex]);
1164
							gestureData.progress = 0.5f;
1165
						}
1166
						break;
1167
				
1168
					case 1:  // gesture phase 2 = complete
1169
						if((timestamp - gestureData.timestamp) < 1.5f)
1170
						{
1171
							bool isInPose = jointsTracked[hipCenterIndex] &&
1172
								(jointsPos[hipCenterIndex].y - gestureData.jointPos.y) < -0.15f && 
1173
								Mathf.Abs(jointsPos[hipCenterIndex].x - gestureData.jointPos.x) < 0.2f;
1174

    
1175
							if(isInPose)
1176
							{
1177
								Vector3 jointPos = jointsPos[gestureData.joint];
1178
								CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
1179
							}
1180
						}
1181
						else
1182
						{
1183
							// cancel the gesture
1184
							SetGestureCancelled(ref gestureData);
1185
						}
1186
						break;
1187
				}
1188
				break;
1189

    
1190
			// check for Push
1191
			case Gestures.Push:
1192
				switch(gestureData.state)
1193
				{
1194
					case 0:  // gesture detection - phase 1
1195
						if(jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[rightShoulderIndex] &&
1196
				   			(jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) > -0.1f &&
1197
				   			Mathf.Abs(jointsPos[rightHandIndex].x - jointsPos[rightShoulderIndex].x) < 0.2f &&
1198
				   			(jointsPos[rightHandIndex].z - jointsPos[leftElbowIndex].z) < -0.2f)
1199
						{
1200
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
1201
							gestureData.progress = 0.5f;
1202
						}
1203
						else if(jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[leftShoulderIndex] &&
1204
								(jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) > -0.1f &&
1205
								Mathf.Abs(jointsPos[leftHandIndex].x - jointsPos[leftShoulderIndex].x) < 0.2f &&
1206
								(jointsPos[leftHandIndex].z - jointsPos[rightElbowIndex].z) < -0.2f)
1207
						{
1208
							SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
1209
							gestureData.progress = 0.5f;
1210
						}
1211
						break;
1212
				
1213
					case 1:  // gesture phase 2 = complete
1214
						if((timestamp - gestureData.timestamp) < 1.5f)
1215
						{
1216
							bool isInPose = gestureData.joint == rightHandIndex ?
1217
								jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[rightShoulderIndex] &&
1218
								(jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) > -0.1f &&
1219
								Mathf.Abs(jointsPos[rightHandIndex].x - gestureData.jointPos.x) < 0.2f &&
1220
								(jointsPos[rightHandIndex].z - gestureData.jointPos.z) < -0.2f :
1221
								jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[leftShoulderIndex] &&
1222
								(jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) > -0.1f &&
1223
								Mathf.Abs(jointsPos[leftHandIndex].x - gestureData.jointPos.x) < 0.2f &&
1224
								(jointsPos[leftHandIndex].z - gestureData.jointPos.z) < -0.2f;
1225

    
1226
							if(isInPose)
1227
							{
1228
								Vector3 jointPos = jointsPos[gestureData.joint];
1229
								CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
1230
							}
1231
						}
1232
						else
1233
						{
1234
							// cancel the gesture
1235
							SetGestureCancelled(ref gestureData);
1236
						}
1237
						break;
1238
				}
1239
				break;
1240

    
1241
			// check for Pull
1242
			case Gestures.Pull:
1243
				switch(gestureData.state)
1244
				{
1245
					case 0:  // gesture detection - phase 1
1246
						if(jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[rightShoulderIndex] &&
1247
						   (jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) > -0.1f &&
1248
						   Mathf.Abs(jointsPos[rightHandIndex].x - jointsPos[rightShoulderIndex].x) < 0.2f &&
1249
						   (jointsPos[rightHandIndex].z - jointsPos[leftElbowIndex].z) < -0.3f)
1250
						{
1251
							SetGestureJoint(ref gestureData, timestamp, rightHandIndex, jointsPos[rightHandIndex]);
1252
							gestureData.progress = 0.5f;
1253
						}
1254
						else if(jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[leftShoulderIndex] &&
1255
						        (jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) > -0.1f &&
1256
						        Mathf.Abs(jointsPos[leftHandIndex].x - jointsPos[leftShoulderIndex].x) < 0.2f &&
1257
						        (jointsPos[leftHandIndex].z - jointsPos[rightElbowIndex].z) < -0.3f)
1258
						{
1259
							SetGestureJoint(ref gestureData, timestamp, leftHandIndex, jointsPos[leftHandIndex]);
1260
							gestureData.progress = 0.5f;
1261
						}
1262
						break;
1263
				
1264
					case 1:  // gesture phase 2 = complete
1265
						if((timestamp - gestureData.timestamp) < 1.5f)
1266
						{
1267
							bool isInPose = gestureData.joint == rightHandIndex ?
1268
								jointsTracked[rightHandIndex] && jointsTracked[leftElbowIndex] && jointsTracked[rightShoulderIndex] &&
1269
								(jointsPos[rightHandIndex].y - jointsPos[leftElbowIndex].y) > -0.1f &&
1270
								Mathf.Abs(jointsPos[rightHandIndex].x - gestureData.jointPos.x) < 0.2f &&
1271
								(jointsPos[rightHandIndex].z - gestureData.jointPos.z) > 0.25f :
1272
								jointsTracked[leftHandIndex] && jointsTracked[rightElbowIndex] && jointsTracked[leftShoulderIndex] &&
1273
								(jointsPos[leftHandIndex].y - jointsPos[rightElbowIndex].y) > -0.1f &&
1274
								Mathf.Abs(jointsPos[leftHandIndex].x - gestureData.jointPos.x) < 0.2f &&
1275
								(jointsPos[leftHandIndex].z - gestureData.jointPos.z) > 0.25f;
1276

    
1277
							if(isInPose)
1278
							{
1279
								Vector3 jointPos = jointsPos[gestureData.joint];
1280
								CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
1281
							}
1282
						}
1283
						else
1284
						{
1285
							// cancel the gesture
1286
							SetGestureCancelled(ref gestureData);
1287
						}
1288
						break;
1289
				}
1290
				break;
1291

    
1292
			// check for ShoulderLeftFron
1293
			case Gestures.ShoulderLeftFront:
1294
				switch(gestureData.state)
1295
				{
1296
				case 0:  // gesture detection - phase 1
1297
					if(jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] && jointsTracked[leftHipIndex] &&
1298
				   	   (jointsPos[rightShoulderIndex].z - jointsPos[leftHipIndex].z) < 0f &&
1299
				       (jointsPos[rightShoulderIndex].z - jointsPos[leftShoulderIndex].z) > -0.15f)
1300
					{
1301
						SetGestureJoint(ref gestureData, timestamp, rightShoulderIndex, jointsPos[rightShoulderIndex]);
1302
						gestureData.progress = 0.5f;
1303
					}
1304
					break;
1305
					
1306
				case 1:  // gesture phase 2 = complete
1307
					if((timestamp - gestureData.timestamp) < 1.5f)
1308
					{
1309
						bool isInPose = jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] && jointsTracked[leftHipIndex] &&
1310
								(jointsPos[rightShoulderIndex].z - jointsPos[leftShoulderIndex].z) < -0.2f;
1311
						
1312
						if(isInPose)
1313
						{
1314
							Vector3 jointPos = jointsPos[gestureData.joint];
1315
							CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
1316
						}
1317
					}
1318
					else
1319
					{
1320
						// cancel the gesture
1321
						SetGestureCancelled(ref gestureData);
1322
					}
1323
					break;
1324
				}
1325
				break;
1326
				
1327
			// check for ShoulderRightFront
1328
			case Gestures.ShoulderRightFront:
1329
				switch(gestureData.state)
1330
				{
1331
				case 0:  // gesture detection - phase 1
1332
					if(jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] && jointsTracked[rightHipIndex] &&
1333
					   (jointsPos[leftShoulderIndex].z - jointsPos[rightHipIndex].z) < 0f &&
1334
					   (jointsPos[leftShoulderIndex].z - jointsPos[rightShoulderIndex].z) > -0.15f)
1335
					{
1336
						SetGestureJoint(ref gestureData, timestamp, leftShoulderIndex, jointsPos[leftShoulderIndex]);
1337
						gestureData.progress = 0.5f;
1338
					}
1339
					break;
1340
					
1341
				case 1:  // gesture phase 2 = complete
1342
					if((timestamp - gestureData.timestamp) < 1.5f)
1343
					{
1344
						bool isInPose = jointsTracked[leftShoulderIndex] && jointsTracked[rightShoulderIndex] && jointsTracked[rightHipIndex] &&
1345
								(jointsPos[leftShoulderIndex].z - jointsPos[rightShoulderIndex].z) < -0.2f;
1346
						
1347
						if(isInPose)
1348
						{
1349
							Vector3 jointPos = jointsPos[gestureData.joint];
1350
							CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
1351
						}
1352
					}
1353
					else
1354
					{
1355
						// cancel the gesture
1356
						SetGestureCancelled(ref gestureData);
1357
					}
1358
					break;
1359
				}
1360
				break;
1361

    
1362
			// check for LeanLeft
1363
			case Gestures.LeanLeft:
1364
				switch(gestureData.state)
1365
				{
1366
					case 0:  // gesture detection - phase 1  (right shoulder is left of the right hip, means leaning left)
1367
						if(jointsTracked[rightShoulderIndex] && jointsTracked[rightHipIndex] &&
1368
						   (jointsPos[rightShoulderIndex].x - jointsPos[rightHipIndex].x) < 0f)
1369
						{
1370
							SetGestureJoint(ref gestureData, timestamp, rightShoulderIndex, jointsPos[rightShoulderIndex]);
1371
							gestureData.progress = 0.3f;
1372
						}
1373
						break;
1374
					
1375
					case 1:  // gesture phase 2 = complete
1376
						if((timestamp - gestureData.timestamp) < 0.5f)
1377
						{
1378
							// check if right shoulder is still left of the right hip (leaning left)
1379
							bool isInPose = jointsTracked[rightShoulderIndex] && jointsTracked[rightHipIndex] &&
1380
								(jointsPos[rightShoulderIndex].x - jointsPos[rightHipIndex].x) < 0f;
1381
							
1382
							if(isInPose)
1383
							{
1384
								// calculate lean angle
1385
								Vector3 vSpineLL = jointsPos[shoulderCenterIndex] - jointsPos[hipCenterIndex];
1386
								gestureData.screenPos.z = Vector3.Angle(Vector3.up, vSpineLL);
1387
								
1388
								gestureData.timestamp = timestamp;
1389
								gestureData.progress = 0.7f;
1390
							}
1391
						}
1392
						else
1393
						{
1394
							// cancel the gesture
1395
							SetGestureCancelled(ref gestureData);
1396
						}
1397
						break;
1398
				}
1399
				break;
1400
				
1401
				// check for LeanRight
1402
			case Gestures.LeanRight:
1403
				switch(gestureData.state)
1404
				{
1405
					case 0:  // gesture detection - phase 1 (left shoulder is right of the left hip, means leaning right)
1406
						if(jointsTracked[leftShoulderIndex] && jointsTracked[leftHipIndex] &&
1407
						   (jointsPos[leftShoulderIndex].x - jointsPos[leftHipIndex].x) > 0f)
1408
						{
1409
							SetGestureJoint(ref gestureData, timestamp, leftShoulderIndex, jointsPos[leftShoulderIndex]);
1410
							gestureData.progress = 0.3f;
1411
						}
1412
						break;
1413
					
1414
					case 1:  // gesture phase 2 = complete
1415
						if((timestamp - gestureData.timestamp) < 0.5f)
1416
						{
1417
							// check if left shoulder is still right of the left hip (leaning right)
1418
							bool isInPose = jointsTracked[leftShoulderIndex] && jointsTracked[leftHipIndex] &&
1419
								(jointsPos[leftShoulderIndex].x - jointsPos[leftHipIndex].x) > 0f;
1420
							
1421
							if(isInPose)
1422
							{
1423
								// calculate lean angle
1424
								Vector3 vSpineLR = jointsPos[shoulderCenterIndex] - jointsPos[hipCenterIndex];
1425
								gestureData.screenPos.z = Vector3.Angle(Vector3.up, vSpineLR);
1426
								
1427
								gestureData.timestamp = timestamp;
1428
								gestureData.progress = 0.7f;
1429
							}
1430
						}
1431
						else
1432
						{
1433
							// cancel the gesture
1434
							SetGestureCancelled(ref gestureData);
1435
						}
1436
						break;
1437
				}
1438
				break;
1439
				
1440
				// check for LeanForward
1441
			case Gestures.LeanForward:
1442
				switch(gestureData.state)
1443
				{
1444
				case 0:  // gesture detection - phase 1 (shoulder center in front of hip center, means leaning forward)
1445
					if(jointsTracked[shoulderCenterIndex] && jointsTracked[hipCenterIndex] &&
1446
						(jointsPos[shoulderCenterIndex].z - jointsPos[hipCenterIndex].z) < -0.1f)
1447
					{
1448
						SetGestureJoint(ref gestureData, timestamp, shoulderCenterIndex, jointsPos[shoulderCenterIndex]);
1449
						gestureData.progress = 0.3f;
1450
					}
1451
					break;
1452

    
1453
				case 1:  // gesture phase 2 = complete
1454
					if((timestamp - gestureData.timestamp) < 0.5f)
1455
					{
1456
						// check if shoulder center is still in front of the hip center (leaning forward)
1457
						bool isInPose = jointsTracked[shoulderCenterIndex] && jointsTracked[hipCenterIndex] &&
1458
							(jointsPos[shoulderCenterIndex].z - jointsPos[leftHipIndex].z) < -0.1f;
1459

    
1460
						if(isInPose)
1461
						{
1462
							// calculate lean angle
1463
							Vector3 vSpineLL = jointsPos[shoulderCenterIndex] - jointsPos[hipCenterIndex];
1464
							gestureData.screenPos.z = Vector3.Angle(Vector3.up, vSpineLL);
1465

    
1466
							gestureData.timestamp = timestamp;
1467
							gestureData.progress = 0.7f;
1468
						}
1469
					}
1470
					else
1471
					{
1472
						// cancel the gesture
1473
						SetGestureCancelled(ref gestureData);
1474
					}
1475
					break;
1476
				}
1477
				break;
1478

    
1479
				// check for LeanBack
1480
			case Gestures.LeanBack:
1481
				switch(gestureData.state)
1482
				{
1483
				case 0:  // gesture detection - phase 1 (shoulder center behind hip center, means leaning back)
1484
					if(jointsTracked[shoulderCenterIndex] && jointsTracked[hipCenterIndex] &&
1485
						(jointsPos[shoulderCenterIndex].z - jointsPos[hipCenterIndex].z) > 0.1f)
1486
					{
1487
						SetGestureJoint(ref gestureData, timestamp, shoulderCenterIndex, jointsPos[shoulderCenterIndex]);
1488
						gestureData.progress = 0.3f;
1489
					}
1490
					break;
1491

    
1492
				case 1:  // gesture phase 2 = complete
1493
					if((timestamp - gestureData.timestamp) < 0.5f)
1494
					{
1495
						// check if shoulder center is still behind of the hip center (leaning back)
1496
						bool isInPose = jointsTracked[shoulderCenterIndex] && jointsTracked[hipCenterIndex] &&
1497
							(jointsPos[shoulderCenterIndex].z - jointsPos[leftHipIndex].z) > 0.1f;
1498

    
1499
						if(isInPose)
1500
						{
1501
							// calculate lean angle
1502
							Vector3 vSpineLR = jointsPos[shoulderCenterIndex] - jointsPos[hipCenterIndex];
1503
							gestureData.screenPos.z = Vector3.Angle(Vector3.up, vSpineLR);
1504

    
1505
							gestureData.timestamp = timestamp;
1506
							gestureData.progress = 0.7f;
1507
						}
1508
					}
1509
					else
1510
					{
1511
						// cancel the gesture
1512
						SetGestureCancelled(ref gestureData);
1513
					}
1514
					break;
1515
				}
1516
				break;
1517

    
1518
			// check for KickLeft
1519
			case Gestures.KickLeft:
1520
				switch(gestureData.state)
1521
				{
1522
				case 0:  // gesture detection - phase 1
1523
					if(jointsTracked[leftAnkleIndex] && jointsTracked[rightAnkleIndex] && jointsTracked[leftHipIndex] &&
1524
					   (jointsPos[leftAnkleIndex].z - jointsPos[leftHipIndex].z) < 0f &&
1525
					   (jointsPos[leftAnkleIndex].z - jointsPos[rightAnkleIndex].z) > -0.2f)
1526
					{
1527
						SetGestureJoint(ref gestureData, timestamp, leftAnkleIndex, jointsPos[leftAnkleIndex]);
1528
						gestureData.progress = 0.5f;
1529
					}
1530
					break;
1531
					
1532
				case 1:  // gesture phase 2 = complete
1533
					if((timestamp - gestureData.timestamp) < 1.5f)
1534
					{
1535
						bool isInPose = jointsTracked[leftAnkleIndex] && jointsTracked[rightAnkleIndex] && jointsTracked[leftHipIndex] &&
1536
							(jointsPos[leftAnkleIndex].z - jointsPos[rightAnkleIndex].z) < -0.4f;
1537
						
1538
						if(isInPose)
1539
						{
1540
							Vector3 jointPos = jointsPos[gestureData.joint];
1541
							CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
1542
						}
1543
					}
1544
					else
1545
					{
1546
						// cancel the gesture
1547
						SetGestureCancelled(ref gestureData);
1548
					}
1549
					break;
1550
				}
1551
				break;
1552
			
1553
			// check for KickRight
1554
			case Gestures.KickRight:
1555
				switch(gestureData.state)
1556
				{
1557
				case 0:  // gesture detection - phase 1
1558
					if(jointsTracked[leftAnkleIndex] && jointsTracked[rightAnkleIndex] && jointsTracked[rightHipIndex] &&
1559
					   (jointsPos[rightAnkleIndex].z - jointsPos[rightHipIndex].z) < 0f &&
1560
					   (jointsPos[rightAnkleIndex].z - jointsPos[leftAnkleIndex].z) > -0.2f)
1561
					{
1562
						SetGestureJoint(ref gestureData, timestamp, rightAnkleIndex, jointsPos[rightAnkleIndex]);
1563
						gestureData.progress = 0.5f;
1564
					}
1565
					break;
1566
					
1567
				case 1:  // gesture phase 2 = complete
1568
					if((timestamp - gestureData.timestamp) < 1.5f)
1569
					{
1570
						bool isInPose = jointsTracked[leftAnkleIndex] && jointsTracked[rightAnkleIndex] && jointsTracked[rightHipIndex] &&
1571
							(jointsPos[rightAnkleIndex].z - jointsPos[leftAnkleIndex].z) < -0.4f;
1572
						
1573
						if(isInPose)
1574
						{
1575
							Vector3 jointPos = jointsPos[gestureData.joint];
1576
							CheckPoseComplete(ref gestureData, timestamp, jointPos, isInPose, 0f);
1577
						}
1578
					}
1579
					else
1580
					{
1581
						// cancel the gesture
1582
						SetGestureCancelled(ref gestureData);
1583
					}
1584
					break;
1585
				}
1586
				break;
1587
				
1588
			case Gestures.Run:
1589
				switch(gestureData.state)
1590
				{
1591
				case 0:  // gesture detection - phase 1
1592
					// check if the left knee is up
1593
					if(jointsTracked[leftKneeIndex] && jointsTracked[rightKneeIndex] &&
1594
					   (jointsPos[leftKneeIndex].y - jointsPos[rightKneeIndex].y) > 0.1f)
1595
					{
1596
						SetGestureJoint(ref gestureData, timestamp, leftKneeIndex, jointsPos[leftKneeIndex]);
1597
						gestureData.progress = 0.3f;
1598
					}
1599
					break;
1600
					
1601
				case 1:  // gesture complete
1602
					if((timestamp - gestureData.timestamp) < 1.0f)
1603
					{
1604
						// check if the right knee is up
1605
						bool isInPose = jointsTracked[rightKneeIndex] && jointsTracked[leftKneeIndex] &&
1606
							(jointsPos[rightKneeIndex].y - jointsPos[leftKneeIndex].y) > 0.1f;
1607
						
1608
						if(isInPose)
1609
						{
1610
							// go to state 2
1611
							gestureData.timestamp = timestamp;
1612
							gestureData.progress = 0.7f;
1613
							gestureData.state = 2;
1614
						}
1615
					}
1616
					else
1617
					{
1618
						// cancel the gesture
1619
						SetGestureCancelled(ref gestureData);
1620
					}
1621
					break;
1622
					
1623
				case 2:  // gesture complete
1624
					if((timestamp - gestureData.timestamp) < 1.0f)
1625
					{
1626
						// check if the left knee is up again
1627
						bool isInPose = jointsTracked[leftKneeIndex] && jointsTracked[rightKneeIndex] &&
1628
							(jointsPos[leftKneeIndex].y - jointsPos[rightKneeIndex].y) > 0.1f;
1629
						
1630
						if(isInPose)
1631
						{
1632
							// go back to state 1
1633
							gestureData.timestamp = timestamp;
1634
							gestureData.progress = 0.8f;
1635
							gestureData.state = 1;
1636
						}
1637
					}
1638
					else
1639
					{
1640
						// cancel the gesture
1641
						SetGestureCancelled(ref gestureData);
1642
					}
1643
					break;
1644
				}
1645
				break;
1646
				
1647
			// here come more gesture-cases
1648
		}
1649
	}
1650

    
1651
}