프로젝트

일반

사용자정보

통계
| 개정판:

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

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

1 3 KTH
#if UNITY_WSA_10_0 && NETFX_CORE
2
using UnityEngine;
3
using System.Collections;
4
5
using MultiK2;
6
using System;
7
using System.Threading;
8
using System.Threading.Tasks;
9
using System.Runtime.InteropServices;
10
using System.Runtime.InteropServices.WindowsRuntime;
11
using Windows.UI.Xaml.Media.Imaging;
12
using Windows.Graphics.Imaging;
13
using MultiK2.Tracking;
14
using Windows.Media.Capture.Frames;
15
using Windows.Media.SpeechRecognition;
16
17
18
public class Kinect2UwpInterface : DepthSensorInterface
19
{
20
    private KinectInterop.SensorData sensorData;
21
    private KinectInterop.FrameSource sensorFlags;
22
23
    private Sensor _kinectSensor;
24
    private ColorFrameReader _colorReader;
25
    private DepthFrameReader _depthReader;
26
    private BodyIndexFrameReader _bodyIndexReader;
27
    private BodyFrameReader _bodyReader;
28
29
    private CameraIntrinsics _colorCameraIntrinsics;
30
    private CameraIntrinsics _depthCameraIntrinsics;
31
    private CoordinateMapper _coordinateMapper;
32
    private CoordinateMapper2 _coordinateMapper2;
33
34
    private SpeechRecognizer speechRecognizer;
35
    private Task<SpeechRecognitionResult> speechRecognizeTask;
36
    private float requiredPhraseConfidence = 0f;
37
38
    private bool isPhraseRecognized;
39
    private string recognizedPhraseTag;
40
    private float recognizedPhraseConfidence;
41
42
    private byte[] _colorDataBuf = null;
43
    private bool _colorDataReady = false;
44
    private long _colorDataTime = 0;
45
    private object _colorDataLock = new object();
46
47
    private byte[] _depthDataBuf = null;
48
    private bool _depthDataReady = false;
49
    private long _depthDataTime = 0;
50
    private object _depthDataLock = new object();
51
52
    private byte[] _bodyIndexDataBuf = null;
53
    private bool _bodyIndexDataReady = false;
54
    private long _bodyIndexDataTime = 0;
55
    private object _bodyIndexDataLock = new object();
56
57
    private BodyFrame _bodyFrame = null;
58
    private bool _bodyFrameReady = false;
59
    private long _bodyFrameTime = 0;
60
    private object _bodyFrameLock = new object();
61
62
    private bool _isDoubleDepthBufNeeded = false;
63
    private ushort[] _lastDepthDataBuf = null;
64
    private long _lastDepthDataTime = 0;
65
66
    private bool _depth2spaceTaskStarted = false;
67
    //private bool _depth2colorTaskStarted = false;
68
    //private bool _color2depthTaskStarted = false;
69
70
    private bool _saveLatestFrames = false;
71
    private bool _clearLatestFrames = false;
72
73
    private MediaFrameReference _latestColorFrame = null;
74
    private MediaFrameReference _latestDepthFrame = null;
75
    private MediaFrameReference _latestBodyIndexFrame = null;
76
    private MediaFrameReference _latestBodyFrame = null;
77
    private MediaFrameReference _latestInfraredFrame = null;
78
79
    private System.Numerics.Vector3[] _color2SpacePoints = null;
80
    //private float[] _color2depthDepth = null;
81
82
    private Vector3[] _depth2SpaceTable = null;
83
84
    private ComputeShader _coordMapperShader = null;
85
    private int _depth2colorKernel = 0;
86
    private int _color2depthKernel = 0;
87
88
    private ComputeBuffer _depthPlaneCoordsBuf = null;
89
    private ComputeBuffer _depthDepthValuesBuf = null;
90
    private ComputeBuffer _colorPlaneCoordsBuf = null;
91
    private ComputeBuffer _colorSpaceCoordsBuf = null;
92
    private ComputeBuffer _colorDepthCoordsBuf = null;
93
94
    private bool _backgroundRemovalInited = false;
95
96
97
    public KinectInterop.DepthSensorPlatform GetSensorPlatform()
98
    {
99
        return KinectInterop.DepthSensorPlatform.KinectUWPv2;
100
    }
101
102
    public bool InitSensorInterface(bool bCopyLibs, ref bool bNeedRestart)
103
    {
104
        bNeedRestart = false;
105
        return true;
106
    }
107
108
    public void FreeSensorInterface(bool bDeleteLibs)
109
    {
110
    }
111
112
    public bool IsSensorAvailable()
113
    {
114
        return true;
115
    }
116
117
    public int GetSensorsCount()
118
    {
119
        return 1;
120
    }
121
122
    public KinectInterop.SensorData OpenDefaultSensor(KinectInterop.FrameSource dwFlags, float sensorAngle, bool bUseMultiSource)
123
    {
124
        if (sensorData == null)
125
        {
126
            sensorData = new KinectInterop.SensorData();
127
        }
128
129
        sensorFlags = dwFlags;
130
131
        sensorData.bodyCount = 6;
132
        sensorData.jointCount = 25;
133
134
        sensorData.depthCameraFOV = 60f;
135
        sensorData.colorCameraFOV = 53.8f;
136
        sensorData.depthCameraOffset = 0f;
137
        sensorData.faceOverlayOffset = 0f;
138
139
        // by-default image widths & heights
140
        sensorData.colorImageWidth = 1920;
141
        sensorData.colorImageHeight = 1080;
142
143
        sensorData.depthImageWidth = 512;
144
        sensorData.depthImageHeight = 424;
145
146
        _saveLatestFrames = bUseMultiSource;
147
148
        Task task = null;
149
//        UnityEngine.WSA.Application.InvokeOnUIThread(() =>
150
//           {
151
               task = InitializeKinect();
152
//           }, true);
153
154
        while (task != null && !task.IsCompleted)
155
        {
156
            task.Wait(100);
157
        }
158
159
        return (_kinectSensor != null && _kinectSensor.IsActive) ? sensorData : null;
160
    }
161
162
    private async Task InitializeKinect()
163
    {
164
        _kinectSensor = await Sensor.GetDefaultAsync();
165
166
        if (_kinectSensor != null)
167
        {
168
            await _kinectSensor.OpenAsync();
169
170
            if ((sensorFlags & KinectInterop.FrameSource.TypeColor) != 0)
171
            {
172
                if (sensorData.colorImage == null)
173
                {
174
                    sensorData.colorImage = new byte[sensorData.colorImageWidth * sensorData.colorImageHeight * 4];
175
                }
176
177
                _colorReader = await _kinectSensor.OpenColorFrameReaderAsync(ReaderConfig.HalfRate | ReaderConfig.HalfResolution);
178
                if (_colorReader != null)
179
                {
180
                    _colorReader.FrameArrived += ColorReader_FrameArrived;
181
                }
182
            }
183
184
            if ((sensorFlags & KinectInterop.FrameSource.TypeDepth) != 0)
185
            {
186
                if (sensorData.depthImage == null)
187
                {
188
                    sensorData.depthImage = new ushort[sensorData.depthImageWidth * sensorData.depthImageHeight];
189
                }
190
191
                _depthReader = await _kinectSensor.OpenDepthFrameReaderAsync();
192
                if (_depthReader != null)
193
                {
194
                    _depthReader.FrameArrived += DepthReader_FrameArrived;
195
                }
196
            }
197
198
            if ((sensorFlags & KinectInterop.FrameSource.TypeBodyIndex) != 0)
199
            {
200
                if (sensorData.bodyIndexImage == null)
201
                {
202
                    sensorData.bodyIndexImage = new byte[sensorData.depthImageWidth * sensorData.depthImageHeight];
203
                }
204
205
                _bodyIndexReader = await _kinectSensor.OpenBodyIndexFrameReaderAsync();
206
                if (_bodyIndexReader != null)
207
                {
208
                    _bodyIndexReader.FrameArrived += BodyIndexReader_FrameArrived;
209
                }
210
            }
211
212
            if ((sensorFlags & KinectInterop.FrameSource.TypeBody) != 0)
213
            {
214
                _bodyReader = await _kinectSensor.OpenBodyFrameReaderAsync();
215
                if (_bodyReader != null)
216
                {
217
                    _bodyReader.FrameArrived += BodyReader_FrameArrived;
218
                }
219
            }
220
221
            // get the coordinate mapper
222
            _coordinateMapper = _kinectSensor.GetCoordinateMapper();
223
            _coordinateMapper2 = new CoordinateMapper2();
224
225
            Debug.Log("UWP-K2 sensor opened");
226
        }
227
        else
228
        {
229
            Debug.Log("UWP-K2 sensor not found");
230
        }
231
    }
232
233
    private void ColorReader_FrameArrived(object sender, ColorFrameArrivedEventArgs e)
234
    {
235
        _colorCameraIntrinsics = e.CameraIntrinsics;
236
237
        if (_colorDataBuf == null || sensorData.colorImageWidth != e.Bitmap.PixelWidth || sensorData.colorImageHeight != e.Bitmap.PixelHeight)
238
        {
239
            sensorData.colorImageWidth = e.Bitmap.PixelWidth;
240
            sensorData.colorImageHeight = e.Bitmap.PixelHeight;
241
242
            int imageLen = e.Bitmap.PixelWidth * e.Bitmap.PixelHeight * 4;
243
244
            lock (_colorDataLock)
245
            {
246
                //_colorDataBuf = new byte[imageLen];
247
                //sensorData.colorImage = new byte[imageLen];
248
                Array.Resize<byte>(ref _colorDataBuf, imageLen);
249
                Array.Resize<byte>(ref sensorData.colorImage, imageLen);
250
            }
251
        }
252
253
        if (_colorDataBuf != null)
254
        {
255
            // convert the bitmap
256
            SoftwareBitmap convertedBitmap = SoftwareBitmap.Convert(e.Bitmap, BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight);
257
258
            lock (_colorDataLock)
259
            {
260
                convertedBitmap?.CopyToBuffer(_colorDataBuf.AsBuffer());
261
                convertedBitmap?.Dispose();
262
263
                if (_saveLatestFrames)
264
                {
265
                    _latestColorFrame = e.Frame;
266
                }
267
268
                _colorDataTime = DateTime.Now.Ticks; // colorFrame.RelativeTime.Ticks;
269
                _colorDataReady = true;
270
            }
271
272
        }
273
    }
274
275
    private void DepthReader_FrameArrived(object sender, DepthFrameArrivedEventArgs e)
276
    {
277
        _depthCameraIntrinsics = e.CameraIntrinsics;
278
279
        if (_depthDataBuf == null || sensorData.depthImageWidth != e.Bitmap.PixelWidth || sensorData.depthImageHeight != e.Bitmap.PixelHeight)
280
        {
281
            sensorData.depthImageWidth = e.Bitmap.PixelWidth;
282
            sensorData.depthImageHeight = e.Bitmap.PixelHeight;
283
284
            int imageLen = e.Bitmap.PixelWidth * e.Bitmap.PixelHeight * sizeof(ushort);
285
286
            lock (_depthDataLock)
287
            {
288
                //_depthDataBuf = new byte[imageLen];
289
                //sensorData.depthImage = new ushort[e.Bitmap.PixelWidth * e.Bitmap.PixelHeight];
290
                Array.Resize<byte>(ref _depthDataBuf, imageLen);
291
                Array.Resize<ushort>(ref sensorData.depthImage, e.Bitmap.PixelWidth * e.Bitmap.PixelHeight);
292
            }
293
294
            int biImageLen = e.Bitmap.PixelWidth * e.Bitmap.PixelHeight;
295
296
            lock (_bodyIndexDataLock)
297
            {
298
                //_bodyIndexDataBuf = new byte[biImageLen];
299
                //sensorData.bodyIndexImage = new byte[biImageLen];
300
                Array.Resize<byte>(ref _bodyIndexDataBuf, biImageLen);
301
                Array.Resize<byte>(ref sensorData.bodyIndexImage, biImageLen);
302
            }
303
        }
304
305
        if (_depthDataBuf != null)
306
        {
307
            lock (_depthDataLock)
308
            {
309
                e.Bitmap.CopyToBuffer(_depthDataBuf.AsBuffer());
310
311
                if (_saveLatestFrames)
312
                {
313
                    _latestDepthFrame = e.Frame;
314
                }
315
316
                _depthDataTime = DateTime.Now.Ticks; // depthFrame.RelativeTime.Ticks;
317
                _depthDataReady = true;
318
            }
319
320
        }
321
    }
322
323
    private void BodyIndexReader_FrameArrived(object sender, BodyIndexFrameArrivedEventArgs e)
324
    {
325
        if (_bodyIndexDataBuf != null)
326
        {
327
            lock (_bodyIndexDataLock)
328
            {
329
                e.Bitmap.CopyToBuffer(_bodyIndexDataBuf.AsBuffer());
330
331
                if (_saveLatestFrames)
332
                {
333
                    _latestBodyIndexFrame = e.Frame;
334
                }
335
336
                _bodyIndexDataTime = DateTime.Now.Ticks; // bodyIndexFrame.RelativeTime.Ticks;
337
                _bodyIndexDataReady = true;
338
            }
339
340
        }
341
    }
342
343
    private void BodyReader_FrameArrived(object sender, BodyFrameArrivedEventArgs e)
344
    {
345
        lock (_bodyFrameLock)
346
        {
347
            _bodyFrame = e.BodyFrame;
348
349
            if (_saveLatestFrames)
350
            {
351
                _latestBodyFrame = e.Frame;
352
            }
353
354
            _bodyFrameTime = DateTime.Now.Ticks; // _bodyFrame.SystemRelativeTime.Value.Ticks;
355
            _bodyFrameReady = true;
356
        }
357
    }
358
359
    public void CloseSensor(KinectInterop.SensorData sensorData)
360
    {
361
//        UnityEngine.WSA.Application.InvokeOnUIThread(() =>
362
//        {
363
            _kinectSensor?.CloseAsync();
364
            Debug.Log("UWP-K2 sensor closed");
365
//        }, true);
366
367
        if (_depthPlaneCoordsBuf != null)
368
        {
369
            _depthPlaneCoordsBuf.Release();
370
            _depthPlaneCoordsBuf = null;
371
        }
372
373
        if (_depthDepthValuesBuf != null)
374
        {
375
            _depthDepthValuesBuf.Release();
376
            _depthDepthValuesBuf = null;
377
        }
378
379
        if (_colorPlaneCoordsBuf != null)
380
        {
381
            _colorPlaneCoordsBuf.Release();
382
            _colorPlaneCoordsBuf = null;
383
        }
384
385
        if (_colorSpaceCoordsBuf != null)
386
        {
387
            _colorSpaceCoordsBuf.Release();
388
            _colorSpaceCoordsBuf = null;
389
        }
390
391
        if (_colorDepthCoordsBuf != null)
392
        {
393
            _colorDepthCoordsBuf.Release();
394
            _colorDepthCoordsBuf = null;
395
        }
396
397
        _colorCameraIntrinsics = null;
398
        _depthCameraIntrinsics = null;
399
        _coordinateMapper = null;
400
        _coordinateMapper2 = null;
401
402
        _coordMapperShader = null;
403
        _lastDepthDataBuf = null;
404
405
        _clearLatestFrames = true;
406
        FreeMultiSourceFrame(sensorData);
407
    }
408
409
    public bool UpdateSensorData(KinectInterop.SensorData sensorData)
410
    {
411
        return true;
412
    }
413
414
    public bool GetMultiSourceFrame(KinectInterop.SensorData sensorData)
415
    {
416
        if (_saveLatestFrames)
417
        {
418
            bool bAllSet =
419
                ((sensorFlags & KinectInterop.FrameSource.TypeColor) == 0 || _latestColorFrame != null) &&
420
                ((sensorFlags & KinectInterop.FrameSource.TypeDepth) == 0 || _latestDepthFrame != null) &&
421
                ((sensorFlags & KinectInterop.FrameSource.TypeBodyIndex) == 0 || _latestBodyIndexFrame != null) &&
422
                ((sensorFlags & KinectInterop.FrameSource.TypeBody) == 0 || _latestBodyFrame != null) &&
423
                ((sensorFlags & KinectInterop.FrameSource.TypeInfrared) == 0 || _latestInfraredFrame != null);
424
425
            return bAllSet;
426
        }
427
428
        return false;
429
    }
430
431
    public void FreeMultiSourceFrame(KinectInterop.SensorData sensorData)
432
    {
433
        if (_clearLatestFrames)
434
        {
435
            lock (_colorDataLock)
436
            {
437
                _latestColorFrame = null;
438
            }
439
440
            lock (_depthDataLock)
441
            {
442
                _latestDepthFrame = null;
443
            }
444
445
            lock (_bodyIndexDataLock)
446
            {
447
                _latestBodyIndexFrame = null;
448
            }
449
450
            lock (_bodyFrameLock)
451
            {
452
                _latestBodyFrame = null;
453
            }
454
455
            _clearLatestFrames = false;
456
        }
457
    }
458
459
    public bool PollBodyFrame(KinectInterop.SensorData sensorData, ref KinectInterop.BodyFrameData bodyFrame, ref Matrix4x4 kinectToWorld, bool bIgnoreJointZ)
460
    {
461
        bool bNewFrame = _bodyFrameReady;
462
463
        if (_bodyFrameReady)
464
        {
465
            lock (_bodyFrameLock)
466
            {
467
                bodyFrame.liPreviousTime = bodyFrame.liRelativeTime;
468
                bodyFrame.liRelativeTime = _bodyFrameTime;
469
470
                if (sensorData.hintHeightAngle)
471
                {
472
                    //// get the floor plane
473
                    //Windows.Kinect.Vector4 vFloorPlane = _bodyFrame.FloorClipPlane;
474
                    //Vector3 floorPlane = new Vector3(vFloorPlane.X, vFloorPlane.Y, vFloorPlane.Z);
475
476
                    //sensorData.sensorRotDetected = Quaternion.FromToRotation(floorPlane, Vector3.up);
477
                    //sensorData.sensorHgtDetected = vFloorPlane.W;
478
                }
479
480
                for (int i = 0; i < sensorData.bodyCount; i++)
481
                {
482
                    Body body = i < _bodyFrame.Bodies.Length ? _bodyFrame.Bodies[i] : null;
483
484
                    if (body == null)
485
                    {
486
                        bodyFrame.bodyData[i].bIsTracked = 0;
487
                        continue;
488
                    }
489
490
                    bodyFrame.bodyData[i].bIsTracked = (short)(body.IsTracked ? 1 : 0);
491
492
                    if (body.IsTracked)
493
                    {
494
                        // transfer body and joints data
495
                        byte[] entityBytes = body.EntityId.ToByteArray();
496
                        bodyFrame.bodyData[i].liTrackingID = BitConverter.ToInt64(entityBytes, 8);
497
498
                        // cache the body joints (following the advice of Brian Chasalow)
499
                        //Dictionary<Windows.Kinect.JointType, Windows.Kinect.Joint> bodyJoints = body.Joints;
500
501
                        // calculate the inter-frame time
502
                        float frameTime = 0f;
503
                        if (bodyFrame.bTurnAnalisys && bodyFrame.liPreviousTime > 0)
504
                        {
505
                            frameTime = (float)(bodyFrame.liRelativeTime - bodyFrame.liPreviousTime) / 100000000000;
506
                        }
507
508
                        for (int j = 0; j < sensorData.jointCount; j++)
509
                        {
510
                            if (j >= body.Joints.Count)
511
                                continue;
512
513
                            MultiK2.Tracking.Joint joint = body.Joints[(MultiK2.Tracking.JointType)j];
514
                            KinectInterop.JointData jointData = bodyFrame.bodyData[i].joint[j];
515
516
                            //jointData.jointType = (KinectInterop.JointType)j;
517
                            jointData.trackingState = (KinectInterop.TrackingState)joint.PositionTrackingState;
518
519
                            if ((int)joint.PositionTrackingState != (int)TrackingState.NotTracked)
520
                            {
521
                                float jPosZ = (bIgnoreJointZ && j > 0) ? bodyFrame.bodyData[i].joint[0].kinectPos.z : joint.Position.Z;
522
                                jointData.kinectPos = new Vector3(joint.Position.X, joint.Position.Y, joint.Position.Z);
523
                                jointData.position = kinectToWorld.MultiplyPoint3x4(new Vector3(joint.Position.X, joint.Position.Y, jPosZ));
524
                            }
525
526
                            jointData.orientation = Quaternion.identity;
527
528
                            if (j == 0)
529
                            {
530
                                bodyFrame.bodyData[i].position = jointData.position;
531
                                bodyFrame.bodyData[i].orientation = jointData.orientation;
532
                            }
533
534
                            bodyFrame.bodyData[i].joint[j] = jointData;
535
                        }
536
537
                        //if (bodyFrame.bTurnAnalisys && bodyFrame.liPreviousTime > 0)
538
                        //{
539
                        //    for (int j = 0; j < sensorData.jointCount; j++)
540
                        //    {
541
                        //        KinectInterop.JointData jointData = bodyFrame.bodyData[i].joint[j];
542
543
                        //        int p = (int)GetParentJoint((KinectInterop.JointType)j);
544
                        //        Vector3 parentPos = bodyFrame.bodyData[i].joint[p].position;
545
546
                        //        jointData.posRel = jointData.position - parentPos;
547
                        //        jointData.posDrv = frameTime > 0f ? (jointData.position - jointData.posPrev) / frameTime : Vector3.zero;
548
                        //        jointData.posPrev = jointData.position;
549
550
                        //        bodyFrame.bodyData[i].joint[j] = jointData;
551
                        //    }
552
                        //}
553
554
                        // tranfer hand states
555
                        bodyFrame.bodyData[i].leftHandState = (KinectInterop.HandState)body.HandStateLeft;
556
                        bodyFrame.bodyData[i].leftHandConfidence = (KinectInterop.TrackingConfidence)body.ConfidenceLeft;
557
558
                        bodyFrame.bodyData[i].rightHandState = (KinectInterop.HandState)body.HandStateRight;
559
                        bodyFrame.bodyData[i].rightHandConfidence = (KinectInterop.TrackingConfidence)body.ConfidenceRight;
560
                    }
561
                }
562
563
                _bodyFrameReady = false;
564
            }
565
        }
566
567
        return bNewFrame;
568
    }
569
570
    public bool PollColorFrame(KinectInterop.SensorData sensorData)
571
    {
572
        bool bNewFrame = _colorDataReady;
573
574
        if (_colorDataReady)
575
        {
576
            lock (_colorDataLock)
577
            {
578
                Buffer.BlockCopy(_colorDataBuf, 0, sensorData.colorImage, 0, _colorDataBuf.Length);
579
                sensorData.lastColorFrameTime = _colorDataTime;
580
                _colorDataReady = false;
581
            }
582
        }
583
584
        return bNewFrame;
585
    }
586
587
    public bool PollDepthFrame(KinectInterop.SensorData sensorData)
588
    {
589
        bool bNewFrame = _depthDataReady || _bodyIndexDataReady;
590
591
        if (_depthDataReady)
592
        {
593
            if (_isDoubleDepthBufNeeded)
594
            {
595
                if (_lastDepthDataBuf == null)
596
                {
597
                    _lastDepthDataBuf = new ushort[sensorData.depthImage.Length];
598
                }
599
600
                Buffer.BlockCopy(sensorData.depthImage, 0, _lastDepthDataBuf, 0, _lastDepthDataBuf.Length * sizeof(ushort));
601
                _lastDepthDataTime = sensorData.lastDepthFrameTime;
602
            }
603
604
            lock (_depthDataLock)
605
            {
606
                Buffer.BlockCopy(_depthDataBuf, 0, sensorData.depthImage, 0, _depthDataBuf.Length);
607
                sensorData.lastDepthFrameTime = _depthDataTime;
608
                _depthDataReady = false;
609
            }
610
        }
611
612
        if (_bodyIndexDataReady)
613
        {
614
            lock (_bodyIndexDataLock)
615
            {
616
                Buffer.BlockCopy(_bodyIndexDataBuf, 0, sensorData.bodyIndexImage, 0, _bodyIndexDataBuf.Length);
617
                sensorData.lastBodyIndexFrameTime = _bodyIndexDataTime;
618
                _bodyIndexDataReady = false;
619
            }
620
        }
621
622
        return bNewFrame;
623
    }
624
625
    public bool PollInfraredFrame(KinectInterop.SensorData sensorData)
626
    {
627
        return false;
628
    }
629
630
    public void FixJointOrientations(KinectInterop.SensorData sensorData, ref KinectInterop.BodyData bodyData)
631
    {
632
    }
633
634
    public bool IsBodyTurned(ref KinectInterop.BodyData bodyData)
635
    {
636
        return false;
637
    }
638
639
    public Vector2 MapSpacePointToDepthCoords(KinectInterop.SensorData sensorData, Vector3 spacePos)
640
    {
641
        Vector2 vPoint = Vector2.zero;
642
643
        if (_depthCameraIntrinsics != null)
644
        {
645
            System.Numerics.Vector3 camPoint = new System.Numerics.Vector3(spacePos.x, spacePos.y, spacePos.z);
646
            System.Numerics.Vector2 depthPoint = _depthCameraIntrinsics.ProjectOntoFrame(camPoint);
647
648
            if (depthPoint.X >= 0 && depthPoint.X < sensorData.depthImageWidth &&
649
               depthPoint.Y >= 0 && depthPoint.Y < sensorData.depthImageHeight)
650
            {
651
                vPoint = new Vector2(depthPoint.X, depthPoint.Y);
652
            }
653
        }
654
655
        return vPoint;
656
    }
657
658
    public Vector3 MapDepthPointToSpaceCoords(KinectInterop.SensorData sensorData, Vector2 depthPos, ushort depthVal)
659
    {
660
        Vector3 vPoint = Vector3.zero;
661
662
        if (_depthCameraIntrinsics != null && depthPos != Vector2.zero)
663
        {
664
            System.Numerics.Vector2 depthPoint = new System.Numerics.Vector2(depthPos.x, depthPos.y);
665
            System.Numerics.Vector3 camPoint = _depthCameraIntrinsics.UnprojectFromFrame(depthPoint, (float)depthVal / 1000f);
666
667
            vPoint = new Vector3(camPoint.X, camPoint.Y, camPoint.Z);
668
        }
669
670
        return vPoint;
671
    }
672
673
    public bool MapDepthFrameToSpaceCoords(KinectInterop.SensorData sensorData, ref Vector3[] vSpaceCoords)
674
    {
675
        _isDoubleDepthBufNeeded = true;
676
677
        if (_depthCameraIntrinsics != null && sensorData.depthImage != null)
678
        {
679
            int depthImageLength = sensorData.depthImageWidth * sensorData.depthImageHeight;
680
681
            if (_depth2SpaceTable == null || _depth2SpaceTable.Length != depthImageLength)
682
            {
683
                _depth2SpaceTable = new Vector3[depthImageLength];
684
685
                for (int dy = 0, di = 0; dy < sensorData.depthImageHeight; dy++)
686
                {
687
                    for (int dx = 0; dx < sensorData.depthImageWidth; dx++)
688
                    {
689
                        System.Numerics.Vector2 depthPoint = new System.Numerics.Vector2(dx, dy);
690
                        System.Numerics.Vector3 camPoint = _depthCameraIntrinsics.UnprojectFromFrame(depthPoint, 1f);
691
692
                        _depth2SpaceTable[di] = new Vector3(camPoint.X, camPoint.Y, camPoint.Z);
693
                        di++;
694
                    }
695
                }
696
            }
697
698
            if (_lastDepthDataBuf != null && !_depth2spaceTaskStarted)
699
            {
700
                _depth2spaceTaskStarted = true;
701
702
                //long timeStamp = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
703
704
                //Task.Run( () => {
705
706
                for (int dy = 0, di = 0; dy < sensorData.depthImageHeight; dy++)
707
                {
708
                    for (int dx = 0; dx < sensorData.depthImageWidth; dx++)
709
                    {
710
                        if (di >= 0 && di < _lastDepthDataBuf.Length &&
711
                            sensorData.depthImage[di] != _lastDepthDataBuf[di])
712
                        {
713
                            if (sensorData.depthImage[di] != 0)
714
                            {
715
                                float depthVal = (float)sensorData.depthImage[di] / 1000f;
716
                                vSpaceCoords[di] = _depth2SpaceTable[di] * depthVal;
717
                            }
718
                            else
719
                            {
720
                                vSpaceCoords[di] = Vector3.zero;
721
                            }
722
                        }
723
724
                        di++;
725
                    }
726
                }
727
728
                _depth2spaceTaskStarted = false;
729
                //});
730
731
                //long timeDuration = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - timeStamp);
732
                //Debug.Log("depth2spaceTask() took " + timeDuration + " ms");
733
            }
734
        }
735
736
        return true;
737
    }
738
739
    public Vector2 MapDepthPointToColorCoords(KinectInterop.SensorData sensorData, Vector2 depthPos, ushort depthVal)
740
    {
741
        Vector2 vPoint = Vector2.zero;
742
743
        if (_coordinateMapper != null && _depthCameraIntrinsics != null && _colorCameraIntrinsics != null && depthPos != Vector2.zero)
744
        {
745
            System.Numerics.Vector2 depthPoint = new System.Numerics.Vector2(depthPos.x, depthPos.y);
746
            System.Numerics.Vector3 depthSpace = _depthCameraIntrinsics.UnprojectFromFrame(depthPoint, (float)depthVal / 1000f);
747
            System.Numerics.Vector3 colorSpace = _coordinateMapper.MapDepthSpacePointToColor(depthSpace);
748
            System.Numerics.Vector2 colorPoint = _colorCameraIntrinsics.ProjectOntoFrame(colorSpace);
749
750
            vPoint = new Vector2(colorPoint.X, colorPoint.Y);
751
        }
752
753
        return vPoint;
754
    }
755
756
    public bool MapDepthFrameToColorCoords(KinectInterop.SensorData sensorData, ref Vector2[] vColorCoords)
757
    {
758
        bool bReadyToMap = //_saveLatestFrames ? (_latestColorFrame != null && _latestDepthFrame != null) :
759
            sensorData.depthImage != null && sensorData.colorImage != null;
760
761
        if (bReadyToMap)
762
        {
763
            if (_coordMapperShader == null || _colorPlaneCoordsBuf == null)
764
            {
765
                CreateCoordMapperShader(sensorData, false);
766
            }
767
768
            if (_coordMapperShader)
769
            {
770
                //long timeStamp = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
771
772
                int depthImageLength = sensorData.depthImageWidth * sensorData.depthImageHeight;
773
                int[] depthDepthValues = new int[depthImageLength];
774
775
                for (int di = 0; di < depthImageLength; di++)
776
                {
777
                    depthDepthValues[di] = sensorData.depthImage[di];
778
                }
779
780
                _depthDepthValuesBuf.SetData(depthDepthValues);
781
782
                _coordMapperShader.Dispatch(_depth2colorKernel, depthImageLength / 64, 1, 1);
783
784
                if (vColorCoords == null || vColorCoords.Length != depthImageLength)
785
                {
786
                    vColorCoords = new Vector2[depthImageLength];
787
                }
788
789
                _colorPlaneCoordsBuf.GetData(vColorCoords);
790
791
                //long timeDuration = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - timeStamp);
792
                //Debug.Log("depth2colorTask() took " + timeDuration + " ms");
793
            }
794
795
            _clearLatestFrames = true;
796
        }
797
798
        return true;
799
    }
800
801
    private bool CreateCoordMapperShader(KinectInterop.SensorData sensorData, bool bColor2Depth)
802
    {
803
        if (_depthCameraIntrinsics == null || _colorCameraIntrinsics == null || _coordinateMapper == null)
804
            return false;
805
806
        System.Numerics.Matrix4x4? matrix = !bColor2Depth ? _coordinateMapper.DepthToColorMatrix : _coordinateMapper.ColorToDepthMatrix;
807
        if (_coordMapperShader == null)
808
        {
809
            _coordMapperShader = matrix.HasValue ? Resources.Load("CoordMapper") as ComputeShader : null;
810
        }
811
812
        if (_coordMapperShader)
813
        {
814
            _depth2colorKernel = _coordMapperShader.FindKernel("MapDepthFrame2ColorFrame");
815
            _color2depthKernel = _coordMapperShader.FindKernel("MapColorSpace2DepthFrame");
816
817
            float[] depthFocalLength = new float[] { _depthCameraIntrinsics.FocalLengthX, _depthCameraIntrinsics.FocalLengthY };
818
            float[] depthPrincipalPoint = new float[] { _depthCameraIntrinsics.PrincipalPointX, _depthCameraIntrinsics.PrincipalPointY };
819
            float[] depthRadialDistortion = new float[] { _depthCameraIntrinsics.RadialDistortionSecondOrder, _depthCameraIntrinsics.RadialDistortionFourthOrder, _depthCameraIntrinsics.RadialDistortionSixthOrder };
820
821
            _coordMapperShader.SetFloats("depthFocalLength", depthFocalLength);
822
            _coordMapperShader.SetFloats("depthPrincipalPoint", depthPrincipalPoint);
823
            _coordMapperShader.SetFloats("depthRadialDistortion", depthRadialDistortion);
824
825
            float[] colorFocalLength = new float[] { _colorCameraIntrinsics.FocalLengthX, _colorCameraIntrinsics.FocalLengthY };
826
            float[] colorPrincipalPoint = new float[] { _colorCameraIntrinsics.PrincipalPointX, _colorCameraIntrinsics.PrincipalPointY };
827
            float[] colorRadialDistortion = new float[] { _colorCameraIntrinsics.RadialDistortionSecondOrder, _colorCameraIntrinsics.RadialDistortionFourthOrder, _colorCameraIntrinsics.RadialDistortionSixthOrder };
828
829
            _coordMapperShader.SetFloats("colorFocalLength", colorFocalLength);
830
            _coordMapperShader.SetFloats("colorPrincipalPoint", colorPrincipalPoint);
831
            _coordMapperShader.SetFloats("colorRadialDistortion", colorRadialDistortion);
832
833
            float[] space2spaceMat = new float[] {
834
                    matrix.Value.M11, matrix.Value.M12, matrix.Value.M13, matrix.Value.M14,
835
                    matrix.Value.M21, matrix.Value.M22, matrix.Value.M23, matrix.Value.M24,
836
                    matrix.Value.M31, matrix.Value.M32, matrix.Value.M33, matrix.Value.M34,
837
                    matrix.Value.M41, matrix.Value.M42, matrix.Value.M43, matrix.Value.M44
838
                };
839
840
            if (!bColor2Depth)
841
            {
842
                _coordMapperShader.SetFloats("depth2colorMat", space2spaceMat);
843
            }
844
            else
845
            {
846
                _coordMapperShader.SetFloats("color2depthMat", space2spaceMat);
847
            }
848
849
            // compute buffers
850
            int depthImageLength = sensorData.depthImageWidth * sensorData.depthImageHeight;
851
852
            if(_depthDepthValuesBuf == null)
853
            {
854
                _depthDepthValuesBuf = new ComputeBuffer(depthImageLength, sizeof(int));
855
                _coordMapperShader.SetBuffer(_depth2colorKernel, "depthDepthValues", _depthDepthValuesBuf);
856
            }
857
858
            if (!bColor2Depth)
859
            {
860
                _depthPlaneCoordsBuf = new ComputeBuffer(depthImageLength, 2 * sizeof(float));
861
                _colorPlaneCoordsBuf = new ComputeBuffer(depthImageLength, 2 * sizeof(float));
862
863
                // set plane coords
864
                Vector2[] depthPlaneCoords = new Vector2[depthImageLength];
865
                for (int dy = 0, di = 0; dy < sensorData.depthImageHeight; dy++)
866
                {
867
                    for (int dx = 0; dx < sensorData.depthImageWidth; dx++)
868
                    {
869
                        depthPlaneCoords[di] = new Vector2(dx, dy);
870
                        di++;
871
                    }
872
                }
873
874
                _depthPlaneCoordsBuf.SetData(depthPlaneCoords);
875
                _coordMapperShader.SetBuffer(_depth2colorKernel, "depthPlaneCoords", _depthPlaneCoordsBuf);
876
                _coordMapperShader.SetBuffer(_depth2colorKernel, "colorPlaneCoords", _colorPlaneCoordsBuf);
877
            }
878
            else
879
            {
880
                int colorImageLength = sensorData.colorImageWidth * sensorData.colorImageHeight;
881
882
                _colorSpaceCoordsBuf = new ComputeBuffer(colorImageLength, 3 * sizeof(float));
883
                _colorDepthCoordsBuf = new ComputeBuffer(colorImageLength, 2 * sizeof(float));
884
885
                _coordMapperShader.SetBuffer(_color2depthKernel, "colorSpaceCoords", _colorSpaceCoordsBuf);
886
                _coordMapperShader.SetBuffer(_color2depthKernel, "colorDepthCoords", _colorDepthCoordsBuf);
887
            }
888
        }
889
890
        return (_coordMapperShader != null);
891
    }
892
893
    public bool MapColorFrameToDepthCoords(KinectInterop.SensorData sensorData, ref Vector2[] vDepthCoords)
894
    {
895
        if (_coordMapperShader == null || _colorDepthCoordsBuf == null)
896
        {
897
            CreateCoordMapperShader(sensorData, true);
898
        }
899
900
        bool bReadyToMap = _saveLatestFrames ? (_latestColorFrame != null && _latestDepthFrame != null && _latestBodyFrame != null) :
901
            sensorData.depthImage != null && sensorData.colorImage != null;
902
903
        if (bReadyToMap)
904
        {
905
            //long timeStamp = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
906
907
            if (_coordMapperShader && _coordinateMapper2 != null &&
908
                _coordinateMapper2.MapColorFrameToDepthSpace(_latestColorFrame, _latestDepthFrame, ref _color2SpacePoints))
909
            {
910
                //long timeDuration = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - timeStamp);
911
                //Debug.Log("mapColorFrameToDepthSpace() took " + timeDuration + " ms");
912
913
                int pointArrayLength = _color2SpacePoints.Length;
914
915
                //timeStamp = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
916
917
                _colorSpaceCoordsBuf.SetData(_color2SpacePoints);
918
                //_coordMapperShader.SetBuffer(_color2depthKernel, "colorSpaceCoords", _colorSpaceCoordsBuf);
919
920
                _coordMapperShader.Dispatch(_color2depthKernel, pointArrayLength / 64, 1, 1);
921
922
                if (vDepthCoords == null || vDepthCoords.Length != pointArrayLength)
923
                {
924
                    vDepthCoords = new Vector2[pointArrayLength];
925
                }
926
927
                _colorDepthCoordsBuf.GetData(vDepthCoords);
928
929
                //timeDuration = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - timeStamp);
930
                //Debug.Log("color2DepthTask() took " + timeDuration + " ms");
931
            }
932
933
            _clearLatestFrames = true;
934
        }
935
936
        return true;
937
	}
938
939
	public int GetJointIndex (KinectInterop.JointType joint)
940
	{
941
		return (int)joint;
942
	}
943
944
	public KinectInterop.JointType GetParentJoint (KinectInterop.JointType joint)
945
	{
946
		switch(joint)
947
		{
948
		case KinectInterop.JointType.SpineBase:
949
			return KinectInterop.JointType.SpineBase;
950
951
		case KinectInterop.JointType.Neck:
952
			return KinectInterop.JointType.SpineShoulder;
953
954
		case KinectInterop.JointType.SpineShoulder:
955
			return KinectInterop.JointType.SpineMid;
956
957
		case KinectInterop.JointType.ShoulderLeft:
958
		case KinectInterop.JointType.ShoulderRight:
959
			return KinectInterop.JointType.SpineShoulder;
960
961
		case KinectInterop.JointType.HipLeft:
962
		case KinectInterop.JointType.HipRight:
963
			return KinectInterop.JointType.SpineBase;
964
965
		case KinectInterop.JointType.HandTipLeft:
966
			return KinectInterop.JointType.HandLeft;
967
968
		case KinectInterop.JointType.ThumbLeft:
969
			return KinectInterop.JointType.WristLeft;
970
971
		case KinectInterop.JointType.HandTipRight:
972
			return KinectInterop.JointType.HandRight;
973
974
		case KinectInterop.JointType.ThumbRight:
975
			return KinectInterop.JointType.WristRight;
976
		}
977
978
		return (KinectInterop.JointType)((int)joint - 1);
979
	}
980
981
	public KinectInterop.JointType GetNextJoint (KinectInterop.JointType joint)
982
	{
983
		switch(joint)
984
		{
985
		case KinectInterop.JointType.SpineBase:
986
			return KinectInterop.JointType.SpineMid;
987
		case KinectInterop.JointType.SpineMid:
988
			return KinectInterop.JointType.SpineShoulder;
989
		case KinectInterop.JointType.SpineShoulder:
990
			return KinectInterop.JointType.Neck;
991
		case KinectInterop.JointType.Neck:
992
			return KinectInterop.JointType.Head;
993
994
		case KinectInterop.JointType.ShoulderLeft:
995
			return KinectInterop.JointType.ElbowLeft;
996
		case KinectInterop.JointType.ElbowLeft:
997
			return KinectInterop.JointType.WristLeft;
998
		case KinectInterop.JointType.WristLeft:
999
			return KinectInterop.JointType.HandLeft;
1000
		case KinectInterop.JointType.HandLeft:
1001
			return KinectInterop.JointType.HandTipLeft;
1002
1003
		case KinectInterop.JointType.ShoulderRight:
1004
			return KinectInterop.JointType.ElbowRight;
1005
		case KinectInterop.JointType.ElbowRight:
1006
			return KinectInterop.JointType.WristRight;
1007
		case KinectInterop.JointType.WristRight:
1008
			return KinectInterop.JointType.HandRight;
1009
		case KinectInterop.JointType.HandRight:
1010
			return KinectInterop.JointType.HandTipRight;
1011
1012
		case KinectInterop.JointType.HipLeft:
1013
			return KinectInterop.JointType.KneeLeft;
1014
		case KinectInterop.JointType.KneeLeft:
1015
			return KinectInterop.JointType.AnkleLeft;
1016
		case KinectInterop.JointType.AnkleLeft:
1017
			return KinectInterop.JointType.FootLeft;
1018
1019
		case KinectInterop.JointType.HipRight:
1020
			return KinectInterop.JointType.KneeRight;
1021
		case KinectInterop.JointType.KneeRight:
1022
			return KinectInterop.JointType.AnkleRight;
1023
		case KinectInterop.JointType.AnkleRight:
1024
			return KinectInterop.JointType.FootRight;
1025
		}
1026
1027
		return joint;  // in case of end joint - Head, HandTipLeft, HandTipRight, FootLeft, FootRight
1028
	}
1029
1030
	public bool IsFaceTrackingAvailable (ref bool bNeedRestart)
1031
	{
1032
		return false;
1033
	}
1034
1035
	public bool InitFaceTracking (bool bUseFaceModel, bool bDrawFaceRect)
1036
	{
1037
		return false;
1038
	}
1039
1040
	public void FinishFaceTracking ()
1041
	{
1042
	}
1043
1044
	public bool UpdateFaceTracking ()
1045
	{
1046
		return false;
1047
	}
1048
1049
	public bool IsFaceTrackingActive ()
1050
	{
1051
		return false;
1052
	}
1053
1054
	public bool IsDrawFaceRect ()
1055
	{
1056
		return false;
1057
	}
1058
1059
	public bool IsFaceTracked (long userId)
1060
	{
1061
		return false;
1062
	}
1063
1064
	public bool GetFaceRect (long userId, ref Rect faceRect)
1065
	{
1066
		return false;
1067
	}
1068
1069
	public void VisualizeFaceTrackerOnColorTex (Texture2D texColor)
1070
	{
1071
	}
1072
1073
	public bool GetHeadPosition (long userId, ref Vector3 headPos)
1074
	{
1075
		return false;
1076
	}
1077
1078
	public bool GetHeadRotation (long userId, ref Quaternion headRot)
1079
	{
1080
		return false;
1081
	}
1082
1083
	public bool GetAnimUnits (long userId, ref System.Collections.Generic.Dictionary<KinectInterop.FaceShapeAnimations, float> afAU)
1084
	{
1085
		return false;
1086
	}
1087
1088
	public bool GetShapeUnits (long userId, ref System.Collections.Generic.Dictionary<KinectInterop.FaceShapeDeformations, float> afSU)
1089
	{
1090
		return false;
1091
	}
1092
1093
	public int GetFaceModelVerticesCount (long userId)
1094
	{
1095
		return 0;
1096
	}
1097
1098
	public bool GetFaceModelVertices (long userId, ref Vector3[] avVertices)
1099
	{
1100
		return false;
1101
	}
1102
1103
	public int GetFaceModelTrianglesCount ()
1104
	{
1105
		return 0;
1106
	}
1107
1108
	public bool GetFaceModelTriangles (bool bMirrored, ref int[] avTriangles)
1109
	{
1110
		return false;
1111
	}
1112
1113
	public bool IsSpeechRecognitionAvailable (ref bool bNeedRestart)
1114
	{
1115
		return true;
1116
	}
1117
1118
	public int InitSpeechRecognition (string sRecoCriteria, bool bUseKinect, bool bAdaptationOff)
1119
	{
1120
        speechRecognizer = new SpeechRecognizer();
1121
        return 0;
1122
	}
1123
1124
	public void FinishSpeechRecognition ()
1125
	{
1126
        if(speechRecognizer != null)
1127
        {
1128
            speechRecognizer.Dispose();
1129
            speechRecognizer = null;
1130
        }
1131
    }
1132
1133
	public int UpdateSpeechRecognition ()
1134
	{
1135
        if(speechRecognizer != null)
1136
        {
1137
            if(speechRecognizeTask == null)
1138
            {
1139
//                UnityEngine.WSA.Application.InvokeOnUIThread(() =>
1140
//                {
1141
                    speechRecognizeTask = RecognizeSpeechAsync();
1142
//                }, true);
1143
            }
1144
1145
            if (speechRecognizeTask != null)
1146
            {
1147
                // check for error
1148
                if (speechRecognizeTask.IsFaulted)
1149
                {
1150
                    Debug.LogError("RecognizeSpeechAsync() has faulted.");
1151
                    if (speechRecognizeTask.Exception != null)
1152
                        Debug.LogError(speechRecognizeTask.Exception);
1153
1154
                    speechRecognizeTask = null;
1155
                }
1156
                else if(speechRecognizeTask.IsCanceled)
1157
                {
1158
                    speechRecognizeTask = null;
1159
                }
1160
                else if(speechRecognizeTask.IsCompleted)
1161
                {
1162
                    SpeechRecognitionResult result = speechRecognizeTask.Result;
1163
1164
                    if(result.Status == SpeechRecognitionResultStatus.Success)
1165
                    {
1166
                        if(result.Confidence != SpeechRecognitionConfidence.Rejected)
1167
                        {
1168
                            //Debug.LogError("Phrase: " + result.Text + ", Confidence: " + result.Confidence.ToString() + ", RawConf: " + result.RawConfidence);
1169
1170
                            float fConfidence = (float)result.RawConfidence; // (3f - (float)result.Confidence) / 3f;
1171
                            if(fConfidence >= requiredPhraseConfidence)
1172
                            {
1173
                                isPhraseRecognized = true;
1174
                                recognizedPhraseTag = result.SemanticInterpretation.Properties.ContainsKey("<ROOT>") ?
1175
                                    result.SemanticInterpretation.Properties["<ROOT>"][0] : result.Text;
1176
                                recognizedPhraseConfidence = fConfidence;
1177
                            }
1178
                        }
1179
                    }
1180
                    //else
1181
                    //{
1182
                    //    Debug.LogError("Speech recognition failed: " + result.Status.ToString());
1183
                    //}
1184
1185
                    speechRecognizeTask = null;
1186
                }
1187
            }
1188
        }
1189
1190
        return 0;
1191
	}
1192
1193
    private async Task<SpeechRecognitionResult> RecognizeSpeechAsync()
1194
    {
1195
        SpeechRecognitionResult result = null;
1196
1197
        if (speechRecognizer != null)
1198
        {
1199
            result = await speechRecognizer.RecognizeAsync();
1200
        }
1201
1202
        return result;
1203
    }
1204
1205
1206
	public int LoadSpeechGrammar (string sFileName, short iLangCode, bool bDynamic)
1207
	{
1208
        Task<int> task = null;
1209
1210
//        UnityEngine.WSA.Application.InvokeOnUIThread(() =>
1211
//        {
1212
            task = LoadGrammarFileAsync(sFileName);
1213
//        }, true);
1214
1215
        while (task != null && !task.IsCompleted && !task.IsFaulted)
1216
        {
1217
            task.Wait(100);
1218
        }
1219
1220
        if(task.IsFaulted)
1221
        {
1222
            Debug.LogError("LoadGrammarFileAsync() has faulted.");
1223
            if (task.Exception != null)
1224
                Debug.LogError(task.Exception);
1225
1226
            return -1;
1227
        }
1228
1229
        return 0;
1230
	}
1231
1232
    private async Task<int> LoadGrammarFileAsync(string sFileName)
1233
    {
1234
        if(speechRecognizer != null)
1235
        {
1236
            string sUrl = "ms-appdata:///local/" + sFileName;
1237
            var storageFile = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(new Uri(sUrl));
1238
            var grammarFile = new SpeechRecognitionGrammarFileConstraint(storageFile, sFileName);
1239
1240
            speechRecognizer.Constraints.Add(grammarFile);
1241
            await speechRecognizer.CompileConstraintsAsync();
1242
        }
1243
1244
        return 0;
1245
    }
1246
1247
	public int AddGrammarPhrase (string sFromRule, string sToRule, string sPhrase, bool bClearRulePhrases, bool bCommitGrammar)
1248
	{
1249
		return -1;
1250
	}
1251
1252
	public void SetSpeechConfidence (float fConfidence)
1253
	{
1254
        requiredPhraseConfidence = fConfidence;
1255
    }
1256
1257
	public bool IsSpeechStarted ()
1258
	{
1259
		return speechRecognizer != null ? speechRecognizer.State == SpeechRecognizerState.SoundStarted : false;
1260
	}
1261
1262
	public bool IsSpeechEnded ()
1263
	{
1264
        return speechRecognizer != null ? speechRecognizer.State == SpeechRecognizerState.SoundEnded : false;
1265
    }
1266
1267
	public bool IsPhraseRecognized ()
1268
	{
1269
		return isPhraseRecognized;
1270
	}
1271
1272
	public float GetPhraseConfidence ()
1273
	{
1274
		return recognizedPhraseConfidence;
1275
	}
1276
1277
	public string GetRecognizedPhraseTag ()
1278
	{
1279
		return recognizedPhraseTag;
1280
	}
1281
1282
	public void ClearRecognizedPhrase ()
1283
	{
1284
        isPhraseRecognized = false;
1285
        recognizedPhraseTag = string.Empty;
1286
        recognizedPhraseConfidence = 0f;
1287
    }
1288
1289
	public bool IsBackgroundRemovalAvailable (ref bool bNeedRestart)
1290
	{
1291
		return true;
1292
	}
1293
1294
	public bool InitBackgroundRemoval (KinectInterop.SensorData sensorData, bool isHiResPrefered)
1295
	{
1296
        _backgroundRemovalInited = KinectInterop.InitBackgroundRemoval(sensorData, isHiResPrefered);
1297
        return _backgroundRemovalInited;
1298
	}
1299
1300
	public void FinishBackgroundRemoval (KinectInterop.SensorData sensorData)
1301
	{
1302
        KinectInterop.FinishBackgroundRemoval(sensorData);
1303
        _backgroundRemovalInited = false;
1304
    }
1305
1306
	public bool UpdateBackgroundRemoval (KinectInterop.SensorData sensorData, bool isHiResPrefered, Color32 defaultColor, bool bAlphaTexOnly)
1307
	{
1308
        return KinectInterop.UpdateBackgroundRemoval(sensorData, isHiResPrefered, defaultColor, bAlphaTexOnly);
1309
    }
1310
1311
	public bool IsBackgroundRemovalActive ()
1312
	{
1313
		return _backgroundRemovalInited;
1314
	}
1315
1316
	public bool IsBRHiResSupported ()
1317
	{
1318
		return true;
1319
	}
1320
1321
	public Rect GetForegroundFrameRect (KinectInterop.SensorData sensorData, bool isHiResPrefered)
1322
	{
1323
        return KinectInterop.GetForegroundFrameRect(sensorData, isHiResPrefered);
1324
    }
1325
1326
	public int GetForegroundFrameLength (KinectInterop.SensorData sensorData, bool isHiResPrefered)
1327
	{
1328
        return KinectInterop.GetForegroundFrameLength(sensorData, isHiResPrefered);
1329
    }
1330
1331
	public bool PollForegroundFrame (KinectInterop.SensorData sensorData, bool isHiResPrefered, Color32 defaultColor, bool bLimitedUsers, System.Collections.Generic.ICollection<int> alTrackedIndexes, ref byte[] foregroundImage)
1332
	{
1333
        return KinectInterop.PollForegroundFrame(sensorData, isHiResPrefered, defaultColor, bLimitedUsers, alTrackedIndexes, ref foregroundImage);
1334
    }
1335
1336
}
1337
#endif