3using System.Threading.Tasks;
4using System.Runtime.InteropServices;
5using Microsoft.Azure.Kinect.Sensor;
6using Microsoft.Azure.Kinect.BodyTracking;
15 public bool HasData {
get;
private set; } =
false;
22 private object dataMutex =
new object();
23 private CancellationTokenSource cancellationTokenSource =
new CancellationTokenSource();
24 private Task backgroundThread =
null;
28 UnityEditor.EditorApplication.quitting += OnEditorClose;
38 UnityEditor.EditorApplication.quitting -= OnEditorClose;
41 cancellationTokenSource?.Cancel();
42 cancellationTokenSource?.Dispose();
43 cancellationTokenSource =
null;
45 backgroundThread?.Wait();
52 var temp = frontBuffer;
63 UnityEngine.Debug.Log(
"Starting body tracker background thread.");
66 if (Device.GetInstalledCount() <= deviceId) {
67 throw new Exception(
"SkeletalFrameDataProvider - Cannot open device ID " + deviceId +
". Only " + Device.GetInstalledCount() +
" devices are connected. Terminating thread.");
71 using (Device device = Device.Open(deviceId)) {
75 device.StartCameras(
new DeviceConfiguration() {
76 CameraFPS = FPS.FPS30,
77 ColorResolution = ColorResolution.Off,
78 DepthMode = DepthMode.NFOV_Unbinned,
79 WiredSyncMode = WiredSyncMode.Standalone,
80 DisableStreamingIndicator =
false
83 UnityEngine.Debug.Log(
"SkeletalFrameDataProvider - Open K4A device successfully. Device ID: " + deviceId +
", Serial Number: " + device.SerialNum);
86 var trackerCalibration = device.GetCalibration();
87 TrackerConfiguration trackerConfig =
new TrackerConfiguration() {
88 ProcessingMode = TrackerProcessingMode.Cpu,
98 bool isFirstFrame =
true;
99 TimeSpan initialTimestamp =
new TimeSpan(0);
100 using (Tracker tracker = Tracker.Create(trackerCalibration, trackerConfig)) {
101 while (!token.IsCancellationRequested) {
103 using (Capture sensorCapture = device.GetCapture()) {
104 tracker.EnqueueCapture(sensorCapture);
108 using (Frame frame = tracker.PopResult(TimeSpan.Zero, throwOnTimeout:
false)) {
110 UnityEngine.Debug.Log($
"SkeletalFrameDataProvider - ID: {deviceId}, Pop result from tracker timeout!");
118 backBuffer.NumDetectedBodies = frame.NumberOfBodies;
124 Capture bodyFrameCapture = frame.Capture;
125 Image depthImage = bodyFrameCapture.Depth;
127 isFirstFrame =
false;
128 initialTimestamp = depthImage.DeviceTimestamp;
130 backBuffer.TimestampInMs = (float)(depthImage.DeviceTimestamp - initialTimestamp).TotalMilliseconds;
131 backBuffer.DepthImageWidth = depthImage.WidthPixels;
132 backBuffer.DepthImageHeight = depthImage.HeightPixels;
135 var depthFrame = MemoryMarshal.Cast<byte, ushort>(depthImage.Memory.Span);
138 const float MAX_DISPLAYED_DEPTH_IN_MILLIMETERS = 5000.0f;
140 backBuffer.DepthImageSize = backBuffer.DepthImageWidth * backBuffer.DepthImageHeight * 3;
142 byte b = (byte)(depthFrame[it] / MAX_DISPLAYED_DEPTH_IN_MILLIMETERS * 255);
156 }
catch (Exception e) {
157 UnityEngine.Debug.Log($
"SkeletalFrameDataProvider - ID: {deviceId}, Catching exception for background thread: {e.Message}");
159 UnityEngine.Debug.Log($
"SkeletalFrameDataProvider - ID: {deviceId}, Shutting down background thread.");
166 private void SwapBuffers() {
168 var temp = backBuffer;
169 backBuffer = frontBuffer;
Processes data from the ORBBEC sensor in a background thread to produce FrameData.
bool GetData(ref FrameData output)
SensorOrientation Orientation
delegate void FinishCallback()
bool HasStarted
Flag to determine of the background thread has started.
void RunBackgroundThreadAsync(int deviceId, CancellationToken token, FinishCallback onFinish)
FrameDataProvider(int deviceId, SensorOrientation orientation, FinishCallback onFinish)
BodyData[] Bodies
Array of bodies. Use NumDetectedBodies to determine how many bodies contain useful data.
void CopyFromBodyTrackingSdk(Microsoft.Azure.Kinect.BodyTracking.Body body, Calibration sensorCalibration)