프로젝트

일반

사용자정보

통계
| 개정판:

t1 / TFDContents / Assets / KinectScripts / Interfaces / Kinect1Interface.cs @ 3

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

1
using UnityEngine;
2
using System.Collections;
3
using System.Collections.Generic;
4
using System.Runtime.InteropServices;
5
using System;
6

    
7
public class Kinect1Interface : DepthSensorInterface 
8
{
9
	public static class Constants
10
	{
11
		public const int NuiSkeletonCount = 6;
12
		public const int JointCount = 20;
13

    
14
		public const NuiImageResolution ColorImageResolution = NuiImageResolution.resolution640x480;
15
		public const NuiImageResolution DepthImageResolution = NuiImageResolution.resolution640x480;
16
		
17
		public const bool IsNearMode = true;
18
	}
19

    
20
	// Structs and constants for interfacing C# with the Kinect.dll 
21

    
22
	[Flags]
23
	public enum NuiInitializeFlags : uint
24
	{
25
		UsesNone = 0,
26
		UsesAudio = 0x10000000,
27
		UsesDepthAndPlayerIndex = 0x00000001,
28
		UsesColor = 0x00000002,
29
		UsesSkeleton = 0x00000008,
30
		UsesDepth = 0x00000020,
31
		UsesHighQualityColor = 0x00000040
32
	}
33
	
34
	public enum NuiErrorCodes : uint
35
	{
36
		FrameNoData = 0x83010001,
37
		StreamNotEnabled = 0x83010002,
38
		ImageStreamInUse = 0x83010003,
39
		FrameLimitExceeded = 0x83010004,
40
		FeatureNotInitialized = 0x83010005,
41
		DeviceNotGenuine = 0x83010006,
42
		InsufficientBandwidth = 0x83010007,
43
		DeviceNotSupported = 0x83010008,
44
		DeviceInUse = 0x83010009,
45
		
46
		DatabaseNotFound = 0x8301000D,
47
		DatabaseVersionMismatch = 0x8301000E,
48
		HardwareFeatureUnavailable = 0x8301000F,
49
		
50
		DeviceNotConnected = 0x83010014,
51
		DeviceNotReady = 0x83010015,
52
		SkeletalEngineBusy = 0x830100AA,
53
		DeviceNotPowered = 0x8301027F,
54
	}
55
	
56
	public enum NuiSkeletonPositionIndex : int
57
	{
58
		HipCenter = 0,
59
		Spine,
60
		ShoulderCenter,
61
		Head,
62
		ShoulderLeft,
63
		ElbowLeft,
64
		WristLeft,
65
		HandLeft,
66
		ShoulderRight,
67
		ElbowRight,
68
		WristRight,
69
		HandRight,
70
		HipLeft,
71
		KneeLeft,
72
		AnkleLeft,
73
		FootLeft,
74
		HipRight,
75
		KneeRight,
76
		AnkleRight,
77
		FootRight,
78
		Count
79
	}
80
	
81
	public enum NuiSkeletonPositionTrackingState
82
	{
83
		NotTracked = 0,
84
		Inferred,
85
		Tracked
86
	}
87
	
88
	public enum NuiSkeletonTrackingState
89
	{
90
		NotTracked = 0,
91
		PositionOnly,
92
		SkeletonTracked
93
	}
94
	
95
	public enum NuiImageType
96
	{
97
		DepthAndPlayerIndex = 0,	// USHORT
98
		Color,						// RGB32 data
99
		ColorYUV,					// YUY2 stream from camera h/w, but converted to RGB32 before user getting it.
100
		ColorRawYUV,				// YUY2 stream from camera h/w.
101
		Depth						// USHORT
102
	}
103
	
104
	public enum NuiImageResolution
105
	{
106
		resolutionInvalid = -1,
107
		resolution80x60 = 0,
108
		resolution320x240 = 1,
109
		resolution640x480 = 2,
110
		resolution1280x960 = 3     // for hires color only
111
	}
112

    
113
	public enum NuiImageStreamFlags
114
	{
115
		None = 0x00000000,
116
		SupressNoFrameData = 0x0001000,
117
		EnableNearMode = 0x00020000,
118
		TooFarIsNonZero = 0x0004000
119
	}
120
	
121
	public struct NuiSkeletonData
122
	{
123
		public NuiSkeletonTrackingState eTrackingState;
124
		public uint dwTrackingID;
125
		public uint dwEnrollmentIndex_NotUsed;
126
		public uint dwUserIndex;
127
		public Vector4 Position;
128
		[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 20, ArraySubType = UnmanagedType.Struct)]
129
		public Vector4[] SkeletonPositions;
130
		[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 20, ArraySubType = UnmanagedType.Struct)]
131
		public NuiSkeletonPositionTrackingState[] eSkeletonPositionTrackingState;
132
		public uint dwQualityFlags;
133
	}
134
	
135
	public struct NuiSkeletonFrame
136
	{
137
		public long liTimeStamp;
138
		public uint dwFrameNumber;
139
		public uint dwFlags;
140
		public Vector4 vFloorClipPlane;
141
		public Vector4 vNormalToGravity;
142
		[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.Struct)]
143
		public NuiSkeletonData[] SkeletonData;
144
	}
145
	
146
	public struct NuiTransformSmoothParameters
147
	{
148
		public float fSmoothing;
149
		public float fCorrection;
150
		public float fPrediction;
151
		public float fJitterRadius;
152
		public float fMaxDeviationRadius;
153
	}
154
	
155
	public struct NuiSkeletonBoneRotation
156
	{
157
		public Matrix4x4 rotationMatrix;
158
		public Quaternion rotationQuaternion;
159
	}
160
	
161
	public struct NuiSkeletonBoneOrientation
162
	{
163
		public NuiSkeletonPositionIndex endJoint;
164
		public NuiSkeletonPositionIndex startJoint;
165
		public NuiSkeletonBoneRotation hierarchicalRotation;
166
		public NuiSkeletonBoneRotation absoluteRotation;
167
	}
168
	
169
	public struct NuiImageViewArea
170
	{
171
		public int eDigitalZoom;
172
		public int lCenterX;
173
		public int lCenterY;
174
	}
175
	
176
	public class NuiImageBuffer
177
	{
178
		public int m_Width;
179
		public int m_Height;
180
		public int m_BytesPerPixel;
181
		public IntPtr m_pBuffer;
182
	}
183
	
184
	public struct NuiImageFrame
185
	{
186
		public Int64 liTimeStamp;
187
		public uint dwFrameNumber;
188
		public NuiImageType eImageType;
189
		public NuiImageResolution eResolution;
190
		//[MarshalAsAttribute(UnmanagedType.Interface)]
191
		public IntPtr pFrameTexture;
192
		public uint dwFrameFlags_NotUsed;
193
		public NuiImageViewArea ViewArea_NotUsed;
194
	}
195
	
196
	public struct NuiLockedRect
197
	{
198
		public int pitch;
199
		public int size;
200
		//[MarshalAsAttribute(UnmanagedType.U8)] 
201
		public IntPtr pBits; 
202
		
203
	}
204

    
205
	public enum NuiHandpointerState : uint
206
	{
207
		None = 0,
208
		Tracked = 1,
209
		Active = 2,
210
		Interactive = 4,
211
		Pressed = 8,
212
		PrimaryForUser = 0x10
213
	}
214
	
215
	public enum InteractionHandEventType : int
216
	{
217
		None = 0,
218
		Grip = 1,
219
		Release = 2
220
	}
221
	
222
	private NuiImageViewArea pcViewArea = new NuiImageViewArea 
223
	{
224
		eDigitalZoom = 0,
225
		lCenterX = 0,
226
		lCenterY = 0
227
	};
228
	
229
	public struct FaceRect
230
	{
231
		public int x;
232
		public int y;
233
		public int width;
234
		public int height;
235
	}
236
	
237

    
238
	// private interface data
239

    
240
	private KinectInterop.FrameSource sourceFlags;
241

    
242
	//private IntPtr colorStreamHandle;
243
	//private IntPtr depthStreamHandle;
244

    
245
	private NuiSkeletonFrame skeletonFrame;
246
	private NuiTransformSmoothParameters smoothParameters;
247

    
248
	private Dictionary<uint, InteractionHandEventType> lastLeftHandEvent = new Dictionary<uint, InteractionHandEventType>();
249
	private Dictionary<uint, InteractionHandEventType> lastRightHandEvent = new Dictionary<uint, InteractionHandEventType>();
250

    
251
	private bool isUseFaceModel = false;
252
	private bool isDrawFaceRect = false;
253

    
254
	private bool bFaceTrackingInited = false;
255
	private FaceRect faceRect;
256
	private Vector4 vHeadPos = Vector4.zero;
257
	private Vector4 vHeadRot = Vector4.zero;
258

    
259
	private float[] afAU = null;
260
	private float[] afSU = null;
261

    
262
	private bool bBackgroundRemovalInited = false;
263

    
264
	// exported wrapper functions
265

    
266
	[DllImport(@"Kinect10.dll")]
267
	private static extern int NuiGetSensorCount(out int pCount);
268

    
269
	[DllImport(@"Kinect10.dll")]
270
	private static extern int NuiTransformSmooth(ref NuiSkeletonFrame pSkeletonFrame, ref NuiTransformSmoothParameters pSmoothingParams);
271

    
272
	[DllImport(@"Kinect10.dll")]
273
	private static extern int NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution(NuiImageResolution eColorResolution, NuiImageResolution eDepthResolution, ref NuiImageViewArea pcViewArea, int lDepthX, int lDepthY, ushort sDepthValue, out int plColorX, out int plColorY);
274
	
275

    
276
	[DllImportAttribute(@"KinectUnityWrapper.dll")]
277
	private static extern int InitKinectSensor(NuiInitializeFlags dwFlags, bool bEnableEvents, int iColorResolution, int iDepthResolution, bool bNearMode);
278
	
279
	[DllImportAttribute(@"KinectUnityWrapper.dll")]
280
	private static extern void ShutdownKinectSensor();
281
	
282
	[DllImportAttribute(@"KinectUnityWrapper.dll")]
283
	private static extern int SetKinectElevationAngle(int sensorAngle);
