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
28 private static BodyTrackerManager instance;
29 public void SetBodyTracker(BodyTracker bodyTracker) { this.bodyTracker = bodyTracker; }
30 public BodyTracker GetBodyTracker() { return this.bodyTracker; }
31
32 public void SetSensorOrientation(SensorOrientation sensorOrientation) { this.sensorOrientation = sensorOrientation; }
33 public SensorOrientation GetSensorOrientation() { return this.sensorOrientation; }
34
35 public void SetDeviceSerial(string deviceSerial) { this.deviceSerial = deviceSerial; }
36 public string GetDeviceSerial() { return deviceSerial; }
37 public List<string> GetAvailableSerials() { return availableSerials; }
38
39 private void Awake() {
40 // This ensures that only 1 BodyTrackerManager exists at a time.
41 if (instance == null) {
42 instance = this;
43 } else {
44 Destroy(this);
45 }
46 }
47
48 private void OnDestroy() {
49 if (frameDataProvider != null) {
50 frameDataProvider.Dispose();
51 frameDataProvider = null;
52 }
53
54 if (instance == this) {
55 instance = null;
56 }
57 }
58
59 private void Update() {
60 // Disconnect the currently connected device if the serial number no longer matches what we want.
61 if (frameDataProvider != null &&
62 frameDataProvider.HasStarted &&
63 (frameDataProvider.DeviceSerial != deviceSerial || frameDataProvider.Orientation != sensorOrientation)) {
64 Debug.Log("New serial number " + deviceSerial + "selected. Shutting down " + frameDataProvider.DeviceSerial + ".");
65 frameDataProvider.Dispose();
66 frameDataProvider = null;
67 }
68
69 // Connect to the new device.
70 if (isReady && null == frameDataProvider) {
71 // Scan for devices.
72 ScanDeviceSerials();
73
74 // See if any of the devices match.
75 for (int i = 0; i < availableSerials.Count; ++i) {
76 if (availableSerials[i] == deviceSerial) {
77 Debug.Log("Attempting to start " + deviceSerial + ".");
78 frameDataProvider = new FrameDataProvider(i, sensorOrientation, OnFrameDataProviderFinish);
79 isReady = false;
80 }
81 }
82
83 // If none match, start index 0 if connectDefaultIfNoSerialMatch is set to true.
84 if (connectDefaultIfNoSerialMatch && 0 < availableSerials.Count && frameDataProvider == null) {
85 deviceSerial = availableSerials[0];
86 }
87 }
88
89 // Update the skeleton.
90 if (null == frameDataProvider ||
91 !frameDataProvider.HasStarted ||
92 !frameDataProvider.GetData(ref frameData) ||
93 frameData.NumDetectedBodies == 0) { return; }
94 bodyTracker.UpdateSkeleton(frameData, sensorOrientation);
95 }
96
97 /// Scan through the ORBBEC devices and retrieve their serial numbers.
98 private void ScanDeviceSerials() {
99 int deviceCount = Device.GetInstalledCount();
100 availableSerials.Clear();
101 for (int i = 0; i < deviceCount; ++i) {
102 try {
103 using (Device device = Device.Open(i)) {
104 availableSerials.Add(device.SerialNum);
105 Debug.Log("BodyTrackerManager::ScanDeviceSerials - Found device with serial number " + device.SerialNum + ".");
106 device.Dispose();
107 }
108 } catch (Exception e) {
109 Debug.LogError(e.ToString());
110 }
111 }
112 }
113
114 private void OnFrameDataProviderFinish() { isReady = true; }
115 }
116}
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.