Spelunx Cavern SDK
 
Loading...
Searching...
No Matches
ViveTracker.cs
Go to the documentation of this file.
1using System.Linq;
2using UnityEngine;
3using UnityEngine.Events;
4using Valve.VR;
5
6namespace Spelunx.Vive
7{
8 public sealed class ViveTracker : OVRT_TrackedDevice
9 {
10 // an enum representing the possible bindings a vive tracker can be assigned to
11 // The tracker -> binding assignment should be done on the CAVERN computer
12 // in SteamVR
14 {
15 [InspectorName("Disabled")] // note: This isn't actually disabled. It's just another binding
17 [InspectorName("Any Hand")]
18 AnyHand,
19 [InspectorName("Left Hand")]
21 [InspectorName("Right Hand")]
23 [InspectorName("Left Foot")]
25 [InspectorName("Right Foot")]
27 [InspectorName("Left Shoulder")]
29 [InspectorName("Right Shoulder")]
31 [InspectorName("Left Elbow")]
33 [InspectorName("Right Elbow")]
35 [InspectorName("Left Knee")]
37 [InspectorName("Right Knee")]
39 [InspectorName("Left Wrist")]
41 [InspectorName("Right Wrist")]
43 [InspectorName("Left Ankle")]
45 [InspectorName("Right Ankle")]
47 [InspectorName("Waist")]
49 [InspectorName("Chest")]
51 [InspectorName("Camera")]
53 [InspectorName("Keyboard")]
55 }
56
57 [Tooltip("Specify a binding from SteamVR for this tracker. Assign a tracker to this same binding in SteamVR.")]
59
60 [Tooltip("If not set, relative to parent")]
61
62 private UnityAction<string, TrackedDevicePose_t, int> _onNewBoundPoseAction;
63 private UnityAction _onTrackerRolesChanged;
64
65 private Quaternion rotationAlignment = Quaternion.identity;
66
67 // All bindings are referenced in steamvr by their name (like TrackerRole_Camera)
68 // Except for the hands, which have binding names with commas in them
69 // Hence the need for this function
71 {
72 switch (binding)
73 {
74 case SteamVRPoseBindings.AnyHand:
75 return "TrackerRole_Handed,TrackedControllerRole_Invalid";
76 case SteamVRPoseBindings.LeftHand:
77 return "TrackerRole_Handed,TrackedControllerRole_LeftHand";
78 case SteamVRPoseBindings.RightHand:
79 return "TrackerRole_Handed,TrackedControllerRole_RightHand";
80 default:
81 return binding.ToString();
82 }
83 }
84
85 // get the display name instead of the actual enum name of our bindings
86 // thanks stackoverflow: https://stackoverflow.com/questions/1799370/getting-attributes-of-enums-value
88 {
89 try
90 {
91 var enumType = typeof(ViveTracker.SteamVRPoseBindings);
92
93 var memberInfos = enumType
94 .GetMember(binding.ToString());
95
96 var enumValueMemberInfo = memberInfos
97 .FirstOrDefault(m => m.DeclaringType == enumType);
98
99 var valueAttributes = enumValueMemberInfo
100 .GetCustomAttributes(typeof(InspectorNameAttribute), false);
101
102 var description = ((InspectorNameAttribute)valueAttributes[0])
103 .displayName;
104 return description;
105 }
106 catch
107 {
109 }
110 }
111
112 private void OnDeviceConnected(int index, bool connected)
113 {
114 if (DeviceIndex == index && !connected)
115 {
116 IsConnected = false;
117 }
118 }
119
120 private bool doCalibration = false; // Whether to calibrate the rotation of the vive tracker on the next frame
121
122 private void OnNewBoundPose(string binding, TrackedDevicePose_t pose, int deviceIndex)
123 {
124 if (TrackerRoleToBindingName(this.binding) != binding)
125 return;
126
127 IsValid = false;
128
129 if (DeviceIndex != deviceIndex)
130 {
131 DeviceIndex = deviceIndex;
133 }
134 IsConnected = pose.bDeviceIsConnected;
135
136 if (!pose.bDeviceIsConnected)
137 return;
138
139 if (!pose.bPoseIsValid)
140 return;
141
142 IsValid = true;
143
144 var rigidTransform = new OVRT_Utils.RigidTransform(pose.mDeviceToAbsoluteTracking);
145
146 if (origin != null)
147 {
148 transform.position = origin.transform.TransformPoint(rigidTransform.pos);
149 // Realign the rotation of the vive tracker. It's hard to know visually when they're pointing forwards,
150 // So this offsets their rotation
151 if (doCalibration)
152 {
153 // calibrate
154 rotationAlignment = Quaternion.Inverse(origin.rotation * rigidTransform.rot);
155 doCalibration = false;
156 }
157 transform.rotation = origin.rotation * rigidTransform.rot * rotationAlignment;
158 }
159 else
160 {
161 transform.localPosition = rigidTransform.pos;
162 transform.localRotation = rigidTransform.rot;
163 }
164 }
165
166 // Calibrate vive trackers on the next pose frame
167 public void Calibrate()
168 {
169 doCalibration = true;
170 }
171
172 private void OnTrackerRolesChanged()
173 {
174 IsValid = false;
175 IsConnected = false;
176 }
177
178 private void Awake()
179 {
180 _onNewBoundPoseAction += OnNewBoundPose;
181 _onDeviceConnectedAction += OnDeviceConnected;
182 _onTrackerRolesChanged += OnTrackerRolesChanged;
183 }
184
185 private void OnEnable()
186 {
187 OVRT_Events.NewBoundPose.AddListener(_onNewBoundPoseAction);
188 OVRT_Events.TrackedDeviceConnected.AddListener(_onDeviceConnectedAction);
189 OVRT_Events.TrackerRolesChanged.AddListener(_onTrackerRolesChanged);
190 }
191
192 private void OnDisable()
193 {
194 OVRT_Events.NewBoundPose.RemoveListener(_onNewBoundPoseAction);
195 OVRT_Events.TrackedDeviceConnected.RemoveListener(_onDeviceConnectedAction);
196 OVRT_Events.TrackerRolesChanged.RemoveListener(_onTrackerRolesChanged);
197 IsValid = false;
198 IsConnected = false;
199 }
200
201 private void Start()
202 {
203 SetOrigin(FindFirstObjectByType<Vive_Manager>().transform);
204 }
205
206 // t is treated as the (0,0,0) point
207 public void SetOrigin(Transform t)
208 {
209 origin = t;
210 }
211
212#if UNITY_EDITOR
213 // A gizmo, which can be enabled or disabled through the gizmos menu
214 // This shows the position, size, and rotation of the vive tracker.
215 private void OnDrawGizmos()
216 {
217 Gizmos.DrawMesh(ViveDebugRenderer.trackerMesh, transform.position, transform.rotation);
218 }
219#endif
220 }
221}
UnityAction< int, bool > _onDeviceConnectedAction
This class loads the vive tracker mesh, to be used by ViveTracker when rendering a gizmo.
void SetOrigin(Transform t)
Definition: ViveTracker.cs:207
SteamVRPoseBindings binding
Definition: ViveTracker.cs:58
static string GetReadableName(SteamVRPoseBindings binding)
Definition: ViveTracker.cs:87
static string TrackerRoleToBindingName(SteamVRPoseBindings binding)
Definition: ViveTracker.cs:70