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 |