t1 / TFDContents / Assets / KinectScripts / Interfaces / OpenNI2Interface.cs @ 3
이력 | 보기 | 이력해설 | 다운로드 (32.1 KB)
1 |
using UnityEngine; |
---|---|
2 |
using System.Collections; |
3 |
using System.Collections.Generic; |
4 |
using System.Runtime.InteropServices; |
5 |
using System; |
6 |
using System.IO; |
7 |
|
8 |
|
9 |
public class OpenNI2Interface : DepthSensorInterface |
10 |
{ |
11 |
|
12 |
private static class Constants |
13 |
{ |
14 |
public const int SkeletonCount = 6; |
15 |
public const int JointCount = 20; |
16 |
public const float SmoothingFactor = 0.7f; |
17 |
|
18 |
|
19 |
public static readonly int[] BodyJoint2OniJoint = { |
20 |
(int)SkeletonJoint.HIPS, //SpineBase |
21 |
-1, //SpineMid |
22 |
(int)SkeletonJoint.NECK, //Neck |
23 |
(int)SkeletonJoint.HEAD, //Head |
24 |
(int)SkeletonJoint.LEFT_SHOULDER, //ShoulderLeft |
25 |
(int)SkeletonJoint.LEFT_ELBOW, //ElbowLeft |
26 |
-1, //WristLeft |
27 |
(int)SkeletonJoint.LEFT_HAND, //HandLeft |
28 |
(int)SkeletonJoint.RIGHT_SHOULDER, //ShoulderRight |
29 |
(int)SkeletonJoint.RIGHT_ELBOW, //ElbowRight |
30 |
-1, //WristRight |
31 |
(int)SkeletonJoint.RIGHT_HAND, //HandRight |
32 |
(int)SkeletonJoint.LEFT_HIP, //HipLeft |
33 |
(int)SkeletonJoint.LEFT_KNEE, //KneeLeft |
34 |
(int)SkeletonJoint.LEFT_FOOT, //AnkleLeft |
35 |
-1, //FootLeft |
36 |
(int)SkeletonJoint.RIGHT_HIP, //HipRight |
37 |
(int)SkeletonJoint.RIGHT_KNEE, //KneeRight |
38 |
(int)SkeletonJoint.RIGHT_FOOT, //AnkleRight |
39 |
-1 //FootRight |
40 |
}; |
41 |
} |
42 |
|
43 |
public enum SkeletonJoint |
44 |
{ |
45 |
HEAD = 0, |
46 |
NECK = 1, |
47 |
|
48 |
LEFT_SHOULDER = 2, |
49 |
RIGHT_SHOULDER = 3, |
50 |
LEFT_ELBOW = 4, |
51 |
RIGHT_ELBOW = 5, |
52 |
LEFT_HAND = 6, |
53 |
RIGHT_HAND = 7, |
54 |
|
55 |
HIPS = 8, |
56 |
|
57 |
LEFT_HIP = 9, |
58 |
RIGHT_HIP = 10, |
59 |
LEFT_KNEE = 11, |
60 |
RIGHT_KNEE = 12, |
61 |
LEFT_FOOT = 13, |
62 |
RIGHT_FOOT = 14 |
63 |
}; |
64 |
|
65 |
// Struct to store the joint's poision. |
66 |
public struct SkeletonJointPosition |
67 |
{ |
68 |
public float x, y, z; |
69 |
} |
70 |
|
71 |
// Struct that will hold the joints orientation. |
72 |
public struct SkeletonJointOrientation |
73 |
{ |
74 |
public float x, y, z, w; |
75 |
} |
76 |
|
77 |
// Struct that combines the previous two and makes the transform. |
78 |
public struct SkeletonJointTransformation |
79 |
{ |
80 |
public SkeletonJoint jointType; |
81 |
public SkeletonJointPosition position; |
82 |
public float positionConfidence; |
83 |
public SkeletonJointOrientation orientation; |
84 |
public float orientationConfidence; |
85 |
} |
86 |
|
87 |
private short[] oniUsers = new short[Constants.SkeletonCount]; |
88 |
private short[] oniStates = new short[Constants.SkeletonCount]; |
89 |
private Int32 oniUsersCount = 0; |
90 |
|
91 |
private List<uint> allUsers = new List<uint>(); |
92 |
private SkeletonJointPosition jointPosition = new SkeletonJointPosition(); |
93 |
|
94 |
private int usersMapSize = 0; |
95 |
private short[] usersLabelMap; |
96 |
private short[] usersDepthMap; |
97 |
|
98 |
private int usersClrSize = 0; |
99 |
private byte[] usersColorMap; |
100 |
|
101 |
private bool bBackgroundRemovalInited = false; |
102 |
|
103 |
[DllImport("UnityInterface2")] |
104 |
private static extern int GetDeviceCount(out int pCount); |
105 |
[DllImport("UnityInterface2", EntryPoint = "Init", SetLastError = true)] |
106 |
private static extern int InitNative(bool isInitDepthStream, bool isInitColorStream, bool isInitInfraredStream); |
107 |
[DllImport("UnityInterface2", EntryPoint = "Shutdown", SetLastError = true)] |
108 |
private static extern void ShutdownNative(); |
109 |
[DllImport("UnityInterface2", EntryPoint = "Update", SetLastError = true)] |
110 |
private static extern int UpdateNative([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = Constants.SkeletonCount, ArraySubType = UnmanagedType.U2)] short[] pUsers, |
111 |
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = Constants.SkeletonCount, ArraySubType = UnmanagedType.U2)] short[] pStates, ref int pUsersCount); |
112 |
|
113 |
[DllImport("UnityInterface2")] |
114 |
private static extern IntPtr GetLastErrorString(); |
115 |
[DllImport("UnityInterface2", SetLastError = true)] |
116 |
private static extern int GetDepthWidth(); |
117 |
[DllImport("UnityInterface2", SetLastError = true)] |
118 |
private static extern int GetDepthHeight(); |
119 |
[DllImport("UnityInterface2", SetLastError = true)] |
120 |
private static extern int GetInfraredWidth(); |
121 |
[DllImport("UnityInterface2", SetLastError = true)] |
122 |
private static extern int GetInfraredHeight(); |
123 |
[DllImport("UnityInterface2", SetLastError = true)] |
124 |
private static extern int GetColorWidth(); |
125 |
[DllImport("UnityInterface2", SetLastError = true)] |
126 |
private static extern int GetColorHeight(); |
127 |
[DllImport("UnityInterface2", SetLastError = true)] |
128 |
private static extern IntPtr GetUsersLabelMap(); |
129 |
[DllImport("UnityInterface2", SetLastError = true)] |
130 |
private static extern IntPtr GetUsersDepthMap(); |
131 |
[DllImport("UnityInterface2", SetLastError = true)] |
132 |
private static extern IntPtr GetUsersInfraredMap(); |
133 |
[DllImport("UnityInterface2", SetLastError = true)] |
134 |
private static extern IntPtr GetUsersColorMap(); |
135 |
|
136 |
[DllImport("UnityInterface2", SetLastError = true)] |
137 |
private static extern bool ConvertDepthToColor(int depthX, int depthY, ushort depthZ, out int pColorX, out int pColorY); |
138 |
|
139 |
[DllImport("UnityInterface2", SetLastError = true)] |
140 |
private static extern bool ConvertDepthToWorld(float depthX, float depthY, float depthZ, out float pWorldX, out float pWorldY, out float pWorldZ); |
141 |
|
142 |
[DllImport("UnityInterface2", SetLastError = true)] |
143 |
private static extern bool ConvertWorldToDepth(float worldX, float worldY, float worldZ, out int pDepthX, out int pDepthY, out ushort pDepthZ); |
144 |
|
145 |
[DllImport("UnityInterface2", SetLastError = true)] |
146 |
private static extern void SetSkeletonSmoothing(float factor); |
147 |
|
148 |
[DllImport("UnityInterface2", SetLastError = true)] |
149 |
private static extern bool GetJointPosition(uint userID, int joint, ref SkeletonJointPosition pTransformation); |
150 |
// [DllImport("UnityInterface2", SetLastError = true)] |
151 |
// private static extern bool GetJointOrientation(uint userID, int joint, ref SkeletonJointOrientation pTransformation); |
152 |
[DllImport("UnityInterface2", SetLastError = true)] |
153 |
private static extern float GetJointPositionConfidence(uint userID, int joint); |
154 |
// [DllImport("UnityInterface2", SetLastError = true)] |
155 |
// private static extern float GetJointOrientationConfidence(uint userID, int joint); |
156 |
|
157 |
[DllImport("UnityInterface2", SetLastError = true)] |
158 |
private static extern void StartLookingForUsers(IntPtr NewUser, IntPtr CalibrationStarted, IntPtr CalibrationFailed, IntPtr CalibrationSuccess, IntPtr UserLost); |
159 |
[DllImport("UnityInterface2", SetLastError = true)] |
160 |
private static extern void StopLookingForUsers(); |
161 |
|
162 |
public delegate void UserDelegate(uint userId); |
163 |
|
164 |
private static void StartLookingForUsers(UserDelegate NewUser, UserDelegate CalibrationStarted, UserDelegate CalibrationFailed, UserDelegate CalibrationSuccess, UserDelegate UserLost) |
165 |
{ |
166 |
StartLookingForUsers( |
167 |
Marshal.GetFunctionPointerForDelegate(NewUser), |
168 |
Marshal.GetFunctionPointerForDelegate(CalibrationStarted), |
169 |
Marshal.GetFunctionPointerForDelegate(CalibrationFailed), |
170 |
Marshal.GetFunctionPointerForDelegate(CalibrationSuccess), |
171 |
Marshal.GetFunctionPointerForDelegate(UserLost)); |
172 |
} |
173 |
|
174 |
|
175 |
public KinectInterop.DepthSensorPlatform GetSensorPlatform () |
176 |
{ |
177 |
return KinectInterop.DepthSensorPlatform.OpenNIv2; |
178 |
} |
179 |
|
180 |
public bool InitSensorInterface (bool bCopyLibs, ref bool bNeedRestart) |
181 |
{ |
182 |
bool bOneCopied = false, bAllCopied = true; |
183 |
bool bArchX64 = KinectInterop.Is64bitArchitecture(); |
184 |
|
185 |
string sTargetPath = KinectInterop.GetTargetDllPath(".", bArchX64) + "/"; |
186 |
//string sTargetPath = "./"; |
187 |
|
188 |
if(!bCopyLibs) |
189 |
{ |
190 |
// check if the native library is there |
191 |
string sTargetLib = sTargetPath + "UnityInterface2.dll"; |
192 |
bNeedRestart = false; |
193 |
|
194 |
string sZipFileName = !bArchX64 ? "OpenNI2UnityInterface.x86.zip" : "OpenNI2UnityInterface.x64.zip"; |
195 |
long iTargetSize = KinectInterop.GetUnzippedEntrySize(sZipFileName, "UnityInterface2.dll"); |
196 |
|
197 |
// FileInfo targetFile = new FileInfo(sTargetLib); |
198 |
// return targetFile.Exists && targetFile.Length == iTargetSize; |
199 |
return KinectInterop.IsFileExists(sTargetLib, iTargetSize); |
200 |
} |
201 |
|
202 |
// check openni directory and resources |
203 |
string sOpenNIPath = KinectInterop.GetEnvironmentVariable(!bArchX64 ? "OPENNI2_REDIST" : "OPENNI2_REDIST64"); |
204 |
if(sOpenNIPath == String.Empty || !Directory.Exists(sOpenNIPath)) |
205 |
{ |
206 |
Debug.LogWarning("OpenNI2-folder not found (check OPENNI2_REDIST)."); |
207 |
return false; |
208 |
} |
209 |
|
210 |
sOpenNIPath = sOpenNIPath.Replace('\\', '/'); |
211 |
if(sOpenNIPath.EndsWith("/")) |
212 |
{ |
213 |
sOpenNIPath = sOpenNIPath.Substring(0, sOpenNIPath.Length - 1); |
214 |
} |
215 |
|
216 |
// check nite directory and resources |
217 |
string sNiTEPath = KinectInterop.GetEnvironmentVariable(!bArchX64 ? "NITE2_REDIST" : "NITE2_REDIST64"); |
218 |
if(sNiTEPath == String.Empty || !Directory.Exists(sNiTEPath)) |
219 |
{ |
220 |
Debug.LogWarning("NiTE2-folder not found (check NITE2_REDIST)."); |
221 |
return false; |
222 |
} |
223 |
|
224 |
sNiTEPath = sNiTEPath.Replace('\\', '/'); |
225 |
if(sNiTEPath.EndsWith("/")) |
226 |
{ |
227 |
sNiTEPath = sNiTEPath.Substring(0, sNiTEPath.Length - 1); |
228 |
} |
229 |
|
230 |
string sUnityInterfaceLib = "UnityInterface2.dll"; |
231 |
string sOpenNI2Lib = "OpenNI2.dll"; |
232 |
string sNiTE22Lib = "NiTE2.dll"; |
233 |
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX |
234 |
sUnityInterfaceLib = "UnityInterface2.dll"; |
235 |
sOpenNI2Lib = "libOpenNI2.dylib"; |
236 |
sNiTE22Lib = "libNiTE2.dylib"; |
237 |
#endif |
238 |
|
239 |
KinectInterop.CopyFile(sOpenNIPath + "/" + sOpenNI2Lib, sTargetPath + sOpenNI2Lib, ref bOneCopied, ref bAllCopied); |
240 |
KinectInterop.CopyFile(sNiTEPath + "/" + sNiTE22Lib, sTargetPath + sNiTE22Lib, ref bOneCopied, ref bAllCopied); |
241 |
|
242 |
if(!bArchX64) |
243 |
{ |
244 |
Dictionary<string, string> dictFilesToUnzip = new Dictionary<string, string>(); |
245 |
|
246 |
dictFilesToUnzip[sUnityInterfaceLib] = sTargetPath + sUnityInterfaceLib; |
247 |
//dictFilesToUnzip["OpenNI2.dll"] = sTargetPath + "OpenNI2.dll"; |
248 |
//dictFilesToUnzip["NiTE2.dll"] = sTargetPath + "NiTE2.dll"; |
249 |
dictFilesToUnzip["OpenNI.ini"] = sTargetPath + "OpenNI.ini"; |
250 |
dictFilesToUnzip["NiTE.ini"] = sTargetPath + "NiTE.ini"; |
251 |
|
252 |
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN |
253 |
dictFilesToUnzip["msvcp100.dll"] = sTargetPath + "msvcp100.dll"; |
254 |
dictFilesToUnzip["msvcr100.dll"] = sTargetPath + "msvcr100.dll"; |
255 |
#endif |
256 |
|
257 |
KinectInterop.UnzipResourceFiles(dictFilesToUnzip, "OpenNI2UnityInterface.x86.zip", ref bOneCopied, ref bAllCopied); |
258 |
} |
259 |
else |
260 |
{ |
261 |
Dictionary<string, string> dictFilesToUnzip = new Dictionary<string, string>(); |
262 |
|
263 |
dictFilesToUnzip[sUnityInterfaceLib] = sTargetPath + sUnityInterfaceLib; |
264 |
//dictFilesToUnzip["OpenNI2.dll"] = sTargetPath + "OpenNI2.dll"; |
265 |
//dictFilesToUnzip["NiTE2.dll"] = sTargetPath + "NiTE2.dll"; |
266 |
dictFilesToUnzip["OpenNI.ini"] = sTargetPath + "OpenNI.ini"; |
267 |
dictFilesToUnzip["NiTE.ini"] = sTargetPath + "NiTE.ini"; |
268 |
|
269 |
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN |
270 |
dictFilesToUnzip["msvcp100.dll"] = sTargetPath + "msvcp100.dll"; |
271 |
dictFilesToUnzip["msvcr100.dll"] = sTargetPath + "msvcr100.dll"; |
272 |
#endif |
273 |
|
274 |
KinectInterop.UnzipResourceFiles(dictFilesToUnzip, "OpenNI2UnityInterface.x64.zip", ref bOneCopied, ref bAllCopied); |
275 |
} |
276 |
|
277 |
if(File.Exists(sTargetPath + "OpenNI.ini")) |
278 |
{ |
279 |
string sFileContent = File.ReadAllText(sTargetPath + "OpenNI.ini"); |
280 |
sFileContent = sFileContent.Replace("%OPENNI_REDIST_DIR%", sOpenNIPath); |
281 |
File.WriteAllText(sTargetPath + "OpenNI.ini", sFileContent); |
282 |
} |
283 |
|
284 |
if(File.Exists(sTargetPath + "NiTE.ini")) |
285 |
{ |
286 |
string sFileContent = File.ReadAllText(sTargetPath + "NiTE.ini"); |
287 |
sFileContent = sFileContent.Replace("%NITE_REDIST_DIR%", sNiTEPath); |
288 |
File.WriteAllText(sTargetPath + "NiTE.ini", sFileContent); |
289 |
} |
290 |
|
291 |
bNeedRestart = (bOneCopied && bAllCopied); |
292 |
|
293 |
return true; |
294 |
} |
295 |
|
296 |
public void FreeSensorInterface (bool bDeleteLibs) |
297 |
{ |
298 |
if(bDeleteLibs) |
299 |
{ |
300 |
KinectInterop.DeleteNativeLib("UnityInterface2.dll", true); |
301 |
KinectInterop.DeleteNativeLib("OpenNI2.dll", false); |
302 |
KinectInterop.DeleteNativeLib("NiTE2.dll", false); |
303 |
KinectInterop.DeleteNativeLib("OpenNI.ini", false); |
304 |
KinectInterop.DeleteNativeLib("NiTE.ini", false); |
305 |
KinectInterop.DeleteNativeLib("msvcp100.dll", false); |
306 |
KinectInterop.DeleteNativeLib("msvcr100.dll", false); |
307 |
} |
308 |
} |
309 |
|
310 |
public bool IsSensorAvailable () |
311 |
{ |
312 |
bool bAvailable = GetSensorsCount() > 0; |
313 |
return bAvailable; |
314 |
} |
315 |
|
316 |
public int GetSensorsCount () |
317 |
{ |
318 |
int iSensorCount = 0; |
319 |
int hr = GetDeviceCount(out iSensorCount); |
320 |
|
321 |
return (hr == 0 ? iSensorCount : 0); |
322 |
} |
323 |
|
324 |
public KinectInterop.SensorData OpenDefaultSensor (KinectInterop.FrameSource dwFlags, float sensorAngle, bool bUseMultiSource) |
325 |
{ |
326 |
bool bColor = false, bDepth = false, bInfrared = false; |
327 |
|
328 |
if((dwFlags & KinectInterop.FrameSource.TypeColor) != 0) |
329 |
{ |
330 |
bColor = true; |
331 |
} |
332 |
|
333 |
if((dwFlags & KinectInterop.FrameSource.TypeDepth) != 0) |
334 |
{ |
335 |
bDepth = true; |
336 |
} |
337 |
|
338 |
if((dwFlags & KinectInterop.FrameSource.TypeBodyIndex) != 0) |
339 |
{ |
340 |
bDepth = true; |
341 |
} |
342 |
|
343 |
if((dwFlags & KinectInterop.FrameSource.TypeInfrared) != 0) |
344 |
{ |
345 |
bInfrared = true; |
346 |
} |
347 |
|
348 |
int hr = InitNative(bDepth, bColor, bInfrared); |
349 |
|
350 |
if(hr == 0) |
351 |
{ |
352 |
KinectInterop.SensorData sensorData = new KinectInterop.SensorData(); |
353 |
|
354 |
sensorData.bodyCount = Constants.SkeletonCount; |
355 |
sensorData.jointCount = Constants.JointCount; |
356 |
|
357 |
sensorData.depthCameraFOV = 46.6f; |
358 |
sensorData.colorCameraFOV = 48.6f; |
359 |
sensorData.depthCameraOffset = 0.01f; |
360 |
sensorData.faceOverlayOffset = 0.01f; |
361 |
|
362 |
sensorData.colorImageWidth = GetColorWidth(); |
363 |
sensorData.colorImageHeight = GetColorHeight(); |
364 |
|
365 |
sensorData.depthImageWidth = GetDepthWidth(); |
366 |
sensorData.depthImageHeight = GetDepthHeight(); |
367 |
|
368 |
usersClrSize = sensorData.colorImageWidth * sensorData.colorImageHeight; |
369 |
usersColorMap = new byte[usersClrSize * 3]; |
370 |
|
371 |
usersMapSize = sensorData.depthImageWidth * sensorData.depthImageHeight; |
372 |
usersLabelMap = new short[usersMapSize]; |
373 |
usersDepthMap = new short[usersMapSize]; |
374 |
|
375 |
if((dwFlags & KinectInterop.FrameSource.TypeColor) != 0) |
376 |
{ |
377 |
sensorData.colorImage = new byte[sensorData.colorImageWidth * sensorData.colorImageHeight * 4]; |
378 |
} |
379 |
|
380 |
if((dwFlags & KinectInterop.FrameSource.TypeDepth) != 0) |
381 |
{ |
382 |
sensorData.depthImage = new ushort[sensorData.depthImageWidth * sensorData.depthImageHeight]; |
383 |
} |
384 |
|
385 |
if((dwFlags & KinectInterop.FrameSource.TypeBodyIndex) != 0) |
386 |
{ |
387 |
sensorData.bodyIndexImage = new byte[sensorData.depthImageWidth * sensorData.depthImageHeight]; |
388 |
} |
389 |
|
390 |
if((dwFlags & KinectInterop.FrameSource.TypeInfrared) != 0) |
391 |
{ |
392 |
sensorData.infraredImage = new ushort[sensorData.colorImageWidth * sensorData.colorImageHeight]; |
393 |
} |
394 |
|
395 |
if((dwFlags & KinectInterop.FrameSource.TypeBody) != 0) |
396 |
{ |
397 |
StartLookingForUsers(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); |
398 |
SetSkeletonSmoothing(Constants.SmoothingFactor); |
399 |
} |
400 |
|
401 |
return sensorData; |
402 |
} |
403 |
else |
404 |
{ |
405 |
Debug.LogError("InitKinectSensor failed: " + Marshal.PtrToStringAnsi(GetLastErrorString())); |
406 |
} |
407 |
|
408 |
return null; |
409 |
} |
410 |
|
411 |
public void CloseSensor (KinectInterop.SensorData sensorData) |
412 |
{ |
413 |
StopLookingForUsers(); |
414 |
ShutdownNative(); |
415 |
} |
416 |
|
417 |
public bool UpdateSensorData (KinectInterop.SensorData sensorData) |
418 |
{ |
419 |
// Update to the next frame. |
420 |
oniUsersCount = oniUsers.Length; |
421 |
UpdateNative(oniUsers, oniStates, ref oniUsersCount); |
422 |
|
423 |
return true; |
424 |
} |
425 |
|
426 |
public bool GetMultiSourceFrame (KinectInterop.SensorData sensorData) |
427 |
{ |
428 |
return false; |
429 |
} |
430 |
|
431 |
public void FreeMultiSourceFrame (KinectInterop.SensorData sensorData) |
432 |
{ |
433 |
} |
434 |
|
435 |
public bool PollBodyFrame (KinectInterop.SensorData sensorData, ref KinectInterop.BodyFrameData bodyFrame, |
436 |
ref Matrix4x4 kinectToWorld, bool bIgnoreJointZ) |
437 |
{ |
438 |
for(int i = 0; i < oniUsersCount; i++) |
439 |
{ |
440 |
uint userId = (uint)oniUsers[i]; |
441 |
short userState = oniStates[i]; |
442 |
|
443 |
switch(userState) |
444 |
{ |
445 |
case 1: // new user |
446 |
Debug.Log(String.Format("New user: {0}", userId)); |
447 |
break; |
448 |
|
449 |
case 2: // calibration started |
450 |
//Debug.Log(String.Format("Calibration started for user: {0}", userId)); |
451 |
break; |
452 |
|
453 |
case 3: // calibration succeeded |
454 |
Debug.Log(String.Format("Calibration succeeded for user: {0}", userId)); |
455 |
|
456 |
if(!allUsers.Contains(userId)) |
457 |
{ |
458 |
allUsers.Add(userId); |
459 |
} |
460 |
break; |
461 |
|
462 |
case 4: // calibration failed |
463 |
Debug.Log(String.Format("Calibration failed for user: {0}", userId)); |
464 |
break; |
465 |
|
466 |
case 5: // user lost |
467 |
Debug.Log(String.Format("User lost: {0}", userId)); |
468 |
|
469 |
if(allUsers.Contains(userId)) |
470 |
{ |
471 |
allUsers.Remove(userId); |
472 |
} |
473 |
break; |
474 |
} |
475 |
} |
476 |
|
477 |
bool newSkeleton = (allUsers.Count > 0); |
478 |
|
479 |
if(newSkeleton) |
480 |
{ |
481 |
bodyFrame.liPreviousTime = bodyFrame.liRelativeTime; |
482 |
bodyFrame.liRelativeTime = DateTime.Now.Ticks; |
483 |
} |
484 |
|
485 |
// set initially all the skeletons as not tracked |
486 |
for(int i = 0; i < sensorData.bodyCount; i++) |
487 |
{ |
488 |
bodyFrame.bodyData[i].liTrackingID = 0; |
489 |
bodyFrame.bodyData[i].bIsTracked = 0; |
490 |
} |
491 |
|
492 |
// fill in joint info for the tracked skeletons |
493 |
for(int i = 0; i < allUsers.Count; i++) |
494 |
{ |
495 |
uint userId = allUsers[i]; |
496 |
int userIndex = (int)userId % 6; |
497 |
|
498 |
bodyFrame.bodyData[userIndex].liTrackingID = (long)userId; |
499 |
bodyFrame.bodyData[userIndex].bIsTracked = 1; |
500 |
|
501 |
for(int j = 0; j < sensorData.jointCount; j++) |
502 |
{ |
503 |
KinectInterop.JointData jointData = bodyFrame.bodyData[userIndex].joint[j]; |
504 |
int oniJ = Constants.BodyJoint2OniJoint[j]; |
505 |
|
506 |
if(oniJ >= 0) |
507 |
{ |
508 |
//jointData.jointType = GetJointAtIndex(j); |
509 |
|
510 |
float fConfidence = GetJointPositionConfidence(userId, oniJ); |
511 |
jointData.trackingState = (fConfidence > 0.7f ? KinectInterop.TrackingState.Tracked : |
512 |
(fConfidence > 0.3f ? KinectInterop.TrackingState.Inferred : KinectInterop.TrackingState.NotTracked)); |
513 |
|
514 |
if(jointData.trackingState != KinectInterop.TrackingState.NotTracked) |
515 |
{ |
516 |
if(GetJointPosition(userId, oniJ, ref jointPosition)) |
517 |
{ |
518 |
float jPosZ = (bIgnoreJointZ && j > 0) ? bodyFrame.bodyData[i].joint[0].kinectPos.z : jointPosition.z * 0.001f; |
519 |
jointData.kinectPos = new Vector3(jointPosition.x * 0.001f, jointPosition.y * 0.001f, jointPosition.z * 0.001f); |
520 |
jointData.position = kinectToWorld.MultiplyPoint3x4(new Vector3(jointPosition.x * 0.001f, jointPosition.y * 0.001f, jPosZ)); |
521 |
} |
522 |
} |
523 |
|
524 |
jointData.orientation = Quaternion.identity; |
525 |
|
526 |
if(j == 0) |
527 |
{ |
528 |
bodyFrame.bodyData[userIndex].position = jointData.position; |
529 |
bodyFrame.bodyData[userIndex].orientation = jointData.orientation; |
530 |
} |
531 |
|
532 |
bodyFrame.bodyData[userIndex].joint[j] = jointData; |
533 |
} |
534 |
} |
535 |
} |
536 |
|
537 |
return newSkeleton; |
538 |
} |
539 |
|
540 |
public bool PollColorFrame (KinectInterop.SensorData sensorData) |
541 |
{ |
542 |
IntPtr pColorMap = GetUsersColorMap(); |
543 |
if(pColorMap == IntPtr.Zero) |
544 |
return false; |
545 |
|
546 |
sensorData.lastColorFrameTime = DateTime.Now.Ticks; |
547 |
|
548 |
// copy over the map |
549 |
Marshal.Copy(pColorMap, usersColorMap, 0, usersColorMap.Length); |
550 |
|
551 |
// Create the actual users texture based on label map and depth histogram |
552 |
for (int i = 0, srcI = 0, dstI = 0; i < usersClrSize; i++) |
553 |
{ |
554 |
sensorData.colorImage[dstI] = usersColorMap[srcI]; |
555 |
sensorData.colorImage[dstI + 1] = usersColorMap[srcI + 1]; |
556 |
sensorData.colorImage[dstI + 2] = usersColorMap[srcI + 2]; |
557 |
sensorData.colorImage[dstI + 3] = 255; |
558 |
|
559 |
srcI += 3; |
560 |
dstI += 4; |
561 |
} |
562 |
|
563 |
return true; |
564 |
} |
565 |
|
566 |
public bool PollDepthFrame (KinectInterop.SensorData sensorData) |
567 |
{ |
568 |
IntPtr pLabelMap = GetUsersLabelMap(); |
569 |
IntPtr pDepthMap = GetUsersDepthMap(); |
570 |
|
571 |
if(pLabelMap == IntPtr.Zero || pDepthMap == IntPtr.Zero) |
572 |
return false; |
573 |
|
574 |
sensorData.lastDepthFrameTime = sensorData.lastBodyIndexFrameTime = DateTime.Now.Ticks; |
575 |
|
576 |
// copy over the maps |
577 |
Marshal.Copy(pLabelMap, usersLabelMap, 0, usersLabelMap.Length); |
578 |
Marshal.Copy(pDepthMap, usersDepthMap, 0, usersDepthMap.Length); |
579 |
|
580 |
for (int i = 0; i < usersMapSize; i++) |
581 |
{ |
582 |
int userIndex = usersLabelMap[i]; |
583 |
|
584 |
sensorData.bodyIndexImage[i] = userIndex != 0 ? (byte)(userIndex - 1) : (byte)255; |
585 |
sensorData.depthImage[i] = (ushort)usersDepthMap[i]; |
586 |
} |
587 |
|
588 |
return true; |
589 |
} |
590 |
|
591 |
public bool PollInfraredFrame (KinectInterop.SensorData sensorData) |
592 |
{ |
593 |
throw new System.NotImplementedException (); |
594 |
} |
595 |
|
596 |
public void FixJointOrientations (KinectInterop.SensorData sensorData, ref KinectInterop.BodyData bodyData) |
597 |
{ |
598 |
} |
599 |
|
600 |
public bool IsBodyTurned(ref KinectInterop.BodyData bodyData) |
601 |
{ |
602 |
return false; |
603 |
} |
604 |
|
605 |
public Vector2 MapSpacePointToDepthCoords (KinectInterop.SensorData sensorData, Vector3 spacePos) |
606 |
{ |
607 |
Vector2 depthPos = Vector3.zero; |
608 |
|
609 |
int depthX = 0, depthY = 0; ushort depthZ = 0; |
610 |
if(ConvertWorldToDepth(spacePos.x * 1000f, spacePos.y * 1000f, spacePos.z * 1000f, out depthX, out depthY, out depthZ)) |
611 |
{ |
612 |
depthPos = new Vector2(depthX, depthY); |
613 |
} |
614 |
|
615 |
return depthPos; |
616 |
} |
617 |
|
618 |
public Vector3 MapDepthPointToSpaceCoords (KinectInterop.SensorData sensorData, Vector2 depthPos, ushort depthVal) |
619 |
{ |
620 |
Vector3 spacePos = Vector3.zero; |
621 |
|
622 |
float spaceX = 0f, spaceY = 0f, spaceZ = 0f; |
623 |
if(ConvertDepthToWorld(depthPos.x, depthPos.y, depthVal, out spaceX, out spaceY, out spaceZ)) |
624 |
{ |
625 |
spacePos = new Vector3(spaceX / 1000f, spaceY / 1000f, spaceZ / 1000f); |
626 |
} |
627 |
|
628 |
return spacePos; |
629 |
} |
630 |
|
631 |
public bool MapDepthFrameToSpaceCoords (KinectInterop.SensorData sensorData, ref Vector3[] vSpaceCoords) |
632 |
{ |
633 |
return false; |
634 |
} |
635 |
|
636 |
public Vector2 MapDepthPointToColorCoords (KinectInterop.SensorData sensorData, Vector2 depthPos, ushort depthVal) |
637 |
{ |
638 |
Vector2 colorPos = new Vector2(float.NegativeInfinity, float.NegativeInfinity); |
639 |
|
640 |
int colorX = 0, colorY = 0; |
641 |
if(ConvertDepthToColor((int)depthPos.x, (int)depthPos.y, depthVal, out colorX, out colorY)) |
642 |
{ |
643 |
colorPos = new Vector2(colorX, colorY); |
644 |
} |
645 |
|
646 |
return colorPos; |
647 |
} |
648 |
|
649 |
public bool MapDepthFrameToColorCoords (KinectInterop.SensorData sensorData, ref Vector2[] vColorCoords) |
650 |
{ |
651 |
if(sensorData.depthImage != null && sensorData.colorImage != null) |
652 |
{ |
653 |
Vector2 vInfinity = new Vector2(float.NegativeInfinity, float.NegativeInfinity); |
654 |
int i = 0, cx = 0, cy = 0; |
655 |
|
656 |
for(int y = 0; y < sensorData.depthImageHeight; y++) |
657 |
{ |
658 |
for(int x = 0; x < sensorData.depthImageWidth; x++) |
659 |
{ |
660 |
ushort dv = sensorData.depthImage[i]; |
661 |
|
662 |
if(ConvertDepthToColor(x, y, dv, out cx, out cy)) |
663 |
vColorCoords[i] = new Vector2(cx, cy); |
664 |
else |
665 |
vColorCoords[i] = vInfinity; |
666 |
|
667 |
i++; |
668 |
} |
669 |
} |
670 |
|
671 |
return true; |
672 |
} |
673 |
|
674 |
return false; |
675 |
} |
676 |
|
677 |
public bool MapColorFrameToDepthCoords (KinectInterop.SensorData sensorData, ref Vector2[] vDepthCoords) |
678 |
{ |
679 |
return false; |
680 |
} |
681 |
|
682 |
public int GetJointIndex (KinectInterop.JointType joint) |
683 |
{ |
684 |
switch(joint) |
685 |
{ |
686 |
case KinectInterop.JointType.SpineBase: |
687 |
return (int)KinectInterop.JointType.SpineBase; |
688 |
case KinectInterop.JointType.SpineShoulder: |
689 |
case KinectInterop.JointType.Neck: |
690 |
return (int)KinectInterop.JointType.Neck; |
691 |
case KinectInterop.JointType.Head: |
692 |
return (int)KinectInterop.JointType.Head; |
693 |
|
694 |
case KinectInterop.JointType.ShoulderLeft: |
695 |
return (int)KinectInterop.JointType.ShoulderLeft; |
696 |
case KinectInterop.JointType.ElbowLeft: |
697 |
return (int)KinectInterop.JointType.ElbowLeft; |
698 |
//case KinectInterop.JointType.WristLeft: |
699 |
case KinectInterop.JointType.HandLeft: |
700 |
return (int)KinectInterop.JointType.HandLeft; |
701 |
|
702 |
case KinectInterop.JointType.ShoulderRight: |
703 |
return (int)KinectInterop.JointType.ShoulderRight; |
704 |
case KinectInterop.JointType.ElbowRight: |
705 |
return (int)KinectInterop.JointType.ElbowRight; |
706 |
//case KinectInterop.JointType.WristRight: |
707 |
case KinectInterop.JointType.HandRight: |
708 |
return (int)KinectInterop.JointType.HandRight; |
709 |
|
710 |
case KinectInterop.JointType.HipLeft: |
711 |
return (int)KinectInterop.JointType.HipLeft; |
712 |
case KinectInterop.JointType.KneeLeft: |
713 |
return (int)KinectInterop.JointType.KneeLeft; |
714 |
case KinectInterop.JointType.AnkleLeft: |
715 |
//case KinectInterop.JointType.FootLeft: |
716 |
return (int)KinectInterop.JointType.AnkleLeft; |
717 |
|
718 |
case KinectInterop.JointType.HipRight: |
719 |
return (int)KinectInterop.JointType.HipRight; |
720 |
case KinectInterop.JointType.KneeRight: |
721 |
return (int)KinectInterop.JointType.KneeRight; |
722 |
case KinectInterop.JointType.AnkleRight: |
723 |
//case KinectInterop.JointType.FootRight: |
724 |
return (int)KinectInterop.JointType.AnkleRight; |
725 |
} |
726 |
|
727 |
return -1; |
728 |
} |
729 |
|
730 |
// public KinectInterop.JointType GetJointAtIndex (int index) |
731 |
// { |
732 |
// switch(index) |
733 |
// { |
734 |
// case (int)SkeletonJoint.HIPS: |
735 |
// return KinectInterop.JointType.SpineBase; |
736 |
// case (int)SkeletonJoint.NECK: |
737 |
// return KinectInterop.JointType.Neck; |
738 |
// case (int)SkeletonJoint.HEAD: |
739 |
// return KinectInterop.JointType.Head; |
740 |
// |
741 |
// case (int)SkeletonJoint.LEFT_SHOULDER: |
742 |
// return KinectInterop.JointType.ShoulderLeft; |
743 |
// case (int)SkeletonJoint.LEFT_ELBOW: |
744 |
// return KinectInterop.JointType.ElbowLeft; |
745 |
// case (int)SkeletonJoint.LEFT_HAND: |
746 |
// return KinectInterop.JointType.WristLeft; |
747 |
// |
748 |
// case (int)SkeletonJoint.RIGHT_SHOULDER: |
749 |
// return KinectInterop.JointType.ShoulderRight; |
750 |
// case (int)SkeletonJoint.RIGHT_ELBOW: |
751 |
// return KinectInterop.JointType.ElbowRight; |
752 |
// case (int)SkeletonJoint.RIGHT_HAND: |
753 |
// return KinectInterop.JointType.WristRight; |
754 |
// |
755 |
// case (int)SkeletonJoint.LEFT_HIP: |
756 |
// return KinectInterop.JointType.HipLeft; |
757 |
// case (int)SkeletonJoint.LEFT_KNEE: |
758 |
// return KinectInterop.JointType.KneeLeft; |
759 |
// case (int)SkeletonJoint.LEFT_FOOT: |
760 |
// return KinectInterop.JointType.AnkleLeft; |
761 |
// |
762 |
// case (int)SkeletonJoint.RIGHT_HIP: |
763 |
// return KinectInterop.JointType.HipRight; |
764 |
// case (int)SkeletonJoint.RIGHT_KNEE: |
765 |
// return KinectInterop.JointType.KneeRight; |
766 |
// case (int)SkeletonJoint.RIGHT_FOOT: |
767 |
// return KinectInterop.JointType.AnkleRight; |
768 |
// } |
769 |
// |
770 |
// return (KinectInterop.JointType)(-1); |
771 |
// } |
772 |
|
773 |
public KinectInterop.JointType GetParentJoint (KinectInterop.JointType joint) |
774 |
{ |
775 |
switch(joint) |
776 |
{ |
777 |
case KinectInterop.JointType.Neck: |
778 |
return KinectInterop.JointType.SpineBase; |
779 |
case KinectInterop.JointType.Head: |
780 |
return KinectInterop.JointType.Neck; |
781 |
|
782 |
case KinectInterop.JointType.ShoulderLeft: |
783 |
return KinectInterop.JointType.Neck; |
784 |
case KinectInterop.JointType.ElbowLeft: |
785 |
return KinectInterop.JointType.ShoulderLeft; |
786 |
case KinectInterop.JointType.HandLeft: |
787 |
return KinectInterop.JointType.ElbowLeft; |
788 |
|
789 |
case KinectInterop.JointType.ShoulderRight: |
790 |
return KinectInterop.JointType.Neck; |
791 |
case KinectInterop.JointType.ElbowRight: |
792 |
return KinectInterop.JointType.ShoulderRight; |
793 |
case KinectInterop.JointType.HandRight: |
794 |
return KinectInterop.JointType.ElbowRight; |
795 |
|
796 |
case KinectInterop.JointType.HipLeft: |
797 |
return KinectInterop.JointType.SpineBase; |
798 |
case KinectInterop.JointType.KneeLeft: |
799 |
return KinectInterop.JointType.HipLeft; |
800 |
case KinectInterop.JointType.AnkleLeft: |
801 |
return KinectInterop.JointType.KneeLeft; |
802 |
|
803 |
case KinectInterop.JointType.HipRight: |
804 |
return KinectInterop.JointType.SpineBase; |
805 |
case KinectInterop.JointType.KneeRight: |
806 |
return KinectInterop.JointType.HipRight; |
807 |
case KinectInterop.JointType.AnkleRight: |
808 |
return KinectInterop.JointType.KneeRight; |
809 |
} |
810 |
|
811 |
return joint; |
812 |
} |
813 |
|
814 |
public KinectInterop.JointType GetNextJoint (KinectInterop.JointType joint) |
815 |
{ |
816 |
switch(joint) |
817 |
{ |
818 |
case KinectInterop.JointType.SpineBase: |
819 |
return KinectInterop.JointType.Neck; |
820 |
case KinectInterop.JointType.Neck: |
821 |
return KinectInterop.JointType.Head; |
822 |
|
823 |
case KinectInterop.JointType.ShoulderLeft: |
824 |
return KinectInterop.JointType.ElbowLeft; |
825 |
case KinectInterop.JointType.ElbowLeft: |
826 |
return KinectInterop.JointType.HandLeft; |
827 |
|
828 |
case KinectInterop.JointType.ShoulderRight: |
829 |
return KinectInterop.JointType.ElbowRight; |
830 |
case KinectInterop.JointType.ElbowRight: |
831 |
return KinectInterop.JointType.HandRight; |
832 |
|
833 |
case KinectInterop.JointType.HipLeft: |
834 |
return KinectInterop.JointType.KneeLeft; |
835 |
case KinectInterop.JointType.KneeLeft: |
836 |
return KinectInterop.JointType.AnkleLeft; |
837 |
|
838 |
case KinectInterop.JointType.HipRight: |
839 |
return KinectInterop.JointType.KneeRight; |
840 |
case KinectInterop.JointType.KneeRight: |
841 |
return KinectInterop.JointType.AnkleRight; |
842 |
} |
843 |
|
844 |
return joint; // end joint |
845 |
} |
846 |
|
847 |
public bool IsFaceTrackingAvailable (ref bool bNeedRestart) |
848 |
{ |
849 |
bNeedRestart = false; |
850 |
return false; |
851 |
} |
852 |
|
853 |
public bool InitFaceTracking (bool bUseFaceModel, bool bDrawFaceRect) |
854 |
{ |
855 |
return false; |
856 |
} |
857 |
|
858 |
public void FinishFaceTracking () |
859 |
{ |
860 |
} |
861 |
|
862 |
public bool UpdateFaceTracking () |
863 |
{ |
864 |
return false; |
865 |
} |
866 |
|
867 |
public bool IsFaceTrackingActive () |
868 |
{ |
869 |
return false; |
870 |
} |
871 |
|
872 |
public bool IsDrawFaceRect () |
873 |
{ |
874 |
return false; |
875 |
} |
876 |
|
877 |
public bool IsFaceTracked (long userId) |
878 |
{ |
879 |
return false; |
880 |
} |
881 |
|
882 |
public bool GetFaceRect (long userId, ref Rect faceRect) |
883 |
{ |
884 |
return false; |
885 |
} |
886 |
|
887 |
public void VisualizeFaceTrackerOnColorTex (Texture2D texColor) |
888 |
{ |
889 |
} |
890 |
|
891 |
public bool GetHeadPosition (long userId, ref Vector3 headPos) |
892 |
{ |
893 |
return false; |
894 |
} |
895 |
|
896 |
public bool GetHeadRotation (long userId, ref Quaternion headRot) |
897 |
{ |
898 |
return false; |
899 |
} |
900 |
|
901 |
public bool GetAnimUnits (long userId, ref System.Collections.Generic.Dictionary<KinectInterop.FaceShapeAnimations, float> afAU) |
902 |
{ |
903 |
return false; |
904 |
} |
905 |
|
906 |
public bool GetShapeUnits (long userId, ref System.Collections.Generic.Dictionary<KinectInterop.FaceShapeDeformations, float> afSU) |
907 |
{ |
908 |
return false; |
909 |
} |
910 |
|
911 |
public int GetFaceModelVerticesCount (long userId) |
912 |
{ |
913 |
return 0; |
914 |
} |
915 |
|
916 |
public bool GetFaceModelVertices (long userId, ref Vector3[] avVertices) |
917 |
{ |
918 |
return false; |
919 |
} |
920 |
|
921 |
public int GetFaceModelTrianglesCount () |
922 |
{ |
923 |
return 0; |
924 |
} |
925 |
|
926 |
public bool GetFaceModelTriangles (bool bMirrored, ref int[] avTriangles) |
927 |
{ |
928 |
return false; |
929 |
} |
930 |
|
931 |
public bool IsSpeechRecognitionAvailable (ref bool bNeedRestart) |
932 |
{ |
933 |
bNeedRestart = false; |
934 |
return false; |
935 |
} |
936 |
|
937 |
public int InitSpeechRecognition (string sRecoCriteria, bool bUseKinect, bool bAdaptationOff) |
938 |
{ |
939 |
return 0; |
940 |
} |
941 |
|
942 |
public void FinishSpeechRecognition () |
943 |
{ |
944 |
} |
945 |
|
946 |
public int UpdateSpeechRecognition () |
947 |
{ |
948 |
return 0; |
949 |
} |
950 |
|
951 |
public int LoadSpeechGrammar (string sFileName, short iLangCode, bool bDynamic) |
952 |
{ |
953 |
return 0; |
954 |
} |
955 |
|
956 |
public int AddGrammarPhrase(string sFromRule, string sToRule, string sPhrase, bool bClearRulePhrases, bool bCommitGrammar) |
957 |
{ |
958 |
return 0; |
959 |
} |
960 |
|
961 |
public void SetSpeechConfidence (float fConfidence) |
962 |
{ |
963 |
} |
964 |
|
965 |
public bool IsSpeechStarted () |
966 |
{ |
967 |
return false; |
968 |
} |
969 |
|
970 |
public bool IsSpeechEnded () |
971 |
{ |
972 |
return false; |
973 |
} |
974 |
|
975 |
public bool IsPhraseRecognized () |
976 |
{ |
977 |
return false; |
978 |
} |
979 |
|
980 |
public float GetPhraseConfidence() |
981 |
{ |
982 |
return 0; |
983 |
} |
984 |
|
985 |
public string GetRecognizedPhraseTag () |
986 |
{ |
987 |
return string.Empty; |
988 |
} |
989 |
|
990 |
public void ClearRecognizedPhrase () |
991 |
{ |
992 |
} |
993 |
|
994 |
public bool IsBackgroundRemovalAvailable(ref bool bNeedRestart) |
995 |
{ |
996 |
bBackgroundRemovalInited = KinectInterop.IsOpenCvAvailable(ref bNeedRestart); |
997 |
return bBackgroundRemovalInited; |
998 |
} |
999 |
|
1000 |
public bool InitBackgroundRemoval(KinectInterop.SensorData sensorData, bool isHiResPrefered) |
1001 |
{ |
1002 |
return KinectInterop.InitBackgroundRemoval(sensorData, isHiResPrefered); |
1003 |
} |
1004 |
|
1005 |
public void FinishBackgroundRemoval(KinectInterop.SensorData sensorData) |
1006 |
{ |
1007 |
KinectInterop.FinishBackgroundRemoval(sensorData); |
1008 |
bBackgroundRemovalInited = false; |
1009 |
} |
1010 |
|
1011 |
public bool UpdateBackgroundRemoval(KinectInterop.SensorData sensorData, bool isHiResPrefered, Color32 defaultColor, bool bAlphaTexOnly) |
1012 |
{ |
1013 |
return KinectInterop.UpdateBackgroundRemoval(sensorData, isHiResPrefered, defaultColor, bAlphaTexOnly); |
1014 |
} |
1015 |
|
1016 |
public bool IsBackgroundRemovalActive() |
1017 |
{ |
1018 |
return bBackgroundRemovalInited; |
1019 |
} |
1020 |
|
1021 |
public bool IsBRHiResSupported() |
1022 |
{ |
1023 |
return false; |
1024 |
} |
1025 |
|
1026 |
public Rect GetForegroundFrameRect(KinectInterop.SensorData sensorData, bool isHiResPrefered) |
1027 |
{ |
1028 |
return KinectInterop.GetForegroundFrameRect(sensorData, isHiResPrefered); |
1029 |
} |
1030 |
|
1031 |
public int GetForegroundFrameLength(KinectInterop.SensorData sensorData, bool isHiResPrefered) |
1032 |
{ |
1033 |
return KinectInterop.GetForegroundFrameLength(sensorData, isHiResPrefered); |
1034 |
} |
1035 |
|
1036 |
public bool PollForegroundFrame(KinectInterop.SensorData sensorData, bool isHiResPrefered, Color32 defaultColor, bool bLimitedUsers, ICollection<int> alTrackedIndexes, ref byte[] foregroundImage) |
1037 |
{ |
1038 |
return KinectInterop.PollForegroundFrame(sensorData, isHiResPrefered, defaultColor, bLimitedUsers, alTrackedIndexes, ref foregroundImage); |
1039 |
} |
1040 |
|
1041 |
} |