284
	
285
	[DllImportAttribute(@"KinectUnityWrapper.dll")]
286
	private static extern int GetKinectElevationAngle();
287
	
288
	[DllImportAttribute(@"KinectUnityWrapper.dll")]
289
	private static extern int UpdateKinectSensor();
290
	
291
	[DllImport(@"KinectUnityWrapper.dll")]
292
	private static extern int GetSkeletonFrameLength();
293
	
294
	[DllImport(@"KinectUnityWrapper.dll")]
295
	private static extern bool GetSkeletonFrameData(ref NuiSkeletonFrame pSkeletonData, ref uint iDataBufLen, bool bNewFrame);
296
	
297
	[DllImport(@"KinectUnityWrapper.dll")]
298
	private static extern int GetNextSkeletonFrame(uint dwWaitMs);
299

    
300
	[DllImport(@"KinectUnityWrapper.dll")]
301
	private static extern IntPtr GetColorStreamHandle();
302
	
303
	[DllImport(@"KinectUnityWrapper.dll")]
304
	private static extern IntPtr GetDepthStreamHandle();
305
	
306
	[DllImport(@"KinectUnityWrapper.dll")]
307
	private static extern bool GetColorFrameData(IntPtr btVideoBuf, ref uint iVideoBufLen, bool bGetNewFrame);
308
	
309
	[DllImport(@"KinectUnityWrapper.dll")]
310
	private static extern bool GetDepthFrameData(IntPtr shDepthBuf, ref uint iDepthBufLen, bool bGetNewFrame);
311
	
312
	[DllImport(@"KinectUnityWrapper.dll")]
313
	private static extern bool GetInfraredFrameData(IntPtr shInfraredBuf, ref uint iInfraredBufLen, bool bGetNewFrame);
314

    
315

    
316
	[DllImport(@"KinectUnityWrapper")]
317
	private static extern int InitKinectInteraction();
318
	
319
	[DllImport(@"KinectUnityWrapper")]
320
	private static extern void FinishKinectInteraction();
321
	
322
	[DllImport( @"KinectUnityWrapper")]
323
	private static extern uint GetInteractorsCount();
324
	
325
	[DllImport( @"KinectUnityWrapper", EntryPoint = "GetInteractorSkeletonTrackingID" )]
326
	private static extern uint GetSkeletonTrackingID( uint player );
327
	
328
	[DllImport( @"KinectUnityWrapper", EntryPoint = "GetInteractorLeftHandState" )]
329
	private static extern uint GetLeftHandState( uint player );
330
	
331
	[DllImport( @"KinectUnityWrapper", EntryPoint = "GetInteractorRightHandState" )]
332
	private static extern uint GetRightHandState( uint player );
333
	
334
	[DllImport( @"KinectUnityWrapper", EntryPoint = "GetInteractorLeftHandEvent" )]
335
	private static extern InteractionHandEventType GetLeftHandEvent( uint player );
336
	
337
	[DllImport( @"KinectUnityWrapper", EntryPoint = "GetInteractorRightHandEvent" )]
338
	private static extern InteractionHandEventType GetRightHandEvent( uint player );
339
	
340

    
341
	[DllImport("KinectUnityWrapper", EntryPoint = "InitFaceTracking")]
342
	private static extern int InitFaceTrackingNative();
343

    
344
	[DllImport("KinectUnityWrapper", EntryPoint = "FinishFaceTracking")]
345
	private static extern void FinishFaceTrackingNative();
346

    
347
	[DllImport("KinectUnityWrapper", EntryPoint = "UpdateFaceTracking")]
348
	private static extern int UpdateFaceTrackingNative();
349
	
350
	[DllImport("KinectUnityWrapper", EntryPoint = "IsFaceTracked")]
351
	private static extern bool IsFaceTrackedNative();
352

    
353
	[DllImport("KinectUnityWrapper", EntryPoint = "GetFaceTrackingID")]
354
	private static extern uint GetFaceTrackingIDNative();
355
	
356
	[DllImport(@"KinectUnityWrapper.dll", EntryPoint = "GetHeadPosition")]
357
	private static extern bool GetHeadPositionNative(ref Vector4 pvHeadPos);
358

    
359
	[DllImport(@"KinectUnityWrapper.dll", EntryPoint = "GetHeadRotation")]
360
	private static extern bool GetHeadRotationNative(ref Vector4 pvHeadRot);
361

    
362
	[DllImport(@"KinectUnityWrapper.dll", EntryPoint = "GetHeadScale")]
363
	private static extern bool GetHeadScaleNative(ref Vector4 pvHeadScale);
364
	
365
	[DllImport(@"KinectUnityWrapper.dll", EntryPoint = "GetFaceRect")]
366
	private static extern bool GetFaceRectNative(ref FaceRect pRectFace);
367

    
368
	[DllImport("KinectUnityWrapper", EntryPoint = "GetAnimUnitsCount")]
369
	private static extern int GetAnimUnitsCountNative();
370

    
371
	[DllImport("KinectUnityWrapper", EntryPoint = "GetAnimUnits")]
372
	private static extern bool GetAnimUnitsNative(IntPtr afAU, ref int iAUCount);
373

    
374
	[DllImport("KinectUnityWrapper", EntryPoint = "GetShapeUnitsCount")]
375
	private static extern int GetShapeUnitsCountNative();
376

    
377
	[DllImport("KinectUnityWrapper", EntryPoint = "GetShapeUnits")]
378
	private static extern bool GetShapeUnitsNative(IntPtr afSU, ref int iSUCount);
379

    
380
	[DllImport("KinectUnityWrapper", EntryPoint = "GetShapePointsCount")]
381
	private static extern int GetFacePointsCountNative();
382

    
383
	[DllImport("KinectUnityWrapper", EntryPoint = "GetShapePoints")]
384
	private static extern bool GetFacePointsNative(IntPtr avPoints, ref int iPointsCount);
385
	
386
	[DllImport("KinectUnityWrapper", EntryPoint = "Get3DShapePointsCount")]
387
	private static extern int GetModelPointsCountNative();
388

    
389
	[DllImport("KinectUnityWrapper", EntryPoint = "Get3DShapePoints")]
390
	private static extern bool GetModelPointsNative(IntPtr avPoints, ref int iPointsCount);
391

    
392
	[DllImport("KinectUnityWrapper", EntryPoint = "GetTriangleCount")]
393
	private static extern int GetTriangleCountNative();
394
	
395
	[DllImport("KinectUnityWrapper", EntryPoint = "GetTriangles")]
396
	private static extern bool GetTrianglesNative(IntPtr aiTriangles, ref int iPointsCount);
397
	
398
	// speech wrapper functions
399
	[DllImport("KinectUnityWrapper", EntryPoint = "InitSpeechRecognizer")]
400
	private static extern int InitSpeechRecognizerNative([MarshalAs(UnmanagedType.LPWStr)]string sRecoCriteria, bool bUseKinect, bool bAdaptationOff);
401

    
402
	[DllImport("KinectUnityWrapper", EntryPoint = "FinishSpeechRecognizer")]
403
	private static extern void FinishSpeechRecognizerNative();
404
	
405
	[DllImport("KinectUnityWrapper", EntryPoint = "UpdateSpeechRecognizer")]
406
	private static extern int UpdateSpeechRecognizerNative();
407
	
408
	[DllImport("KinectUnityWrapper", EntryPoint = "LoadSpeechGrammar")]
409
	private static extern int LoadSpeechGrammarNative([MarshalAs(UnmanagedType.LPWStr)]string sFileName, short iNewLangCode, bool bDynamic);
410
	
411
	[DllImport("KinectUnityWrapper", EntryPoint = "AddGrammarPhrase")]
412
	private static extern int AddGrammarPhraseNative([MarshalAs(UnmanagedType.LPWStr)]string sFromRule, [MarshalAs(UnmanagedType.LPWStr)]string sToRule, [MarshalAs(UnmanagedType.LPWStr)]string sPhrase, bool bClearRule, bool bCommitGrammar);
413
	
414
	[DllImport("KinectUnityWrapper", EntryPoint = "SetRequiredConfidence")]
415
	private static extern void SetSpeechConfidenceNative(float fConfidence);
416
	
417
	[DllImport("KinectUnityWrapper", EntryPoint = "IsSoundStarted")]
418
	private static extern bool IsSpeechStartedNative();
419
	
420
	[DllImport("KinectUnityWrapper", EntryPoint = "IsSoundEnded")]
421
	private static extern bool IsSpeechEndedNative();
422
	
423
	[DllImport("KinectUnityWrapper", EntryPoint = "IsPhraseRecognized")]
424
	private static extern bool IsPhraseRecognizedNative();
425
	
426
	[DllImport("KinectUnityWrapper", EntryPoint = "GetPhraseConfidence")]
427
	private static extern float GetPhraseConfidenceNative();
428
	
429
	[DllImport("KinectUnityWrapper", EntryPoint = "GetRecognizedTag")]
430
	private static extern IntPtr GetRecognizedPhraseTagNative();
431
	
432
	[DllImport("KinectUnityWrapper", EntryPoint = "ClearPhraseRecognized")]
433
	private static extern void ClearRecognizedPhraseNative();
434

    
435

    
436
	[DllImport(@"KinectUnityWrapper", EntryPoint = "InitBackgroundRemoval")]
437
	public static extern int InitBackgroundRemovalNative();
438
	
439
	[DllImport(@"KinectUnityWrapper", EntryPoint = "FinishBackgroundRemoval")]
440
	public static extern void FinishBackgroundRemovalNative();
441
	
442
	[DllImport(@"KinectUnityWrapper", EntryPoint = "UpdateBackgroundRemoval")]
443
	public static extern int UpdateBackgroundRemovalNative();
444

    
445
	[DllImport(@"KinectUnityWrapper", EntryPoint = "IsBackgroundRemovalActive")]
446
	public static extern bool IsBackgroundRemovalActiveNative();
447
	
448
	[DllImport(@"KinectUnityWrapper", EntryPoint = "GetBackgroundRemovalFrameLength")]
449
	public static extern int GetBackgroundRemovalFrameLengthNative();
450
	
