20 public const ulong System = (1ul << (int)EVRButtonId.k_EButton_System);
21 public const ulong ApplicationMenu = (1ul << (int)EVRButtonId.k_EButton_ApplicationMenu);
22 public const ulong Grip = (1ul << (int)EVRButtonId.k_EButton_Grip);
23 public const ulong Axis0 = (1ul << (int)EVRButtonId.k_EButton_Axis0);
24 public const ulong Axis1 = (1ul << (int)EVRButtonId.k_EButton_Axis1);
25 public const ulong Axis2 = (1ul << (int)EVRButtonId.k_EButton_Axis2);
26 public const ulong Axis3 = (1ul << (int)EVRButtonId.k_EButton_Axis3);
27 public const ulong Axis4 = (1ul << (int)EVRButtonId.k_EButton_Axis4);
28 public const ulong Touchpad = (1ul << (int)EVRButtonId.k_EButton_SteamVR_Touchpad);
29 public const ulong Trigger = (1ul << (int)EVRButtonId.k_EButton_SteamVR_Trigger);
34 public Device(uint i) { index = i; }
35 public uint index {
get;
private set; }
37 public bool valid {
get;
private set; }
38 public bool connected {
get { Update();
return pose.bDeviceIsConnected; } }
39 public bool hasTracking {
get { Update();
return pose.bPoseIsValid; } }
41 public bool outOfRange {
get { Update();
return pose.eTrackingResult == ETrackingResult.Running_OutOfRange || pose.eTrackingResult == ETrackingResult.Calibrating_OutOfRange; } }
42 public bool calibrating {
get { Update();
return pose.eTrackingResult == ETrackingResult.Calibrating_InProgress || pose.eTrackingResult == ETrackingResult.Calibrating_OutOfRange; } }
43 public bool uninitialized {
get { Update();
return pose.eTrackingResult == ETrackingResult.Uninitialized; } }
48 public Vector3 velocity {
get { Update();
return new Vector3(pose.vVelocity.v0, pose.vVelocity.v1, -pose.vVelocity.v2); } }
49 public Vector3 angularVelocity {
get { Update();
return new Vector3(-pose.vAngularVelocity.v0, -pose.vAngularVelocity.v1, pose.vAngularVelocity.v2); } }
57 int prevFrameCount = -1;
60 if (Time.frameCount != prevFrameCount)
62 prevFrameCount = Time.frameCount;
65 var system = OpenVR.System;
68 valid = system.GetControllerStateWithPose(SteamVR_Render.instance.trackingSpace, index, ref state, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(
VRControllerState_t)), ref pose);
74 public bool GetPress(ulong buttonMask) { Update();
return (state.ulButtonPressed & buttonMask) != 0; }
75 public bool GetPressDown(ulong buttonMask) { Update();
return (state.ulButtonPressed & buttonMask) != 0 && (prevState.ulButtonPressed & buttonMask) == 0; }
76 public bool GetPressUp(ulong buttonMask) { Update();
return (state.ulButtonPressed & buttonMask) == 0 && (prevState.ulButtonPressed & buttonMask) != 0; }
78 public bool GetPress(EVRButtonId buttonId) {
return GetPress(1ul << (
int)buttonId); }
79 public bool GetPressDown(EVRButtonId buttonId) {
return GetPressDown(1ul << (
int)buttonId); }
80 public bool GetPressUp(EVRButtonId buttonId) {
return GetPressUp(1ul << (
int)buttonId); }
82 public bool GetTouch(ulong buttonMask) { Update();
return (state.ulButtonTouched & buttonMask) != 0; }
83 public bool GetTouchDown(ulong buttonMask) { Update();
return (state.ulButtonTouched & buttonMask) != 0 && (prevState.ulButtonTouched & buttonMask) == 0; }
84 public bool GetTouchUp(ulong buttonMask) { Update();
return (state.ulButtonTouched & buttonMask) == 0 && (prevState.ulButtonTouched & buttonMask) != 0; }
86 public bool GetTouch(EVRButtonId buttonId) {
return GetTouch(1ul << (
int)buttonId); }
87 public bool GetTouchDown(EVRButtonId buttonId) {
return GetTouchDown(1ul << (
int)buttonId); }
88 public bool GetTouchUp(EVRButtonId buttonId) {
return GetTouchUp(1ul << (
int)buttonId); }
90 public Vector2 GetAxis(EVRButtonId buttonId = EVRButtonId.k_EButton_SteamVR_Touchpad)
93 var axisId = (uint)buttonId - (uint)EVRButtonId.k_EButton_Axis0;
96 case 0:
return new Vector2(state.rAxis0.x, state.rAxis0.y);
97 case 1:
return new Vector2(state.rAxis1.x, state.rAxis1.y);
98 case 2:
return new Vector2(state.rAxis2.x, state.rAxis2.y);
99 case 3:
return new Vector2(state.rAxis3.x, state.rAxis3.y);
100 case 4:
return new Vector2(state.rAxis4.x, state.rAxis4.y);
105 public void TriggerHapticPulse(ushort durationMicroSec = 500, EVRButtonId buttonId = EVRButtonId.k_EButton_SteamVR_Touchpad)
107 var system = OpenVR.System;
110 var axisId = (uint)buttonId - (uint)EVRButtonId.k_EButton_Axis0;
111 system.TriggerHapticPulse(index, axisId, (char)durationMicroSec);
115 public float hairTriggerDelta = 0.1f;
116 float hairTriggerLimit;
117 bool hairTriggerState, hairTriggerPrevState;
118 void UpdateHairTrigger()
120 hairTriggerPrevState = hairTriggerState;
121 var value = state.rAxis1.x;
122 if (hairTriggerState)
124 if (value < hairTriggerLimit - hairTriggerDelta || value <= 0.0f)
125 hairTriggerState =
false;
129 if (value > hairTriggerLimit + hairTriggerDelta || value >= 1.0f)
130 hairTriggerState =
true;
132 hairTriggerLimit = hairTriggerState ? Mathf.Max(hairTriggerLimit, value) : Mathf.Min(hairTriggerLimit, value);
135 public bool GetHairTrigger() { Update();
return hairTriggerState; }
136 public bool GetHairTriggerDown() { Update();
return hairTriggerState && !hairTriggerPrevState; }
137 public bool GetHairTriggerUp() { Update();
return !hairTriggerState && hairTriggerPrevState; }
140 private static Device[] devices;
142 public static Device Input(
int deviceIndex)
146 devices =
new Device[OpenVR.k_unMaxTrackedDeviceCount];
147 for (uint i = 0; i < devices.Length; i++)
148 devices[i] =
new Device(i);
151 return devices[deviceIndex];
154 public static void Update()
156 for (
int i = 0; i < OpenVR.k_unMaxTrackedDeviceCount; i++)
163 public enum DeviceRelation
173 public static int GetDeviceIndex(DeviceRelation relation,
174 ETrackedDeviceClass deviceClass = ETrackedDeviceClass.Controller,
175 int relativeTo = (
int)
OpenVR.k_unTrackedDeviceIndex_Hmd)
179 var invXform = ((uint)relativeTo <
OpenVR.k_unMaxTrackedDeviceCount) ?
180 Input(relativeTo).transform.GetInverse() : SteamVR_Utils.RigidTransform.identity;
182 var system =
OpenVR.System;
186 var best = -float.MaxValue;
187 for (
int i = 0; i < OpenVR.k_unMaxTrackedDeviceCount; i++)
189 if (i == relativeTo || system.GetTrackedDeviceClass((uint)i) != deviceClass)
192 var device = Input(i);
193 if (!device.connected)
196 if (relation == DeviceRelation.First)
201 var pos = invXform * device.transform.pos;
202 if (relation == DeviceRelation.FarthestRight)
206 else if (relation == DeviceRelation.FarthestLeft)
212 var dir =
new Vector3(pos.x, 0.0f, pos.z).normalized;
213 var dot = Vector3.Dot(dir, Vector3.forward);
214 var cross = Vector3.Cross(dir, Vector3.forward);
215 if (relation == DeviceRelation.Leftmost)
217 score = (cross.y > 0.0f) ? 2.0f - dot : dot;
221 score = (cross.y < 0.0f) ? 2.0f - dot : dot;