Spelunx Cavern SDK
 
Loading...
Searching...
No Matches
BodyTrackerManager.cs
Go to the documentation of this file.
1using UnityEngine;
2using Microsoft.Azure.Kinect.BodyTracking;
3using Microsoft.Azure.Kinect.Sensor;
4using System;
5using System.Collections.Generic;
6
7namespace Spelunx.Orbbec {
8 // ********************************* IMPORTANT: There should only be one instance of BodyTrackerManager in the scene. ********************************* //
9 // If anyone ever wants to add support for more sensors at a time, put the work in to modify this class instead of just adding more BodyTrackerManager.
10 // That is because this class opens and closes devices, and I am not sure if we should allow more than one instance to possibly do that simultaneously and cause multi-threading problems.
11
12 /// Manager class to pass data from FrameDataProvider to BodyTracker.
13 public class BodyTrackerManager : MonoBehaviour {
14 [Header("References")]
15 [SerializeField, Tooltip("The skeleton to control.")] private BodyTracker bodyTracker; // One for each skeleton on the screen. For now we only support 1.
16
17 [Header("Settings")]
18 [SerializeField, Tooltip("How is the sensor mounted?")] private SensorOrientation sensorOrientation;
19 [SerializeField, Tooltip("Serial number of the device we want to connect to.")] private string deviceSerial = "<Insert device serial number here.>";
20 [SerializeField, Tooltip("If no serial numbers match, connect to first device found.")] private bool connectDefaultIfNoSerialMatch = true;
21
22 // Internal Variables
23 private List<string> availableSerials = new List<string>();
24 private FrameData frameData = new FrameData();
25 private FrameDataProvider frameDataProvider = null; // One for each Femto Bolt. One Femto Bolt can support multiple (like 20?) skeletons.
26 private bool isReady = true; // A flag to ensure that a new frame data provider waits for the old one to shutdown completely, so that it is impossible for them to open the same device.
27 private bool hasDetectedBodies = false;
28
29 private static BodyTrackerManager instance;
30 public void SetBodyTracker(BodyTracker bodyTracker) { this.bodyTracker = bodyTracker; }
31 public BodyTracker GetBodyTracker() { return this.bodyTracker; }
32
33 public void SetSensorOrientation(SensorOrientation sensorOrientation) { this.sensorOrientation = sensorOrientation; }
34 public SensorOrientation GetSensorOrientation() { return this.sensorOrientation; }
35
36 public void SetDeviceSerial(string deviceSerial) { this.deviceSerial = deviceSerial; }
37 public string GetDeviceSerial() { return deviceSerial; }
38 public List<string> GetAvailableSerials() { return availableSerials; }
39
40 public bool HasDetectedBodies() { return hasDetectedBodies; }
41
42 private void Awake() {
43 // This ensures that only 1 BodyTrackerManager exists at a time.
44 if (instance == null) {
45 instance = this;
46 } else {
47 Destroy(this);
48 }
49 }
50
51 private void OnDestroy() {
52 if (frameDataProvider != null) {
53 frameDataProvider.Dispose();
54 frameDataProvider = null;
55 }
56
57 if (instance == this) {
58 instance = null;
59 }
60 }
61
62 private void Update() {
63 // Disconnect the currently connected device if the serial number no longer matches what we want.
64 if (frameDataProvider != null &&
65 frameDataProvider.HasStarted &&
66 (frameDataProvider.DeviceSerial != deviceSerial || frameDataProvider.Orientation != sensorOrientation)) {
67 Debug.Log("New serial number " + deviceSerial + "selected. Shutting down " + frameDataProvider.DeviceSerial + ".");
68 frameDataProvider.Dispose();
69 frameDataProvider = null;
70 }
71
72 // Connect to the new device.
73 if (isReady && null == frameDataProvider) {
74 // Scan for devices.
75 ScanDeviceSerials();
76
77 // See if any of the devices match.
78 for (int i = 0; i < availableSerials.Count; ++i) {
79 if (availableSerials[i] == deviceSerial) {
80 Debug.Log("Attempting to start " + deviceSerial + ".");
81 frameDataProvider = new FrameDataProvider(i, sensorOrientation, OnFrameDataProviderFinish);
82 isReady = false;
83 }
84 }
85
86 // If none match, start index 0 if connectDefaultIfNoSerialMatch is set to true.
87 if (connectDefaultIfNoSerialMatch && 0 < availableSerials.Count && frameDataProvider == null) {
88 deviceSerial = availableSerials[0];
89 }
90 }
91
92 // Check if the frame data provider has started.
93 if (null == frameDataProvider || !frameDataProvider.HasStarted) {
94 hasDetectedBodies = false;
95 return;
96 }
97
98 // Update the skeleton if there is new data.
99 if (frameDataProvider.GetData(ref frameData)) {
100 if (0 < frameData.NumDetectedBodies) {
101 hasDetectedBodies = true;
102 bodyTracker.UpdateSkeleton(frameData, sensorOrientation);
103 } else {
104 hasDetectedBodies = false;
105 }
106 }
107 }
108
109 /// Scan through the ORBBEC devices and retrieve their serial numbers.
110 private void ScanDeviceSerials() {
111 int deviceCount = Device.GetInstalledCount();
112 availableSerials.Clear();
113 for (int i = 0; i < deviceCount; ++i) {
114 try {
115 using (Device device = Device.Open(i)) {
116 availableSerials.Add(device.SerialNum);
117 Debug.Log("BodyTrackerManager::ScanDeviceSerials - Found device with serial number " + device.SerialNum + ".");
118 device.Dispose();
119 }
120 } catch (Exception e) {
121 Debug.LogError(e.ToString());
122 }
123 }
124 }
125
126 private void OnFrameDataProviderFinish() { isReady = true; }
127 }
128}
Manager class to pass data from FrameDataProvider to BodyTracker.
void SetSensorOrientation(SensorOrientation sensorOrientation)
void SetBodyTracker(BodyTracker bodyTracker)
SensorOrientation GetSensorOrientation()
void SetDeviceSerial(string deviceSerial)
BodyTracker represents the BodyData from the ORBBEC sensor as a skeleton. Important: BodyTracker pref...
Definition: BodyTracker.cs:10
Processes data from the ORBBEC sensor in a background thread to produce FrameData.
bool GetData(ref FrameData output)
bool HasStarted
Flag to determine of the background thread has started.