451
	[DllImport(@"KinectUnityWrapper.dll", EntryPoint = "GetBackgroundRemovalFrameData")]
452
	public static extern bool GetBackgroundRemovalFrameDataNative(IntPtr btVideoBuf, ref uint iVideoBufLen, bool bGetNewFrame);
453
	
454

    
455
	private string GetNuiErrorString(int hr)
456
	{
457
		string message = string.Empty;
458
		uint uhr = (uint)hr;
459
		
460
		switch(uhr)
461
		{
462
		case (uint)NuiErrorCodes.FrameNoData:
463
			message = "Frame contains no data.";
464
			break;
465
		case (uint)NuiErrorCodes.StreamNotEnabled:
466
			message = "Stream is not enabled.";
467
			break;
468
		case (uint)NuiErrorCodes.ImageStreamInUse:
469
			message = "Image stream is already in use.";
470
			break;
471
		case (uint)NuiErrorCodes.FrameLimitExceeded:
472
			message = "Frame limit is exceeded.";
473
			break;
474
		case (uint)NuiErrorCodes.FeatureNotInitialized:
475
			message = "Feature is not initialized.";
476
			break;
477
		case (uint)NuiErrorCodes.DeviceNotGenuine:
478
			message = "Device is not genuine.";
479
			break;
480
		case (uint)NuiErrorCodes.InsufficientBandwidth:
481
			message = "Bandwidth is not sufficient.";
482
			break;
483
		case (uint)NuiErrorCodes.DeviceNotSupported:
484
			message = "Device is not supported (e.g. Kinect for XBox 360).";
485
			break;
486
		case (uint)NuiErrorCodes.DeviceInUse:
487
			message = "Device is already in use.";
488
			break;
489
		case (uint)NuiErrorCodes.DatabaseNotFound:
490
			message = "Database not found.";
491
			break;
492
		case (uint)NuiErrorCodes.DatabaseVersionMismatch:
493
			message = "Database version mismatch.";
494
			break;
495
		case (uint)NuiErrorCodes.HardwareFeatureUnavailable:
496
			message = "Hardware feature is not available.";
497
			break;
498
		case (uint)NuiErrorCodes.DeviceNotConnected:
499
			message = "Device is not connected.";
500
			break;
501
		case (uint)NuiErrorCodes.DeviceNotReady:
502
			message = "Device is not ready.";
503
			break;
504
		case (uint)NuiErrorCodes.SkeletalEngineBusy:
505
			message = "Skeletal engine is busy.";
506
			break;
507
		case (uint)NuiErrorCodes.DeviceNotPowered:
508
			message = "Device is not powered.";
509
			break;
510
			
511
		default:
512
			message = "hr=0x" + uhr.ToString("X");
513
			break;
514
		}
515
		
516
		return message;
517
	}
518

    
519
	private bool NuiImageResolutionToSize(NuiImageResolution res, out int refWidth, out int refHeight)
520
	{
521
		switch( res )
522
		{
523
			case NuiImageResolution.resolution80x60:
524
				refWidth = 80;
525
				refHeight = 60;
526
				return true;
527
			case NuiImageResolution.resolution320x240:
528
				refWidth = 320;
529
				refHeight = 240;
530
				return true;
531
			case NuiImageResolution.resolution640x480:
532
				refWidth = 640;
533
				refHeight = 480;
534
				return true;
535
			case NuiImageResolution.resolution1280x960:
536
				refWidth = 1280;
537
				refHeight = 960;
538
				return true;
539
			default:
540
				refWidth = 0;
541
				refHeight = 0;
542
				break;
543
		}
544

    
545
		return false;
546
	}
547

    
548
	public KinectInterop.DepthSensorPlatform GetSensorPlatform()
549
	{
550
		return KinectInterop.DepthSensorPlatform.KinectSDKv1;
551
	}
552
	
553
	public bool InitSensorInterface (bool bCopyLibs, ref bool bNeedRestart)
554
	{
555
		bool bOneCopied = false, bAllCopied = true;
556
		//string sTargetPath = KinectInterop.GetTargetDllPath(".", KinectInterop.Is64bitArchitecture()) + "/";
557
		string sTargetPath = "./";
558

    
559
		if(!bCopyLibs)
560
		{
561
			// check if the native library is there
562
			string sTargetLib = sTargetPath + "KinectUnityWrapper.dll";
563
			bNeedRestart = false;
564

    
565
			string sZipFileName = !KinectInterop.Is64bitArchitecture() ? "KinectV1UnityWrapper.x86.zip" : "KinectV1UnityWrapper.x64.zip";
566
			long iTargetSize = KinectInterop.GetUnzippedEntrySize(sZipFileName, "KinectUnityWrapper.dll");
567

    
568
//			System.IO.FileInfo targetFile = new System.IO.FileInfo(sTargetLib);
569
//			return targetFile.Exists && targetFile.Length == iTargetSize;
570
			return KinectInterop.IsFileExists(sTargetLib, iTargetSize);
571
		}
572

    
573
		if(!KinectInterop.Is64bitArchitecture())
574
		{
575
			//Debug.Log("x32-architecture detected.");
576

    
577
			Dictionary<string, string> dictFilesToUnzip = new Dictionary<string, string>();
578

    
579
			dictFilesToUnzip["FaceTrackData.dll"] = sTargetPath + "FaceTrackData.dll";
580
			KinectInterop.UnzipResourceFiles(dictFilesToUnzip, "KinectV1FaceData.zip", ref bOneCopied, ref bAllCopied);
581

    
582
			dictFilesToUnzip.Clear();
583
			dictFilesToUnzip["KinectUnityWrapper.dll"] = sTargetPath + "KinectUnityWrapper.dll";
584
			dictFilesToUnzip["KinectInteraction180_32.dll"] = sTargetPath + "KinectInteraction180_32.dll";
585
			dictFilesToUnzip["FaceTrackLib.dll"] = sTargetPath + "FaceTrackLib.dll";
586
			dictFilesToUnzip["KinectBackgroundRemoval180_32.dll"] = sTargetPath + "KinectBackgroundRemoval180_32.dll";
587

    
588
			dictFilesToUnzip["msvcp100.dll"] = sTargetPath + "msvcp100.dll";
589
			dictFilesToUnzip["msvcr100.dll"] = sTargetPath + "msvcr100.dll";
590

    
591
			KinectInterop.UnzipResourceFiles(dictFilesToUnzip, "KinectV1UnityWrapper.x86.zip", ref bOneCopied, ref bAllCopied);
592
		}
593
		else
594
		{
595
			//Debug.Log("x64-architecture detected.");
596

    
597
			Dictionary<string, string> dictFilesToUnzip = new Dictionary<string, string>();
598
			
599
			dictFilesToUnzip["FaceTrackData.dll"] = sTargetPath + "FaceTrackData.dll";
600
			KinectInterop.UnzipResourceFiles(dictFilesToUnzip, "KinectV1FaceData.zip", ref bOneCopied, ref bAllCopied);
601

    
602
			dictFilesToUnzip.Clear();
603
			dictFilesToUnzip["KinectUnityWrapper.dll"] = sTargetPath + "KinectUnityWrapper.dll";
604
			dictFilesToUnzip["KinectInteraction180_64.dll"] = sTargetPath + "KinectInteraction180_64.dll";
605
			dictFilesToUnzip["FaceTrackLib.dll"] = sTargetPath + "FaceTrackLib.dll";
606
			dictFilesToUnzip["KinectBackgroundRemoval180_64.dll"] = sTargetPath + "KinectBackgroundRemoval180_64.dll";
607
			
608
			dictFilesToUnzip["msvcp100.dll"] = sTargetPath + "msvcp100.dll";
609
			dictFilesToUnzip["msvcr100.dll"] = sTargetPath + "msvcr100.dll";
610
			
611
			KinectInterop.UnzipResourceFiles(dictFilesToUnzip, "KinectV1UnityWrapper.x64.zip", ref bOneCopied, ref bAllCopied);
612
		}
613

    
614
		bNeedRestart = (bOneCopied && bAllCopied);
615

    
616
		return true;
617
	}
618

    
619
	public void FreeSensorInterface (bool bDeleteLibs)
620
	{
621
		if(bDeleteLibs)
622
		{
623
			KinectInterop.DeleteNativeLib("KinectUnityWrapper.dll", true);
624
			KinectInterop.DeleteNativeLib("KinectInteraction180_32.dll", false);
625
			KinectInterop.DeleteNativeLib("KinectInteraction180_64.dll", false);
626
			KinectInterop.DeleteNativeLib("FaceTrackLib.dll", false);
627
			KinectInterop.DeleteNativeLib("FaceTrackData.dll", false);
628
			KinectInterop.DeleteNativeLib("KinectBackgroundRemoval180_32.dll", false);
629
			KinectInterop.DeleteNativeLib("KinectBackgroundRemoval180_64.dll", false);
630
			KinectInterop.DeleteNativeLib("msvcp100.dll", false);
631
			KinectInterop.DeleteNativeLib("msvcr100.dll", false);
632
		}
633
	}
634

    
635
	public bool IsSensorAvailable()
636
	{
637
		bool bAvailable = GetSensorsCount() > 0;
638
		return bAvailable;
639
	}
640
	
641
	public int GetSensorsCount ()
642
	{
643
		int iSensorCount = 0;
644
		int hr = NuiGetSensorCount(out iSensorCount);
645

    
646
		if(hr == 0)
647
			return iSensorCount;
648
		else
649
			return 0;
650
	}
651

    
652
	public KinectInterop.SensorData OpenDefaultSensor (KinectInterop.FrameSource dwFlags, float sensorAngle, bool bUseMultiSource)
