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 |
} |