프로젝트

일반

사용자정보

통계
| 개정판:

t1 / TFDContents / Assets / KinectScripts / VisualGestureManager.cs @ 9

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

1
using UnityEngine;
2
using System;
3
using System.Collections;
4
using System.Collections.Generic;
5
using System.IO;
6
using System.Text;
7
#if !(UNITY_WSA_10_0 && NETFX_CORE)
8
using Microsoft.Kinect.VisualGestureBuilder;
9
using Windows.Kinect;
10
#endif
11

    
12
/// <summary>
13
/// This interface needs to be implemented by all visual gesture listeners
14
/// </summary>
15
public interface VisualGestureListenerInterface
16
{
17
	/// <summary>
18
	/// Invoked when a continuous gesture reports progress >= minConfidence
19
	/// </summary>
20
	/// <param name="userId">User ID</param>
21
	/// <param name="userIndex">User index</param>
22
	/// <param name="gesture">Gesture name</param>
23
	/// <param name="progress">Gesture progress [0..1]</param>
24
	void GestureInProgress(long userId, int userIndex, string gesture, float progress);
25
	
26
	/// <summary>
27
	/// Invoked when a discrete gesture is completed.
28
	/// </summary>
29
	/// <returns><c>true</c>, if the gesture detection must be restarted, <c>false</c> otherwise.</returns>
30
	/// <param name="userId">User ID</param>
31
	/// <param name="userIndex">User index</param>
32
	/// <param name="gesture">Gesture name</param>
33
	/// <param name="confidence">Gesture confidence [0..1]</param>
34
	bool GestureCompleted(long userId, int userIndex, string gesture, float confidence);
35
}
36

    
37
/// <summary>
38
/// Visual gesture data container.
39
/// </summary>
40
public struct VisualGestureData
41
{
42
	public long userId;
43
	public float timestamp;
44
	public string gestureName;
45
	public bool isDiscrete;
46
	public bool isContinuous;
47
	public bool isComplete;
48
	//public bool isResetting;
49
	public bool isProcessed;
50
	public float confidence;
51
	public float progress;
52
	public float lastTimestamp;
53
}
54

    
55
/// <summary>
56
/// Visual gesture manager is the component that manages the visual (VGB) gestures.
57
/// </summary>
58
public class VisualGestureManager : MonoBehaviour 
59
{
60
	[Tooltip("Index of the player, tracked by this component. 0 means the 1st player, 1 - the 2nd one, 2 - the 3rd one, etc.")]
61
	public int playerIndex = 0;
62

    
63
	[Tooltip("File name of the VG database, used by the visual gesture recognizer. The file will be copied from Resources, if does not exist.")]
64
	public string gestureDatabase = string.Empty;
65

    
66
	[Tooltip("List of the tracked visual gestures. If left empty, all gestures found in the database will be tracked.")]
67
	public List<string> gestureNames = new List<string>();
68

    
69
	[Tooltip("Minimum confidence required, to consider discrete gestures as completed. Confidence varies between 0.0 and 1.0.")]
70
	public float minConfidence = 0.1f;
71

    
72
	[Tooltip("List of the visual gesture listeners in the scene. If the list is empty, the available gesture listeners will be detected at the scene start up.")]
73
	public List<MonoBehaviour> visualGestureListeners;
74
	
75
	[Tooltip("GUI-Text to display the VG-manager debug messages.")]
76
	public GUIText debugText;
77

    
78

    
79
	// primary user ID, as reported by KinectManager
80
	private long primaryUserID = 0;
81

    
82
	// gesture data holders for each tracked gesture
83
	private Dictionary<string, VisualGestureData> gestureData = new Dictionary<string, VisualGestureData>();
84

    
85
#if !(UNITY_WSA_10_0 && NETFX_CORE)
86

    
87
	// gesture frame source which should be tied to a body tracking ID
88
	private VisualGestureBuilderFrameSource vgbFrameSource = null;
89
	
90
	// gesture frame reader which will handle gesture events
91
	private VisualGestureBuilderFrameReader vgbFrameReader = null;
92

    
93
#endif
94
	
95
	// primary sensor data structure
96
	//private KinectInterop.SensorData sensorData = null;
97
	
98
	// Bool to keep track of whether visual-gesture system has been initialized
99
	private bool isVisualGestureInitialized = false;
100
	
101
	// The single instance of VisualGestureManager
102
	private static VisualGestureManager instance;
103
	
104

    
105
	/// <summary>
106
	/// Gets the single VisualGestureManager instance.
107
	/// </summary>
108
	/// <value>The VisualGestureManager instance.</value>
109
	public static VisualGestureManager Instance
110
    {
111
        get
112
        {
113
            return instance;
114
        }
115
    }
116
	
117
	/// <summary>
118
	/// Determines whether the visual-gesture manager was successfully initialized.
119
	/// </summary>
120
	/// <returns><c>true</c> if visual-gesture manager was successfully initialized; otherwise, <c>false</c>.</returns>
121
	public bool IsVisualGestureInitialized()
122
	{
123
		return isVisualGestureInitialized;
124
	}
125
	
126
	/// <summary>
127
	/// Gets the skeleton ID of the tracked user, or 0 if no user was associated with the gestures.
128
	/// </summary>
129
	/// <returns>The skeleton ID of the tracked user.</returns>
130
	public long GetTrackedUserID()
131
	{
132
		return primaryUserID;
133
	}
134
	
135
	/// <summary>
136
	/// Gets the list of detected gestures.
137
	/// </summary>
138
	/// <returns>The list of detected gestures.</returns>
139
	public List<string> GetGesturesList()
140
	{
141
		return gestureNames;
142
	}
143
	
144
	/// <summary>
145
	/// Gets the count of detected gestures.
146
	/// </summary>
147
	/// <returns>The count of detected gestures.</returns>
148
	public int GetGesturesCount()
149
	{
150
		return gestureNames.Count;
151
	}
152

    
153
	/// <summary>
154
	/// Gets the gesture name at specified index, or empty string if the index is out of range.
155
	/// </summary>
156
	/// <returns>The gesture name at specified index.</returns>
157
	/// <param name="i">The index</param>
158
	public string GetGestureAtIndex(int i)
159
	{
160
		if(i >= 0 && i < gestureNames.Count)
161
		{
162
			return gestureNames[i];
163
		}
164

    
165
		return string.Empty;
166
	}
167
	
168
	/// <summary>
169
	/// Determines whether the given gesture is in the list of detected gestures.
170
	/// </summary>
171
	/// <returns><c>true</c> if the given gesture is in the list of detected gestures; otherwise, <c>false</c>.</returns>
172
	/// <param name="gestureName">Gesture name.</param>
173
	public bool IsTrackingGesture(string gestureName)
174
	{
175
		return gestureNames.Contains(gestureName);
176
	}
177
	
178
	/// <summary>
179
	/// Determines whether the specified discrete gesture is completed.
180
	/// </summary>
181
	/// <returns><c>true</c> if the specified discrete gesture is completed; otherwise, <c>false</c>.</returns>
182
	/// <param name="gestureName">Gesture name</param>
183
	/// <param name="bResetOnComplete">If set to <c>true</c>, resets the gesture state.</param>
184
	public bool IsGestureCompleted(string gestureName, bool bResetOnComplete)
185
	{
186
		if(gestureNames.Contains(gestureName))
187
		{
188
			VisualGestureData data = gestureData[gestureName];
189
			
190
			if(data.userId != 0 && data.isDiscrete && data.isComplete && /**!data.isProcessed &&*/ data.confidence >= minConfidence)
191
			{
192
				if(bResetOnComplete)
193
				{
194
					//data.isResetting = true;
195
					data.isProcessed = true;
196
					gestureData[gestureName] = data;
197
				}
198

    
199
				return true;
200
			}
201
		}
202

    
203
		return false;
204
	}
205

    
206
	/// <summary>
207
	/// Gets the confidence of the specified discrete gesture, in range [0, 1].
208
	/// </summary>
209
	/// <returns>The gesture confidence.</returns>
210
	/// <param name="gestureName">Gesture name</param>
211
	public float GetGestureConfidence(string gestureName)
212
	{
213
		if(gestureNames.Contains(gestureName))
214
		{
215
			VisualGestureData data = gestureData[gestureName];
216
			
217
			if(data.userId != 0 && data.isDiscrete)
218
			{
219
				return data.confidence;
220
			}
221
		}
222
		
223
		return 0f;
224
	}
225
	
226
	/// <summary>
227
	/// Gets the progress of the specified continuous gesture, in range [0, 1].
228
	/// </summary>
229
	/// <returns>The gesture progress.</returns>
230
	/// <param name="gestureName">Gesture name</param>
231
	public float GetGestureProgress(string gestureName)
232
	{
233
		if(gestureNames.Contains(gestureName))
234
		{
235
			VisualGestureData data = gestureData[gestureName];
236
			
237
			if(data.userId != 0 && data.isContinuous)
238
			{
239
				return data.progress;
240
			}
241
		}
242
		
243
		return 0f;
244
	}
245

    
246
	/// <summary>
247
	/// Resets the gesture state.
248
	/// </summary>
249
	/// <returns><c>true</c>, if gesture state was reset, <c>false</c> if gesture was not found.</returns>
250
	/// <param name="gestureName">Gesture name.</param>
251
	public bool ResetGesture(string gestureName)
252
	{
253
		if(gestureNames.Contains(gestureName))
254
		{
255
			VisualGestureData data = gestureData[gestureName];
256

    
257
			//data.isResetting = true;
258
			data.isProcessed = true;
259
			gestureData[gestureName] = data;
260

    
261
			return true;
262
		}
263

    
264
		return false;
265
	}
266

    
267

    
268
	// gets all gesture dara as csv line
269
	public string GetGestureDataAsCsv(char delimiter)
270
	{
271
		if (!isVisualGestureInitialized)
272
			return string.Empty;
273
		
274
		// create the output string
275
		StringBuilder sbBuf = new StringBuilder();
276
		//const char delimiter = ',';
277

    
278
		sbBuf.Append("vg").Append(delimiter);
279
		sbBuf.Append(gestureNames.Count).Append(delimiter);
280

    
281
		foreach (string gestureName in gestureNames) 
282
		{
283
			VisualGestureData data = gestureData[gestureName];
284

    
285
			if (data.userId != 0 && data.lastTimestamp != data.timestamp) 
286
			{
287
				sbBuf.Append(data.userId).Append(delimiter);
288
				sbBuf.AppendFormat("{0:F3}", data.timestamp).Append(delimiter);
289
				sbBuf.Append(data.gestureName).Append(delimiter);
290
				sbBuf.Append(data.isDiscrete ? 1 : 0).Append(delimiter);
291
				sbBuf.Append(data.isContinuous ? 1 : 0).Append(delimiter);
292
				sbBuf.Append(data.isComplete ? 1 : 0).Append(delimiter);
293
				sbBuf.AppendFormat("{0:F3}", data.confidence).Append(delimiter);
294
				sbBuf.AppendFormat("{0:F3}", data.progress).Append(delimiter);
295

    
296
				data.lastTimestamp = data.timestamp;
297

    
298
				gestureData[gestureName] = data;
299
			}
300
			else
301
			{
302
				sbBuf.Append(0).Append(delimiter);
303
			}
304
		}
305

    
306
		// remove the last delimiter
307
		if(sbBuf.Length > 0 && sbBuf[sbBuf.Length - 1] == delimiter)
308
		{
309
			sbBuf.Remove(sbBuf.Length - 1, 1);
310
		}
311

    
312
		return sbBuf.ToString();
313
	}
314

    
315
	// sets gesture data arrays from a csv line
316
	public bool SetGestureDataFromCsv(string sCsvLine, char[] delimiters)
317
	{
318
		if(sCsvLine.Length == 0)
319
			return false;
320

    
321
		// split the csv line in parts
322
		//char[] delimiters = { ',' };
323
		string[] alCsvParts = sCsvLine.Split(delimiters);
324

    
325
		if(alCsvParts.Length < 1 || alCsvParts[0] != "vg")
326
			return false;
327

    
328
		int iIndex = 1;
329
		int iLength = alCsvParts.Length;
330

    
331
		if (iLength < (iIndex + 1))
332
			return false;
333

    
334
		// number of gestures
335
		int gestureCount = 0;
336
		int.TryParse(alCsvParts[iIndex], out gestureCount);
337
		iIndex++;
338

    
339
		if (gestureCount > 0) 
340
		{
341
			for (int i = 0; i < gestureCount && iLength >= (iIndex + 1); i++) 
342
			{
343
				long userId = 0;
344
				long.TryParse(alCsvParts[iIndex], out userId);
345
				iIndex++;
346

    
347
				if (userId != 0 && iLength >= (iIndex + 7)) 
348
				{
349
					int discrete = 0, continuous = 0, complete = 0;
350
					float timestamp = 0f, confidence = 0f, progress = 0f;
351

    
352
					float.TryParse(alCsvParts[iIndex], out timestamp);
353
					string gestureName = alCsvParts[iIndex + 1];
354

    
355
					int.TryParse(alCsvParts[iIndex + 2], out discrete);
356
					int.TryParse(alCsvParts[iIndex + 3], out continuous);
357
					int.TryParse(alCsvParts[iIndex + 4], out complete);
358

    
359
					float.TryParse(alCsvParts[iIndex + 5], out confidence);
360
					float.TryParse(alCsvParts[iIndex + 6], out progress);
361
					iIndex += 7;
362

    
363
					if (!gestureNames.Contains(gestureName)) 
364
					{
365
						gestureNames.Add(gestureName);
366

    
367
						VisualGestureData newData = new VisualGestureData();
368
						newData.gestureName = gestureName;
369
						gestureData[gestureName] = newData;
370
					}
371

    
372
					VisualGestureData data = gestureData[gestureName];
373
					data.userId = userId;
374
					data.timestamp = timestamp;
375

    
376
					data.isDiscrete = (discrete != 0);
377
					data.isContinuous = (continuous != 0);
378
					data.isComplete = (complete != 0);
379

    
380
					data.confidence = confidence;
381
					float prevProgress = data.progress;
382
					data.progress = progress;
383

    
384
					if(data.isDiscrete)
385
					{
386
						if(data.isProcessed && !data.isComplete)
387
						{
388
							//data.isResetting = false;
389
							data.isProcessed = false;
390
						}
391
					}
392
					else if(data.isContinuous)
393
					{
394
						if(data.isProcessed && data.progress >= minConfidence && data.progress != prevProgress)
395
						{
396
							//data.isResetting = false;
397
							data.isProcessed = false;
398
						}
399
					}
400

    
401
					gestureData[gestureName] = data;
402
				}
403
			}
404

    
405
		}
406

    
407
		return true;
408
	}
409

    
410
	//----------------------------------- end of public functions --------------------------------------//
411

    
412
	void Awake()
413
	{
414
		instance = this;
415
	}
416

    
417
#if !(UNITY_WSA_10_0 && NETFX_CORE)
418

    
419
	void Start() 
420
	{
421
		try 
422
		{
423
			// get sensor data
424
			KinectManager kinectManager = KinectManager.Instance;
425
			KinectInterop.SensorData sensorData = kinectManager != null ? kinectManager.GetSensorData() : null;
426

    
427
			if(sensorData == null || sensorData.sensorInterface == null)
428
			{
429
				throw new Exception("Visual gesture tracking cannot be started, because the KinectManager is missing or not initialized.");
430
			}
431

    
432
			if(sensorData.sensorInterface.GetSensorPlatform() != KinectInterop.DepthSensorPlatform.KinectSDKv2)
433
			{
434
				throw new Exception("Visual gesture tracking is only supported by Kinect SDK v2");
435
			}
436

    
437
			// ensure the needed dlls are in place and face tracking is available for this interface
438
			bool bNeedRestart = false;
439
			if(IsVisualGesturesAvailable(ref bNeedRestart))
440
			{
441
				if(bNeedRestart)
442
				{
443
					KinectInterop.RestartLevel(gameObject, "VG");
444
					return;
445
				}
446
			}
447
			else
448
			{
449
				throw new Exception("Visual gesture tracking is not supported!");
450
			}
451

    
452
			// initialize visual gesture tracker
453
			if (!InitVisualGestures())
454
	        {
455
				throw new Exception("Visual gesture tracking could not be initialized.");
456
	        }
457
			
458
			// try to automatically detect the available gesture listeners in the scene
459
			if(visualGestureListeners.Count == 0)
460
			{
461
				MonoBehaviour[] monoScripts = FindObjectsOfType(typeof(MonoBehaviour)) as MonoBehaviour[];
462
				
463
				foreach(MonoBehaviour monoScript in monoScripts)
464
				{
465
//					if(typeof(VisualGestureListenerInterface).IsAssignableFrom(monoScript.GetType()) &&
466
//					   monoScript.enabled)
467
					if((monoScript is VisualGestureListenerInterface) && monoScript.enabled)
468
					{
469
						visualGestureListeners.Add(monoScript);
470
					}
471
				}
472
			}
473

    
474
			isVisualGestureInitialized = true;
475
		} 
476
		catch(DllNotFoundException ex)
477
		{
478
			Debug.LogError(ex.ToString());
479
			if(debugText != null)
480
				debugText.text = "Please check the Kinect and VGB-Library installations.";
481
		}
482
		catch (Exception ex) 
483
		{
484
			Debug.LogError(ex.ToString());
485
			if(debugText != null)
486
				debugText.text = ex.Message;
487
		}
488
	}
489

    
490
	void OnDestroy()
491
	{
492
		if(isVisualGestureInitialized)
493
		{
494
			// finish visual gesture tracking
495
			FinishVisualGestures();
496
		}
497

    
498
		isVisualGestureInitialized = false;
499
		instance = null;
500
	}
501
	
502
	void Update() 
503
	{
504
		if(isVisualGestureInitialized)
505
		{
506
			KinectManager kinectManager = KinectManager.Instance;
507
			if(kinectManager && kinectManager.IsInitialized())
508
			{
509
				primaryUserID = kinectManager.GetUserIdByIndex(playerIndex);
510
			}
511

    
512
			// update visual gesture tracking
513
			if(UpdateVisualGestures(primaryUserID))
514
			{
515
				// process the gestures
516
				foreach(string gestureName in gestureNames)
517
				{
518
					if(gestureData.ContainsKey(gestureName))
519
					{
520
						VisualGestureData data = gestureData[gestureName];
521

    
522
						if(data.userId != 0 && !data.isProcessed && data.isComplete && data.confidence >= minConfidence)
523
						{
524
							//Debug.Log(gestureName + "-gesture detected.");
525
							int userIndex = kinectManager ? kinectManager.GetUserIndexById(data.userId) : -1;
526

    
527
							foreach(VisualGestureListenerInterface listener in visualGestureListeners)
528
							{
529
								if(listener.GestureCompleted(data.userId, userIndex, data.gestureName, data.confidence))
530
								{
531
									//data.isResetting = true;
532
									data.isProcessed = true;
533
									gestureData[gestureName] = data;
534
								}
535
							}
536
						}
537
						else if(data.userId != 0 && !data.isProcessed && data.progress >= minConfidence)
538
						{
539
							//Debug.Log(gestureName + "-gesture progres: " + data.progress);
540
							int userIndex = kinectManager ? kinectManager.GetUserIndexById(data.userId) : -1;
541

    
542
							foreach(VisualGestureListenerInterface listener in visualGestureListeners)
543
							{
544
								listener.GestureInProgress(data.userId, userIndex, data.gestureName, data.progress);
545

    
546
								//data.isResetting = true;
547
								data.isProcessed = true;
548
								gestureData[gestureName] = data;
549
							}
550
						}
551
					}
552
				}
553

    
554
			}
555

    
556
		}
557
	}
558
	
559
	private bool IsVisualGesturesAvailable(ref bool bNeedRestart)
560
	{
561
		bool bOneCopied = false, bAllCopied = true;
562
		string sTargetPath = ".";
563
		
564
		if(!KinectInterop.Is64bitArchitecture())
565
		{
566
			// 32 bit
567
			sTargetPath = KinectInterop.GetTargetDllPath(".", false) + "/";
568
			
569
			Dictionary<string, string> dictFilesToUnzip = new Dictionary<string, string>();
570
			dictFilesToUnzip["Kinect20.VisualGestureBuilder.dll"] = sTargetPath + "Kinect20.VisualGestureBuilder.dll";
571
			dictFilesToUnzip["KinectVisualGestureBuilderUnityAddin.dll"] = sTargetPath + "KinectVisualGestureBuilderUnityAddin.dll";
572
			dictFilesToUnzip["vgbtechs/AdaBoostTech.dll"] = sTargetPath + "vgbtechs/AdaBoostTech.dll";
573
			dictFilesToUnzip["vgbtechs/RFRProgressTech.dll"] = sTargetPath + "vgbtechs/RFRProgressTech.dll";
574
			dictFilesToUnzip["msvcp110.dll"] = sTargetPath + "msvcp110.dll";
575
			dictFilesToUnzip["msvcr110.dll"] = sTargetPath + "msvcr110.dll";
576
			
577
			KinectInterop.UnzipResourceFiles(dictFilesToUnzip, "KinectV2UnityAddin.x86.zip", ref bOneCopied, ref bAllCopied);
578
		}
579
		else
580
		{
581
			//Debug.Log("Face - x64-architecture.");
582
			sTargetPath = KinectInterop.GetTargetDllPath(".", true) + "/";
583
			
584
			Dictionary<string, string> dictFilesToUnzip = new Dictionary<string, string>();
585
			dictFilesToUnzip["Kinect20.VisualGestureBuilder.dll"] = sTargetPath + "Kinect20.VisualGestureBuilder.dll";
586
			dictFilesToUnzip["KinectVisualGestureBuilderUnityAddin.dll"] = sTargetPath + "KinectVisualGestureBuilderUnityAddin.dll";
587
			dictFilesToUnzip["vgbtechs/AdaBoostTech.dll"] = sTargetPath + "vgbtechs/AdaBoostTech.dll";
588
			dictFilesToUnzip["vgbtechs/RFRProgressTech.dll"] = sTargetPath + "vgbtechs/RFRProgressTech.dll";
589
			dictFilesToUnzip["msvcp110.dll"] = sTargetPath + "msvcp110.dll";
590
			dictFilesToUnzip["msvcr110.dll"] = sTargetPath + "msvcr110.dll";
591
			
592
			KinectInterop.UnzipResourceFiles(dictFilesToUnzip, "KinectV2UnityAddin.x64.zip", ref bOneCopied, ref bAllCopied);
593
		}
594

    
595
		bNeedRestart = (bOneCopied && bAllCopied);
596
		
597
		return true;
598
	}
599
	
600
	private bool InitVisualGestures()
601
	{
602
		KinectManager kinectManager = KinectManager.Instance;
603
		KinectInterop.SensorData sensorData = kinectManager != null ? kinectManager.GetSensorData() : null;
604

    
605
		Kinect2Interface kinectInterface = sensorData.sensorInterface as Kinect2Interface;
606
		KinectSensor kinectSensor = kinectInterface != null ? kinectInterface.kinectSensor : null;
607

    
608
		if(kinectSensor == null)
609
			return false;
610

    
611
		if(gestureDatabase == string.Empty)
612
		{
613
			Debug.LogError("Please specify gesture database file!");
614
			return false;
615
		}
616

    
617
		// copy the gesture database file from Resources, if available
618
		if(!File.Exists(gestureDatabase))
619
		{
620
			TextAsset textRes = Resources.Load(gestureDatabase, typeof(TextAsset)) as TextAsset;
621
			
622
			if(textRes != null && textRes.bytes.Length != 0)
623
			{
624
				File.WriteAllBytes(gestureDatabase, textRes.bytes);
625
			}
626
		}
627
		
628
		// create the vgb source
629
		vgbFrameSource = VisualGestureBuilderFrameSource.Create(kinectSensor, 0);
630

    
631
		// open the reader
632
		vgbFrameReader = vgbFrameSource != null ? vgbFrameSource.OpenReader() : null;
633
		if(vgbFrameReader != null)
634
		{
635
			vgbFrameReader.IsPaused = true;
636
		}
637
		
638
		using (VisualGestureBuilderDatabase database = VisualGestureBuilderDatabase.Create(gestureDatabase))
639
		{
640
			if(database == null)
641
			{
642
				Debug.LogError("Gesture database not found: " + gestureDatabase);
643
				return false;
644
			}
645

    
646
			// check if we need to load all gestures
647
			bool bAllGestures = (gestureNames.Count == 0);
648

    
649
			foreach (Gesture gesture in database.AvailableGestures)
650
			{
651
				bool bAddGesture = bAllGestures || gestureNames.Contains(gesture.Name);
652

    
653
				if(bAddGesture)
654
				{
655
					string sGestureName = gesture.Name;
656
					vgbFrameSource.AddGesture(gesture);
657

    
658
					if(!gestureNames.Contains(sGestureName))
659
					{
660
						gestureNames.Add(sGestureName);
661
					}
662

    
663
					if(!gestureData.ContainsKey(sGestureName))
664
					{
665
						VisualGestureData data = new VisualGestureData();
666
						data.gestureName = sGestureName;
667
						data.timestamp = Time.realtimeSinceStartup;
668

    
669
						data.isDiscrete = (gesture.GestureType == GestureType.Discrete);
670
						data.isContinuous = (gesture.GestureType == GestureType.Continuous);
671

    
672
						gestureData.Add(sGestureName, data);
673
					}
674
				}
675
			}
676
		}
677

    
678
		return true;
679
	}
680
	
681
	private void FinishVisualGestures()
682
	{
683
		if (vgbFrameReader != null)
684
		{
685
			vgbFrameReader.Dispose();
686
			vgbFrameReader = null;
687
		}
688
		
689
		if (vgbFrameSource != null)
690
		{
691
			vgbFrameSource.Dispose();
692
			vgbFrameSource = null;
693
		}
694

    
695
		if(gestureData != null)
696
		{
697
			gestureData.Clear();
698
		}
699
	}
700
	
701
	private bool UpdateVisualGestures(long userId)
702
	{
703
		if(vgbFrameSource == null || vgbFrameReader == null)
704
			return false;
705

    
706
		bool wasPaused = vgbFrameReader.IsPaused;
707
		vgbFrameSource.TrackingId = (ulong)userId;
708
		vgbFrameReader.IsPaused = (userId == 0);
709

    
710
		if(vgbFrameReader.IsPaused)
711
		{
712
			if(!wasPaused)
713
			{
714
				// clear the gesture states
715
				foreach (Gesture gesture in vgbFrameSource.Gestures)
716
				{
717
					if(gestureData.ContainsKey(gesture.Name))
718
					{
719
						VisualGestureData data = gestureData[gesture.Name];
720

    
721
						data.userId = 0;
722
						data.isComplete = false;
723
						//data.isResetting = false;
724
						data.isProcessed = false;
725
						data.confidence = 0f;
726
						data.progress = 0f;
727
						data.timestamp = Time.realtimeSinceStartup;
728
						
729
						gestureData[gesture.Name] = data;
730
					}
731
				}
732
			}
733

    
734
			return false;
735
		}
736

    
737
		VisualGestureBuilderFrame frame = vgbFrameReader.CalculateAndAcquireLatestFrame();
738

    
739
		if(frame != null)
740
		{
741
			Dictionary<Gesture, DiscreteGestureResult> discreteResults = frame.DiscreteGestureResults;
742
			Dictionary<Gesture, ContinuousGestureResult> continuousResults = frame.ContinuousGestureResults;
743

    
744
			if (discreteResults != null)
745
			{
746
				foreach (Gesture gesture in discreteResults.Keys)
747
				{
748
					if(gesture.GestureType == GestureType.Discrete && gestureData.ContainsKey(gesture.Name))
749
					{
750
						DiscreteGestureResult result = discreteResults[gesture];
751
						VisualGestureData data = gestureData[gesture.Name];
752

    
753
						data.userId = vgbFrameSource.IsTrackingIdValid ? (long)vgbFrameSource.TrackingId : 0;
754
						data.isComplete = result.Detected;
755
						data.confidence = result.Confidence;
756
						data.timestamp = Time.realtimeSinceStartup;
757

    
758
						//Debug.Log(string.Format ("{0} - {1}, confidence: {2:F0}%", data.gestureName, data.isComplete ? "Yes" : "No", data.confidence * 100f));
759

    
760
						if(data.isProcessed && !data.isComplete)
761
						{
762
							//data.isResetting = false;
763
							data.isProcessed = false;
764
						}
765

    
766
						gestureData[gesture.Name] = data;
767
					}
768
				}
769
			}
770

    
771
			if (continuousResults != null)
772
			{
773
				foreach (Gesture gesture in continuousResults.Keys)
774
				{
775
					if(gesture.GestureType == GestureType.Continuous && gestureData.ContainsKey(gesture.Name))
776
					{
777
						ContinuousGestureResult result = continuousResults[gesture];
778
						VisualGestureData data = gestureData[gesture.Name];
779

    
780
						data.userId = vgbFrameSource.IsTrackingIdValid ? (long)vgbFrameSource.TrackingId : 0;
781
						float prevProgress = data.progress;
782
						data.progress = result.Progress;
783
						data.timestamp = Time.realtimeSinceStartup;
784

    
785
						if(data.isProcessed && data.progress >= minConfidence && data.progress != prevProgress)
786
						{
787
							//data.isResetting = false;
788
							data.isProcessed = false;
789
						}
790

    
791
						gestureData[gesture.Name] = data;
792
					}
793
				}
794
			}
795
			
796
			frame.Dispose();
797
			frame = null;
798
		}
799

    
800
		return true;
801
	}
802
	
803
	#endif
804
}