653
	{
654
		sourceFlags = dwFlags;
655

    
656
		NuiInitializeFlags nuiFlags = // NuiInitializeFlags.UsesNone;
657
			NuiInitializeFlags.UsesSkeleton | NuiInitializeFlags.UsesDepthAndPlayerIndex;
658

    
659
		if((dwFlags & KinectInterop.FrameSource.TypeBody) != 0)
660
		{
661
			nuiFlags |= NuiInitializeFlags.UsesSkeleton;
662
		}
663
		
664
		if((dwFlags & KinectInterop.FrameSource.TypeColor) != 0)
665
		{
666
			nuiFlags |= NuiInitializeFlags.UsesColor;
667
		}
668
		
669
		if((dwFlags & KinectInterop.FrameSource.TypeDepth) != 0)
670
		{
671
			nuiFlags |= NuiInitializeFlags.UsesDepthAndPlayerIndex;
672
		}
673
		
674
		if((dwFlags & KinectInterop.FrameSource.TypeBodyIndex) != 0)
675
		{
676
			nuiFlags |= NuiInitializeFlags.UsesDepthAndPlayerIndex;
677
		}
678
		
679
		if((dwFlags & KinectInterop.FrameSource.TypeInfrared) != 0)
680
		{
681
			nuiFlags |= (NuiInitializeFlags.UsesColor | (NuiInitializeFlags)0x8000);
682
		}
683
		
684
		if((dwFlags & KinectInterop.FrameSource.TypeAudio) != 0)
685
		{
686
			nuiFlags |= NuiInitializeFlags.UsesAudio;
687
		}
688

    
689
		FacetrackingManager[] faceManagers = GameObject.FindObjectsOfType(typeof(FacetrackingManager)) as FacetrackingManager[];
690
		if(faceManagers != null && faceManagers.Length > 0)
691
		{
692
			for(int i = 0; i < faceManagers.Length; i++)
693
			{
694
				if(faceManagers[i].enabled)
695
				{
696
					//Debug.Log("Found FacetrackingManager => UsesColor");
697
					nuiFlags |= NuiInitializeFlags.UsesColor;
698
					break;
699
				}
700
			}
701
		}
702
		
703
		SpeechManager[] speechManagers = GameObject.FindObjectsOfType(typeof(SpeechManager)) as SpeechManager[];
704
		if(speechManagers != null && speechManagers.Length > 0)
705
		{
706
			for(int i = 0; i < speechManagers.Length; i++)
707
			{
708
				if(speechManagers[i].enabled)
709
				{
710
					//Debug.Log("Found SpeechManager => UsesAudio");
711
					nuiFlags |= NuiInitializeFlags.UsesAudio;
712
					break;
713
				}
714
			}
715
		}
716
		
717
		int hr = InitKinectSensor(nuiFlags, true, (int)Constants.ColorImageResolution, (int)Constants.DepthImageResolution, Constants.IsNearMode);
718

    
719
		if(hr == 0)
720
		{
721
			// set sensor angle
722
			SetKinectElevationAngle((int)sensorAngle);
723

    
724
			// initialize Kinect interaction
725
			hr = InitKinectInteraction();
726
			if(hr != 0)
727
			{
728
				Debug.LogError(string.Format("Error initializing KinectInteraction: hr=0x{0:X}", hr));
729
			}
730
			
731
			KinectInterop.SensorData sensorData = new KinectInterop.SensorData();
732

    
733
			sensorData.bodyCount = Constants.NuiSkeletonCount;
734
			sensorData.jointCount = Constants.JointCount;
735

    
736
			sensorData.depthCameraFOV = 46.6f;
737
			sensorData.colorCameraFOV = 48.6f;
738
			sensorData.depthCameraOffset = 0.01f;
739
			sensorData.faceOverlayOffset = 0.01f;
740

    
741
			NuiImageResolutionToSize(Constants.ColorImageResolution, out sensorData.colorImageWidth, out sensorData.colorImageHeight);
742
//			sensorData.colorImageWidth = Constants.ColorImageWidth;
743
//			sensorData.colorImageHeight = Constants.ColorImageHeight;
744

    
745
			if((dwFlags & KinectInterop.FrameSource.TypeColor) != 0)
746
			{
747
				//colorStreamHandle =  GetColorStreamHandle();
748
				sensorData.colorImage = new byte[sensorData.colorImageWidth * sensorData.colorImageHeight * 4];
749
			}
750

    
751
			NuiImageResolutionToSize(Constants.DepthImageResolution, out sensorData.depthImageWidth, out sensorData.depthImageHeight);
752
//			sensorData.depthImageWidth = Constants.DepthImageWidth;
753
//			sensorData.depthImageHeight = Constants.DepthImageHeight;
754
			
755
			if((dwFlags & KinectInterop.FrameSource.TypeDepth) != 0)
756
			{
757
				//depthStreamHandle = GetDepthStreamHandle();
758
				sensorData.depthImage = new ushort[sensorData.depthImageWidth * sensorData.depthImageHeight];
759
			}
760
			
761
			if((dwFlags & KinectInterop.FrameSource.TypeBodyIndex) != 0)
762
			{
763
				sensorData.bodyIndexImage = new byte[sensorData.depthImageWidth * sensorData.depthImageHeight];
764
			}
765
			
766
			if((dwFlags & KinectInterop.FrameSource.TypeInfrared) != 0)
767
			{
768
				sensorData.infraredImage = new ushort[sensorData.colorImageWidth * sensorData.colorImageHeight];
769
			}
770

    
771
			if((dwFlags & KinectInterop.FrameSource.TypeBody) != 0)
772
			{
773
				skeletonFrame = new NuiSkeletonFrame() 
774
				{ 
775
					SkeletonData = new NuiSkeletonData[Constants.NuiSkeletonCount] 
776
				};
777
				
778
				// default values used to pass to smoothing function
779
				smoothParameters = new NuiTransformSmoothParameters();
780

    
781
				smoothParameters.fSmoothing = 0.5f;
782
				smoothParameters.fCorrection = 0.5f;
783
				smoothParameters.fPrediction = 0.5f;
784
				smoothParameters.fJitterRadius = 0.05f;
785
				smoothParameters.fMaxDeviationRadius = 0.04f;
786
			}
787
			
788
			return sensorData;
789
		}
790
		else
791
		{
792
			Debug.LogError("InitKinectSensor failed: " + GetNuiErrorString(hr));
793
		}
794

    
795
		return null;
796
	}
797

    
798
	public void CloseSensor (KinectInterop.SensorData sensorData)
799
	{
800
		FinishKinectInteraction();
801
		ShutdownKinectSensor();
802
	}
803

    
804
	public bool UpdateSensorData (KinectInterop.SensorData sensorData)
805
	{
806
		int hr = UpdateKinectSensor();
807
		return (hr == 0);
808
	}
809

    
810
	public bool GetMultiSourceFrame (KinectInterop.SensorData sensorData)
811
	{
812
		return false;
813
	}
814

    
815
	public void FreeMultiSourceFrame (KinectInterop.SensorData sensorData)
816
	{
817
	}
818

    
819
	private int NuiSkeletonGetNextFrame(uint dwMillisecondsToWait, ref NuiSkeletonFrame pSkeletonFrame)
820
	{
821
		if(sourceFlags != KinectInterop.FrameSource.TypeAudio)
822
		{
823
			// non-audio sources
824
			uint iFrameLength = (uint)GetSkeletonFrameLength();
825
			bool bSuccess = GetSkeletonFrameData(ref pSkeletonFrame, ref iFrameLength, true);
826
			return bSuccess ? 0 : -1;
827
		}
828
		else
829
		{
830
			// audio only
831
			int hr = GetNextSkeletonFrame(dwMillisecondsToWait);
832

    
833
			if(hr == 0)
834
			{
835
				uint iFrameLength = (uint)GetSkeletonFrameLength();
836
				bool bSuccess = GetSkeletonFrameData(ref pSkeletonFrame, ref iFrameLength, true);
837
				
838
				return bSuccess ? 0 : -1;
839
			}
840
			
841
			return hr;
842
		}
843
	}
844

    
845
	private void GetHandStateAndConf(uint skeletonId, bool isRightHand, uint handState, InteractionHandEventType handEvent, 
846
	                                 ref Dictionary<uint, InteractionHandEventType> lastHandEvent,
847
	                                 ref KinectInterop.HandState refHandState, 
848
	                                 ref KinectInterop.TrackingConfidence refHandConf)
849
	{
850
		bool bHandPrimary = (handState & (uint)NuiHandpointerState.Active) != 0;
851
		refHandConf = bHandPrimary ? KinectInterop.TrackingConfidence.High : KinectInterop.TrackingConfidence.Low;
852

    
853
		if(!lastHandEvent.ContainsKey(skeletonId))
854
		{
855
			lastHandEvent[skeletonId] = InteractionHandEventType.Release;
856
		}
857

    
858
		if(handEvent == InteractionHandEventType.Grip || 
859
		   handEvent == InteractionHandEventType.Release)
860
		{
861
			if(lastHandEvent[skeletonId] != handEvent)
862
			{
863
				//Debug.Log(string.Format("{0} - {1}, event: {2}", skeletonId, !isRightHand ? "left" : "right", handEvent));
864
				lastHandEvent[skeletonId] = handEvent;
865
			}
866
		}
867
		
868
		//if(bHandPrimary)
869
		{
870
			switch(lastHandEvent[skeletonId])
871
			{
872
				case InteractionHandEventType.Grip:
873
					refHandState = KinectInterop.HandState.Closed;
874
					break;
875

    
876
				case InteractionHandEventType.Release:
877
					refHandState = KinectInterop.HandState.Open;
878
					break;
879
			}
880
		}
881
//		else
882
//		{
883
////			if(lastHandEvent[skeletonId] != InteractionHandEventType.Release)
884
////			{
885
////				Debug.Log(string.Format("{0} - old: {1}, NONE: {2}", skeletonId, lastHandEvent[skeletonId], InteractionHandEventType.Release));
886
////				lastHandEvent[skeletonId] = InteractionHandEventType.Release;
887
////			}
888
//
889
//			refHandState = KinectInterop.HandState.NotTracked;
890
//		}
891
	}
892

    
893
	public bool PollBodyFrame (KinectInterop.SensorData sensorData, ref KinectInterop.BodyFrameData bodyFrame, 
894
	                           ref Matrix4x4 kinectToWorld, bool bIgnoreJointZ)
895
	{
896
		// get next body frame
897
		int hr = NuiSkeletonGetNextFrame(0, ref skeletonFrame);
898
		bool newSkeleton = (hr == 0);
899

    
900
		if(newSkeleton)
901
		{
902
			bodyFrame.liPreviousTime = bodyFrame.liRelativeTime;
903
			bodyFrame.liRelativeTime = skeletonFrame.liTimeStamp;
904

    
905
			hr = NuiTransformSmooth(ref skeletonFrame, ref smoothParameters);
906
			if(hr < 0)
907
			{
908
				Debug.LogError(string.Format("Skeleton Data Smoothing failed: hr=0x{0:X}", hr));
909
			}
910

    
911
			for(uint i = 0; i < sensorData.bodyCount; i++)
912
			{
913
				NuiSkeletonData body = skeletonFrame.SkeletonData[i];
914
				
915
				bodyFrame.bodyData[i].bIsTracked = (short)(body.eTrackingState ==  NuiSkeletonTrackingState.SkeletonTracked ? 1 : 0);
916
				
917
				if(body.eTrackingState ==  NuiSkeletonTrackingState.SkeletonTracked)
918
				{
919
					// transfer body and joints data
920
					bodyFrame.bodyData[i].liTrackingID = (long)body.dwTrackingID;
921
					
922
					for(int j = 0; j < sensorData.jointCount; j++)
923
					{
924
						KinectInterop.JointData jointData = bodyFrame.bodyData[i].joint[j];
925
						
926
						//jointData.jointType = (KinectInterop.JointType)j;
927
						jointData.trackingState = (KinectInterop.TrackingState)body.eSkeletonPositionTrackingState[j];
928
						
929
						if(jointData.trackingState != KinectInterop.TrackingState.NotTracked)
930
						{
931
							//jointData.kinectPos = body.SkeletonPositions[j];
932
							float jPosZ = (bIgnoreJointZ && j > 0) ? bodyFrame.bodyData[i].joint[0].kinectPos.z : body.SkeletonPositions[j].z;
933
							jointData.kinectPos = new Vector3(body.SkeletonPositions[j].x, body.SkeletonPositions[j].y, body.SkeletonPositions[j].z);
934
							jointData.position = kinectToWorld.MultiplyPoint3x4(new Vector3(body.SkeletonPositions[j].x, body.SkeletonPositions[j].y, jPosZ));
935
						}
936
						
937
						jointData.orientation = Quaternion.identity;
938
//							Windows.Kinect.Vector4 vQ = body.JointOrientations[jointData.jointType].Orientation;
939
//							jointData.orientation = new Quaternion(vQ.X, vQ.Y, vQ.Z, vQ.W);
940
						
941
						if(j == 0)
942
						{
943
							bodyFrame.bodyData[i].position = jointData.position;
944
							bodyFrame.bodyData[i].orientation = jointData.orientation;
945
						}
946
						
947
						bodyFrame.bodyData[i].joint[j] = jointData;
948
					}
949

    
950

    
951
					// tranfer hand states
952
					uint intCount = GetInteractorsCount();
953
					string sDebug = string.Empty;
954

    
955
					for(uint intIndex = 0; intIndex < intCount; intIndex++)
956
					{
957
						uint skeletonId = GetSkeletonTrackingID(intIndex);
958

    
959
						if(skeletonId == body.dwTrackingID)
960
						{
961
							uint leftHandState = GetLeftHandState(intIndex);
962
							InteractionHandEventType leftHandEvent = GetLeftHandEvent(intIndex);
963

    
964
							uint rightHandState = GetRightHandState(intIndex);
965
							InteractionHandEventType rightHandEvent = GetRightHandEvent(intIndex);
966
							
967
//							sDebug += string.Format("{0}-L:{1},{2};R:{3},{4}    ", skeletonId, 
968
//							                        (int)leftHandState, (int)leftHandEvent, 
969
//							                        (int)rightHandState, (int)rightHandEvent);
970
							
971
							GetHandStateAndConf(skeletonId, false, leftHandState, leftHandEvent, 
972
							                    ref lastLeftHandEvent,
973
							                    ref bodyFrame.bodyData[i].leftHandState, 
974
							                    ref bodyFrame.bodyData[i].leftHandConfidence);
975
							
976
							GetHandStateAndConf(skeletonId, true, rightHandState, rightHandEvent, 
977
							                    ref lastRightHandEvent,
978
							                    ref bodyFrame.bodyData[i].rightHandState, 
979
							                    ref bodyFrame.bodyData[i].rightHandConfidence);
980
						}
981
					}
982

    
983
					if(intCount > 0 && sDebug.Length > 0)
984
					{
985
						Debug.Log(sDebug);
986
					}
987
				}
988
			}
989

    
990
			if(sensorData.hintHeightAngle)
991
			{
992
				// get the floor plane
993
				Vector4 vFloorPlane = skeletonFrame.vFloorClipPlane;
994
				Vector3 floorPlane = new Vector3(vFloorPlane.x, vFloorPlane.y, vFloorPlane.z);
995
				
996
				sensorData.sensorRotDetected = Quaternion.FromToRotation(floorPlane, Vector3.up);
997
				sensorData.sensorHgtDetected = vFloorPlane.w;
998
			}
999
		}
1000
		
1001
		return newSkeleton;
1002
	}
1003

    
1004
	public bool PollColorFrame (KinectInterop.SensorData sensorData)
1005
	{
1006
		uint videoBufLen = (uint)sensorData.colorImage.Length;
1007
		
1008
		var pColorData = GCHandle.Alloc(sensorData.colorImage, GCHandleType.Pinned);
1009
		bool newColor = GetColorFrameData(pColorData.AddrOfPinnedObject(), ref videoBufLen, true);
1010
		pColorData.Free();
1011
		
1012
		if (newColor)
1013
		{
1014
			sensorData.lastColorFrameTime = DateTime.Now.Ticks;
1015

    
1016
			for (int i = 0; i < videoBufLen; i += 4)
1017
			{
1018
				byte btTmp = sensorData.colorImage[i];
1019
				sensorData.colorImage[i] = sensorData.colorImage[i + 2];
1020
				sensorData.colorImage[i + 2] = btTmp;
1021
				sensorData.colorImage[i + 3] = 255;
1022
			}
1023
		}
1024

    
1025
		return newColor;
1026
	}
1027

    
1028
	public bool PollDepthFrame (KinectInterop.SensorData sensorData)
1029
	{
1030
		uint depthBufLen = (uint)(sensorData.depthImage.Length * sizeof(ushort));
1031
		
1032
		var pDepthData = GCHandle.Alloc(sensorData.depthImage, GCHandleType.Pinned);
1033
		bool newDepth = GetDepthFrameData(pDepthData.AddrOfPinnedObject(), ref depthBufLen, true);
1034
		pDepthData.Free();
1035

    
1036
		if(newDepth)
1037
		{
1038
			sensorData.lastDepthFrameTime = sensorData.lastBodyIndexFrameTime = DateTime.Now.Ticks;
1039
			uint depthLen = (uint)sensorData.depthImage.Length;
1040

    
1041
			for (int i = 0; i < depthLen; i++)
1042
			{
1043
				if((sensorData.depthImage[i] & 7) != 0)
1044
					sensorData.bodyIndexImage[i] = (byte)((sensorData.depthImage[i] & 7) - 1);
1045
				else
1046
					sensorData.bodyIndexImage[i] = 255;
1047

    
1048
				sensorData.depthImage[i] = (ushort)(sensorData.depthImage[i] >> 3);
1049
			}
1050
		}
1051

    
1052
		return newDepth;
1053
	}
1054

    
1055
	public bool PollInfraredFrame (KinectInterop.SensorData sensorData)
1056
	{
1057
		uint infraredBufLen = (uint)(sensorData.infraredImage.Length * sizeof(ushort));
1058
		
1059
		var pInfraredData = GCHandle.Alloc(sensorData.infraredImage, GCHandleType.Pinned);
1060
		bool newInfrared = GetInfraredFrameData(pInfraredData.AddrOfPinnedObject(), ref infraredBufLen, true);
1061
		pInfraredData.Free();
1062

    
1063
		if (newInfrared) 
1064
		{
1065
			sensorData.lastInfraredFrameTime = DateTime.Now.Ticks;
1066
		}
1067
		
1068
		return newInfrared;
1069
	}
1070

    
1071
	public void FixJointOrientations(KinectInterop.SensorData sensorData, ref KinectInterop.BodyData bodyData)
1072
	{
1073
		// fix the hips-to-spine tilt (it is about 40 degrees to the back)
1074
		int hipsIndex = (int)KinectInterop.JointType.SpineBase;
1075

    
1076
		Quaternion quat = bodyData.joint[hipsIndex].normalRotation;
1077
		quat *= Quaternion.Euler(40f, 0f, 0f);
1078
		bodyData.joint[hipsIndex].normalRotation = quat;
1079

    
1080
		Vector3 mirroredAngles = quat.eulerAngles;
1081
		mirroredAngles.y = -mirroredAngles.y;
1082
		mirroredAngles.z = -mirroredAngles.z;
1083
		bodyData.joint[hipsIndex].mirroredRotation = Quaternion.Euler(mirroredAngles);
1084

    
1085
		bodyData.normalRotation = bodyData.joint[hipsIndex].normalRotation;
1086
		bodyData.mirroredRotation = bodyData.joint[hipsIndex].mirroredRotation;
1087
	}
1088

    
1089
	public bool IsBodyTurned(ref KinectInterop.BodyData bodyData)
1090
	{
1091
		return false;
1092
	}
1093
	
1094
	private void NuiTransformSkeletonToDepthImage(Vector3 vPoint, out float pfDepthX, out float pfDepthY, out float pfDepthZ)
1095
	{
1096
		if (vPoint.z > float.Epsilon)
1097
		{
1098
			pfDepthX = 0.5f + ((vPoint.x * 285.63f) / (vPoint.z * 320f));
1099
			pfDepthY = 0.5f - ((vPoint.y * 285.63f) / (vPoint.z * 240f));
1100
			pfDepthZ = vPoint.z * 1000f;
1101
		}
1102
		else
1103
		{
1104
			pfDepthX = 0f;
1105
			pfDepthY = 0f;
1106
			pfDepthZ = 0f;
1107
		}
1108
	}
1109
	
1110
	public Vector2 MapSpacePointToDepthCoords (KinectInterop.SensorData sensorData, Vector3 spacePos)
1111
	{
1112
		float fDepthX, fDepthY, fDepthZ;
1113
		NuiTransformSkeletonToDepthImage(spacePos, out fDepthX, out fDepthY, out fDepthZ);
1114
		
1115
		fDepthX = Mathf.RoundToInt(fDepthX * sensorData.depthImageWidth);
1116
		fDepthY = Mathf.RoundToInt(fDepthY * sensorData.depthImageHeight);
1117
		fDepthZ = Mathf.RoundToInt(fDepthZ);
1118

    
1119
		Vector3 point = new Vector3(fDepthX, fDepthY, fDepthZ);
1120

    
1121
		return point;
1122
	}
1123

    
1124
	private Vector3 NuiTransformDepthImageToSkeleton(float fDepthX, float fDepthY, int depthValue)
1125
	{
1126
		Vector3 point = Vector3.zero;
1127
		
1128
		if (depthValue > 0)
1129
		{
1130
			float fSpaceZ = ((float)depthValue) / 1000f;
1131
			float fSpaceX = ((fDepthX - 0.5f) * (0.003501f * fSpaceZ)) * 320f;
1132
			float fSpaceY = ((0.5f - fDepthY) * (0.003501f * fSpaceZ)) * 240f;
1133
			
1134
			point = new Vector3(fSpaceX, fSpaceY, fSpaceZ);
1135
		}
1136
		
1137
		return point;
1138
	}
1139
	
1140
	public Vector3 MapDepthPointToSpaceCoords (KinectInterop.SensorData sensorData, Vector2 depthPos, ushort depthVal)
1141
	{
1142
		float fDepthX = depthPos.x / sensorData.depthImageWidth;
1143
		float fDepthY = depthPos.y / sensorData.depthImageHeight;
1144
		
1145
		Vector3 point = NuiTransformDepthImageToSkeleton(fDepthX, fDepthY, depthVal);
1146
		
1147
		return point;
1148
	}
1149

    
1150
	public bool MapDepthFrameToSpaceCoords (KinectInterop.SensorData sensorData, ref Vector3[] vSpaceCoords)
1151
	{
1152
		// comment out this block of code, if you experience big lags (it is used for creating user or scene visualizations in 3d space)
1153
		if(sensorData.depthImage != null)
1154
		{
1155
			int i = 0;
1156

    
1157
			for(int y = 0; y < sensorData.depthImageHeight; y++)
1158
			{
1159
				for(int x = 0; x < sensorData.depthImageWidth; x++)
1160
				{
1161
					float fDepthX = (float)x / sensorData.depthImageWidth;
1162
					float fDepthY = (float)y / sensorData.depthImageHeight;
1163
					ushort depthVal = sensorData.depthImage[i];
1164

    
1165
					vSpaceCoords[i] = NuiTransformDepthImageToSkeleton(fDepthX, fDepthY, depthVal);
1166
					i++;
1167
				}
1168
			}
1169

    
1170
			return true;
1171
		}
1172

    
1173
		return false;
1174
	}
1175

    
1176
	public Vector2 MapDepthPointToColorCoords (KinectInterop.SensorData sensorData, Vector2 depthPos, ushort depthVal)
1177
	{
1178
		int cx, cy;
1179
		NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution(
1180
			Constants.ColorImageResolution,
1181
			Constants.DepthImageResolution,
1182
			ref pcViewArea,
1183
			(int)depthPos.x, (int)depthPos.y, (ushort)(depthVal << 3),
1184
			out cx, out cy);
1185
		
1186
		return new Vector2(cx, cy);
1187
	}
1188

    
1189
	public bool MapDepthFrameToColorCoords (KinectInterop.SensorData sensorData, ref Vector2[] vColorCoords)
1190
	{
1191
		// comment out this block of code, if you experience big lags (it is used for creating cut-out texture of the users)
1192
		if(sensorData.depthImage != null && sensorData.colorImage != null)
1193
		{
1194
			int i = 0, cx = 0, cy = 0;
1195
			
1196
			for(int y = 0; y < sensorData.depthImageHeight; y++)
1197
			{
1198
				for(int x = 0; x < sensorData.depthImageWidth; x++)
1199
				{
1200
					ushort dv = sensorData.depthImage[i];
1201

    
1202
					NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution(
1203
						Constants.ColorImageResolution,
1204
						Constants.DepthImageResolution,
1205
						ref pcViewArea,
1206
						x, y, (ushort)(dv << 3),
1207
						out cx, out cy);
1208

    
1209
					vColorCoords[i] = new Vector2(cx, cy);
1210
					i++;
1211
				}
1212
			}
1213
			
1214
			return true;
1215
		}
1216

    
1217
		return false;
1218
	}
1219

    
1220
	public bool MapColorFrameToDepthCoords (KinectInterop.SensorData sensorData, ref Vector2[] vDepthCoords)
1221
	{
1222
		return false;
1223
	}
1224
	
1225
	// returns the index of the given joint in joint's array or -1 if joint is not applicable
1226
	public int GetJointIndex(KinectInterop.JointType joint)
1227
	{
1228
		switch(joint)
1229
		{
1230
			case KinectInterop.JointType.SpineBase:
1231
				return (int)NuiSkeletonPositionIndex.HipCenter;
1232
			case KinectInterop.JointType.SpineMid:
1233
				return (int)NuiSkeletonPositionIndex.Spine;
1234
			case KinectInterop.JointType.SpineShoulder:
1235
			case KinectInterop.JointType.Neck:
1236
				return (int)NuiSkeletonPositionIndex.ShoulderCenter;
1237
			case KinectInterop.JointType.Head:
1238
				return (int)NuiSkeletonPositionIndex.Head;
1239
				
1240
			case KinectInterop.JointType.ShoulderLeft:
1241
				return (int)NuiSkeletonPositionIndex.ShoulderLeft;
1242
			case KinectInterop.JointType.ElbowLeft:
1243
				return (int)NuiSkeletonPositionIndex.ElbowLeft;
1244
			case KinectInterop.JointType.WristLeft:
1245
				return (int)NuiSkeletonPositionIndex.WristLeft;
1246
			case KinectInterop.JointType.HandLeft:
1247
				return (int)NuiSkeletonPositionIndex.HandLeft;
1248
				
1249
			case KinectInterop.JointType.ShoulderRight:
1250
				return (int)NuiSkeletonPositionIndex.ShoulderRight;
1251
			case KinectInterop.JointType.ElbowRight:
1252
				return (int)NuiSkeletonPositionIndex.ElbowRight;
1253
			case KinectInterop.JointType.WristRight:
1254
				return (int)NuiSkeletonPositionIndex.WristRight;
1255
			case KinectInterop.JointType.HandRight:
1256
				return (int)NuiSkeletonPositionIndex.HandRight;
1257
				
1258
			case KinectInterop.JointType.HipLeft:
1259
				return (int)NuiSkeletonPositionIndex.HipLeft;
1260
			case KinectInterop.JointType.KneeLeft:
1261
				return (int)NuiSkeletonPositionIndex.KneeLeft;
1262
			case KinectInterop.JointType.AnkleLeft:
1263
				return (int)NuiSkeletonPositionIndex.AnkleLeft;
1264
			case KinectInterop.JointType.FootLeft:
1265
				return (int)NuiSkeletonPositionIndex.FootLeft;
1266
				
1267
			case KinectInterop.JointType.HipRight:
1268
				return (int)NuiSkeletonPositionIndex.HipRight;
1269
			case KinectInterop.JointType.KneeRight:
1270
				return (int)NuiSkeletonPositionIndex.KneeRight;
1271
			case KinectInterop.JointType.AnkleRight:
1272
				return (int)NuiSkeletonPositionIndex.AnkleRight;
1273
			case KinectInterop.JointType.FootRight:
1274
				return (int)NuiSkeletonPositionIndex.FootRight;
1275
		}
1276
		
1277
		return -1;
1278
	}
1279

    
1280
//	// returns the joint at given index
1281
//	public KinectInterop.JointType GetJointAtIndex(int index)
1282
//	{
1283
//		switch(index)
1284
//		{
1285
//		case (int)NuiSkeletonPositionIndex.HipCenter:
1286
//			return KinectInterop.JointType.SpineBase;
1287
//		case (int)NuiSkeletonPositionIndex.Spine:
1288
//			return KinectInterop.JointType.SpineMid;
1289
//		case (int)NuiSkeletonPositionIndex.ShoulderCenter:
1290
//			return KinectInterop.JointType.Neck;
1291
//		case (int)NuiSkeletonPositionIndex.Head:
1292
//			return KinectInterop.JointType.Head;
1293
//			
1294
//		case (int)NuiSkeletonPositionIndex.ShoulderLeft:
1295
//			return KinectInterop.JointType.ShoulderLeft;
1296
//		case (int)NuiSkeletonPositionIndex.ElbowLeft:
1297
//			return KinectInterop.JointType.ElbowLeft;
1298
//		case (int)NuiSkeletonPositionIndex.WristLeft:
1299
//			return KinectInterop.JointType.WristLeft;
1300
//		case (int)NuiSkeletonPositionIndex.HandLeft:
1301
//			return KinectInterop.JointType.HandLeft;
1302
//			
1303
//		case (int)NuiSkeletonPositionIndex.ShoulderRight:
1304
//			return KinectInterop.JointType.ShoulderRight;
1305
//		case (int)NuiSkeletonPositionIndex.ElbowRight:
1306
//			return KinectInterop.JointType.ElbowRight;
1307
//		case (int)NuiSkeletonPositionIndex.WristRight:
1308
//			return KinectInterop.JointType.WristRight;
1309
//		case (int)NuiSkeletonPositionIndex.HandRight:
1310
//			return KinectInterop.JointType.HandRight;
1311
//			
1312
//		case (int)NuiSkeletonPositionIndex.HipLeft:
1313
//			return KinectInterop.JointType.HipLeft;
1314
//		case (int)NuiSkeletonPositionIndex.KneeLeft:
1315
//			return KinectInterop.JointType.KneeLeft;
1316
//		case (int)NuiSkeletonPositionIndex.AnkleLeft:
1317
//			return KinectInterop.JointType.AnkleLeft;
1318
//		case (int)NuiSkeletonPositionIndex.FootLeft:
1319
//			return KinectInterop.JointType.FootLeft;
1320
//			
1321
//		case (int)NuiSkeletonPositionIndex.HipRight:
1322
//			return KinectInterop.JointType.HipRight;
1323
//		case (int)NuiSkeletonPositionIndex.KneeRight:
1324
//			return KinectInterop.JointType.KneeRight;
1325
//		case (int)NuiSkeletonPositionIndex.AnkleRight:
1326
//			return KinectInterop.JointType.AnkleRight;
1327
//		case (int)NuiSkeletonPositionIndex.FootRight:
1328
//			return KinectInterop.JointType.FootRight;
1329
//		}
1330
//		
1331
//		return (KinectInterop.JointType)(-1);
1332
//	}
1333

    
1334
	// returns the parent joint of the given joint
1335
	public KinectInterop.JointType GetParentJoint(KinectInterop.JointType joint)
1336
	{
1337
		switch(joint)
1338
		{
1339
			case KinectInterop.JointType.SpineBase:
1340
				return KinectInterop.JointType.SpineBase;
1341
				
1342
			case KinectInterop.JointType.ShoulderLeft:
1343
			case KinectInterop.JointType.ShoulderRight:
1344
				return KinectInterop.JointType.Neck;
1345
				
1346
			case KinectInterop.JointType.HipLeft:
1347
			case KinectInterop.JointType.HipRight:
1348
				return KinectInterop.JointType.SpineBase;
1349
		}
1350
		
1351
		return (KinectInterop.JointType)((int)joint - 1);
1352
	}
1353
	
1354
	// returns the next joint in the hierarchy, as to the given joint
1355
	public KinectInterop.JointType GetNextJoint(KinectInterop.JointType joint)
1356
	{
1357
		switch(joint)
1358
		{
1359
			case KinectInterop.JointType.SpineBase:
1360
				return KinectInterop.JointType.SpineMid;
1361
			case KinectInterop.JointType.SpineMid:
1362
				return KinectInterop.JointType.Neck;
1363
			case KinectInterop.JointType.Neck:
1364
				return KinectInterop.JointType.Head;
1365
				
1366
			case KinectInterop.JointType.ShoulderLeft:
1367
				return KinectInterop.JointType.ElbowLeft;
1368
			case KinectInterop.JointType.ElbowLeft:
1369
				return KinectInterop.JointType.WristLeft;
1370
			case KinectInterop.JointType.WristLeft:
1371
				return KinectInterop.JointType.HandLeft;
1372
				
1373
			case KinectInterop.JointType.ShoulderRight:
1374
				return KinectInterop.JointType.ElbowRight;
1375
			case KinectInterop.JointType.ElbowRight:
1376
				return KinectInterop.JointType.WristRight;
1377
			case KinectInterop.JointType.WristRight:
1378
				return KinectInterop.JointType.HandRight;
1379
				
1380
			case KinectInterop.JointType.HipLeft:
1381
				return KinectInterop.JointType.KneeLeft;
1382
			case KinectInterop.JointType.KneeLeft:
1383
				return KinectInterop.JointType.AnkleLeft;
1384
			case KinectInterop.JointType.AnkleLeft:
1385
				return KinectInterop.JointType.FootLeft;
1386
				
1387
			case KinectInterop.JointType.HipRight:
1388
				return KinectInterop.JointType.KneeRight;
1389
			case KinectInterop.JointType.KneeRight:
1390
				return KinectInterop.JointType.AnkleRight;
1391
			case KinectInterop.JointType.AnkleRight:
1392
				return KinectInterop.JointType.FootRight;
1393
		}
1394
		
1395
		return joint;  // in case of end joint - Head, HandLeft, HandRight, FootLeft, FootRight
1396
	}
1397

    
1398
	public bool IsFaceTrackingAvailable(ref bool bNeedRestart)
1399
	{
1400
		bNeedRestart = false;
1401
		return true;
1402
	}
1403
	
1404
	public bool InitFaceTracking(bool bUseFaceModel, bool bDrawFaceRect)
1405
	{
1406
		isUseFaceModel = bUseFaceModel;
1407
		isDrawFaceRect = bDrawFaceRect;
1408

    
1409
		int hr = InitFaceTrackingNative();
1410
		if(hr < 0)
1411
		{
1412
			Debug.LogError(string.Format("Error initializing Facetracker: hr=0x{0:X}", hr));
1413
		}
1414

    
1415
		bFaceTrackingInited = (hr >= 0);
1416

    
1417
		return bFaceTrackingInited;
1418
	}
1419
	
1420
	public void FinishFaceTracking()
1421
	{
1422
		FinishFaceTrackingNative();
1423
		bFaceTrackingInited = false;
1424
	}
1425

    
1426
	public bool UpdateFaceTracking()
1427
	{
1428
		int hr = UpdateFaceTrackingNative();
1429
		return (hr >= 0);
1430
	}
1431

    
1432
	public bool IsFaceTrackingActive()
1433
	{
1434
		return bFaceTrackingInited;
1435
	}
1436

    
1437
	public bool IsDrawFaceRect()
1438
	{
1439
		return isDrawFaceRect;
1440
	}
1441
	
1442
	public bool IsFaceTracked(long userId)
1443
	{
1444
		if(GetFaceTrackingIDNative() == userId)
1445
		{
1446
			return IsFaceTrackedNative();
1447
		}
1448

    
1449
		return false;
1450
	}
1451
	
1452
	public bool GetFaceRect(long userId, ref Rect rectFace)
1453
	{
1454
		if(GetFaceTrackingIDNative() == userId)
1455
		{
1456
			if(GetFaceRectNative(ref faceRect))
1457
			{
1458
				rectFace.x = faceRect.x;
1459
				rectFace.y = faceRect.y;
1460
				rectFace.width = faceRect.width;
1461
				rectFace.height = faceRect.height;
1462

    
1463
				return true;
1464
			}
1465
		}
1466
		
1467
		return false;
1468
	}
1469

    
1470
	public void VisualizeFaceTrackerOnColorTex(Texture2D texColor)
1471
	{
1472
		if(bFaceTrackingInited)
1473
		{
1474
			Rect faceRect = new Rect();
1475

    
1476
			if(GetFaceRect(GetFaceTrackingIDNative(), ref faceRect))
1477
			{
1478
				Color color = Color.magenta;
1479
				Vector2 pt1, pt2;
1480
				
1481
				// bottom
1482
				pt1.x = faceRect.x; pt1.y = faceRect.y;
1483
				pt2.x = faceRect.x + faceRect.width - 1; pt2.y = pt1.y;
1484
				DrawLine(texColor, pt1, pt2, color);
1485
				
1486
				// right
1487
				pt1.x = pt2.x; pt1.y = pt2.y;
1488
				pt2.x = pt1.x; pt2.y = faceRect.y + faceRect.height - 1;
1489
				DrawLine(texColor, pt1, pt2, color);
1490
				
1491
				// top
1492
				pt1.x = pt2.x; pt1.y = pt2.y;
1493
				pt2.x = faceRect.x; pt2.y = pt1.y;
1494
				DrawLine(texColor, pt1, pt2, color);
1495
				
1496
				// left
1497
				pt1.x = pt2.x; pt1.y = pt2.y;
1498
				pt2.x = pt1.x; pt2.y = faceRect.y;
1499
				DrawLine(texColor, pt1, pt2, color);
1500
			}
1501
		}
1502
	}
1503

    
1504
	private void DrawLine(Texture2D a_Texture, Vector2 ptStart, Vector2 ptEnd, Color a_Color)
1505
	{
1506
//		int width = a_Texture.width;
1507
//		int height = a_Texture.height;
1508
//		
1509
//		KinectInterop.DrawLine(a_Texture, width - (int)ptStart.x, height - (int)ptStart.y, 
1510
//		    width - (int)ptEnd.x, height - (int)ptEnd.y, a_Color);
1511
		KinectInterop.DrawLine(a_Texture, (int)ptStart.x, (int)ptStart.y, (int)ptEnd.x, (int)ptEnd.y, a_Color);
1512
	}
1513

    
1514
	public bool GetHeadPosition(long userId, ref Vector3 headPos)
1515
	{
1516
		if(GetFaceTrackingIDNative() == userId)
1517
		{
1518
			if(GetHeadPositionNative(ref vHeadPos))
1519
			{
1520
				headPos = vHeadPos;
1521
				return true;
1522
			}
1523
		}
1524
		
1525
		return false;
1526
	}
1527
	
1528
	public bool GetHeadRotation(long userId, ref Quaternion headRot)
1529
	{
1530
		if(GetFaceTrackingIDNative() == userId)
1531
		{
1532
			if(GetHeadRotationNative(ref vHeadRot))
1533
			{
1534
				headRot = Quaternion.Euler((Vector3)vHeadRot);
1535
				return true;
1536
			}
1537
		}
1538
		
1539
		return false;
1540
	}
1541

    
1542
	public bool GetAnimUnits(long userId, ref Dictionary<KinectInterop.FaceShapeAnimations, float> dictAU)
1543
	{
1544
		if(isUseFaceModel && dictAU != null && GetFaceTrackingIDNative() == userId)
1545
		{
1546
			int iAUCount = GetAnimUnitsCountNative();
1547

    
1548
			if(afAU == null || afAU.Length == 0)
1549
			{
1550
				afAU = new float[iAUCount];
1551
			}
1552

    
1553
			var pArrayData = GCHandle.Alloc(afAU, GCHandleType.Pinned);
1554
			bool bSuccess = GetAnimUnitsNative(pArrayData.AddrOfPinnedObject(), ref iAUCount);
1555
			pArrayData.Free();
1556

    
1557
			if(iAUCount >= 6)
1558
			{
1559
				//Debug.Log(string.Format("0:{0:F2} | 1:{1:F2} | 2:{2:F2} | 3:{3:F2} | 4:{4:F2} | 5:{5:F2}", afAU[0], afAU[1], afAU[2], afAU[3], afAU[4], afAU[5]));
1560

    
1561
				dictAU[KinectInterop.FaceShapeAnimations.LipPucker] = afAU[0];  // AU0 - Upper Lip Raiser
1562
				dictAU[KinectInterop.FaceShapeAnimations.JawOpen] = afAU[1];  // AU1 - Jaw Lowerer
1563

    
1564
				dictAU[KinectInterop.FaceShapeAnimations.LipStretcherLeft] = afAU[2];  // AU2 – Lip Stretcher
1565
				dictAU[KinectInterop.FaceShapeAnimations.LipStretcherRight] = afAU[2];  // AU2 – Lip Stretcher
1566

    
1567
				dictAU[KinectInterop.FaceShapeAnimations.LefteyebrowLowerer] = afAU[3] - afAU[5];  // AU3 – Brow Lowerer
1568
				dictAU[KinectInterop.FaceShapeAnimations.RighteyebrowLowerer] = afAU[3] - afAU[5];  // AU3 – Brow Lowerer
1569

    
1570
				dictAU[KinectInterop.FaceShapeAnimations.LipCornerDepressorLeft] = afAU[4];  // AU4 – Lip Corner Depressor
1571
				dictAU[KinectInterop.FaceShapeAnimations.LipCornerDepressorRight] = afAU[4];  // AU4 – Lip Corner Depressor
1572

    
1573
				if(iAUCount >= 7)
1574
				{
1575
					dictAU[KinectInterop.FaceShapeAnimations.LefteyeClosed] = afAU[6];  // AU6, AU7 – Eyelid closed
1576
					dictAU[KinectInterop.FaceShapeAnimations.RighteyeClosed] = afAU[6];  // AU6, AU7 – Eyelid closed
1577
				}
1578
			}
1579

    
1580
			return bSuccess;
1581
		}
1582

    
1583
		return false;
1584
	}
1585
	
1586
	public bool GetShapeUnits(long userId, ref Dictionary<KinectInterop.FaceShapeDeformations, float> dictSU)
1587
	{
1588
		if(isUseFaceModel && dictSU != null && GetFaceTrackingIDNative() == userId)
1589
		{
1590
			int iSUCount = GetShapeUnitsCountNative();
1591
			
1592
			if(afSU == null || afSU.Length == 0)
1593
			{
1594
				afSU = new float[iSUCount];
1595
			}
1596
			
1597
			var pArrayData = GCHandle.Alloc(afSU, GCHandleType.Pinned);
1598
			bool bSuccess = GetShapeUnitsNative(pArrayData.AddrOfPinnedObject(), ref iSUCount);
1599
			pArrayData.Free();
1600

    
1601
			if(iSUCount >= 11)
1602
			{
1603
				// here we must convert the old SUs to the new ones, but there is no info about this kind of conversation
1604
			}
1605
			
1606
			return bSuccess;
1607
		}
1608
		
1609
		return false;
1610
	}
1611
	
1612
	public int GetFaceModelVerticesCount(long userId)
1613
	{
1614
		if(isUseFaceModel && GetFaceTrackingIDNative() == userId || userId == 0)
1615
		{
1616
			return GetModelPointsCountNative();
1617
		}
1618

    
1619
		return 0;
1620
	}
1621
	
1622
	public bool GetFaceModelVertices(long userId, ref Vector3[] avVertices)
1623
	{
1624
		if(isUseFaceModel && avVertices != null && (GetFaceTrackingIDNative() == userId || userId == 0))
1625
		{
1626
			int iPointsCount = avVertices.Length;
1627
			
1628
			var pArrayData = GCHandle.Alloc(avVertices, GCHandleType.Pinned);
1629
			bool bSuccess = GetModelPointsNative(pArrayData.AddrOfPinnedObject(), ref iPointsCount);
1630
			pArrayData.Free();
1631

    
1632
//			for(int i = 0; i < avVertices.Length; i++)
1633
//			{
1634
//				avVertices[i].z = -avVertices[i].z;
1635
//			}
1636
			
1637
			return bSuccess;
1638
		}
1639
		
1640
		return false;
1641
	}
1642
	
1643
	public int GetFaceModelTrianglesCount()
1644
	{
1645
		return isUseFaceModel ? GetTriangleCountNative() : 0;
1646
	}
1647
	
1648
	public bool GetFaceModelTriangles(bool bMirrored, ref int[] avTriangles)
1649
	{
1650
		if(isUseFaceModel && avTriangles != null)
1651
		{
1652
			int iTriangleCount = avTriangles.Length;
1653
			
1654
			var pArrayData = GCHandle.Alloc(avTriangles, GCHandleType.Pinned);
1655
			bool bSuccess = GetTrianglesNative(pArrayData.AddrOfPinnedObject(), ref iTriangleCount);
1656
			pArrayData.Free();
1657
			
1658
			if(bMirrored)
1659
			{
1660
				Array.Reverse(avTriangles);
1661
			}
1662
			
1663
			return bSuccess;
1664
		}
1665
		
1666
		return false;
1667
	}
1668

    
1669
	public bool IsSpeechRecognitionAvailable(ref bool bNeedRestart)
1670
	{
1671
		bNeedRestart = false;
1672
		return true;
1673
	}
1674
	
1675
	public int InitSpeechRecognition(string sRecoCriteria, bool bUseKinect, bool bAdaptationOff)
1676
	{
1677
		return InitSpeechRecognizerNative(sRecoCriteria, bUseKinect, bAdaptationOff);
1678
	}
1679
	
1680
	public void FinishSpeechRecognition()
1681
	{
1682
		FinishSpeechRecognizerNative();
1683
	}
1684
	
1685
	public int UpdateSpeechRecognition()
1686
	{
1687
		return UpdateSpeechRecognizerNative();
1688
	}
1689
	
1690
	public int LoadSpeechGrammar(string sFileName, short iLangCode, bool bDynamic)
1691
	{
1692
		return LoadSpeechGrammarNative(sFileName, iLangCode, bDynamic);
1693
	}
1694
	
1695
	public int AddGrammarPhrase(string sFromRule, string sToRule, string sPhrase, bool bClearRulePhrases, bool bCommitGrammar)
1696
	{
1697
		return AddGrammarPhraseNative(sFromRule, sToRule, sPhrase, bClearRulePhrases, bCommitGrammar);
1698
	}
1699
	
1700
	public void SetSpeechConfidence(float fConfidence)
1701
	{
1702
		SetSpeechConfidenceNative(fConfidence);
1703
	}
1704
	
1705
	public bool IsSpeechStarted()
1706
	{
1707
		return IsSpeechStartedNative();
1708
	}
1709
	
1710
	public bool IsSpeechEnded()
1711
	{
1712
		return IsSpeechEndedNative();
1713
	}
1714
	
1715
	public bool IsPhraseRecognized()
1716
	{
1717
		return IsPhraseRecognizedNative();
1718
	}
1719
	
1720
	public float GetPhraseConfidence()
1721
	{
1722
		return GetPhraseConfidenceNative();
1723
	}
1724
	
1725
	public string GetRecognizedPhraseTag()
1726
	{
1727
		IntPtr pPhraseTag = GetRecognizedPhraseTagNative();
1728
		string sPhraseTag = Marshal.PtrToStringUni(pPhraseTag);
1729
		
1730
		return sPhraseTag;
1731
	}
1732
	
1733
	public void ClearRecognizedPhrase()
1734
	{
1735
		ClearRecognizedPhraseNative();
1736
	}
1737
	
1738
	public bool IsBackgroundRemovalAvailable(ref bool bNeedRestart)
1739
	{
1740
		bNeedRestart = false;
1741
		return true;
1742
	}
1743
	
1744
	public bool InitBackgroundRemoval(KinectInterop.SensorData sensorData, bool isHiResPrefered)
1745
	{
1746
		int hr = InitBackgroundRemovalNative();
1747

    
1748
		if(hr < 0)
1749
		{
1750
			Debug.LogError(string.Format("Error initializing BackgroundRemoval: hr=0x{0:X}", hr));
1751
		}
1752

    
1753
		bBackgroundRemovalInited = (hr >= 0);
1754

    
1755
		return bBackgroundRemovalInited;
1756
	}
1757
	
1758
	public void FinishBackgroundRemoval(KinectInterop.SensorData sensorData)
1759
	{
1760
		FinishBackgroundRemovalNative();
1761
		bBackgroundRemovalInited = false;
1762
	}
1763
	
1764
	public bool UpdateBackgroundRemoval(KinectInterop.SensorData sensorData, bool isHiResPrefered, Color32 defaultColor, bool bAlphaTexOnly)
1765
	{
1766
		int hr = UpdateBackgroundRemovalNative();
1767
		return (hr >= 0);
1768
	}
1769

    
1770
	public bool IsBackgroundRemovalActive()
1771
	{
1772
		return bBackgroundRemovalInited;
1773
	}
1774

    
1775
	public bool IsBRHiResSupported()
1776
	{
1777
		return false;
1778
	}
1779
	
1780
	public Rect GetForegroundFrameRect(KinectInterop.SensorData sensorData, bool isHiResPrefered)
1781
	{
1782
		return new Rect(0f, 0f, sensorData.depthImageWidth, sensorData.depthImageHeight);
1783
	}
1784
	
1785
	public int GetForegroundFrameLength(KinectInterop.SensorData sensorData, bool isHiResPrefered)
1786
	{
1787
		return GetBackgroundRemovalFrameLengthNative();
1788
	}
1789
	
1790
	public bool PollForegroundFrame(KinectInterop.SensorData sensorData, bool isHiResPrefered, Color32 defaultColor, bool bLimitedUsers, ICollection<int> alTrackedIndexes, ref byte[] foregroundImage)
1791
	{
1792
		uint frameLen = (uint)foregroundImage.Length;
1793
		
1794
		var pFrameData = GCHandle.Alloc(foregroundImage, GCHandleType.Pinned);
1795
		bool newFrame = GetBackgroundRemovalFrameDataNative(pFrameData.AddrOfPinnedObject(), ref frameLen, true);
1796
		pFrameData.Free();
1797
		
1798
		return newFrame;
1799
	}
1800

    
1801
}