public void UpdateNode(XRNodeState node) { if (node.nodeType == XRNode.HardwareTracker) { var hwId = GetHardwareId(node); if (!_activeTrackers.ContainsKey(hwId)) { Debug.LogWarning($"No key {hwId}"); AddNode(node); return; } var tracker = _activeTrackers[hwId]; node.TryGetPosition(out var position); node.TryGetRotation(out var rotation); tracker.Rotation = rotation * RotationOffset; tracker.Position = position + tracker.Rotation * PositionOffset; tracker.LastUpdate = Time.unscaledTime; // if tracking is lost, tracker is put at (0, 0, 0) tracker.IsActive = (position - Vector3.zero).sqrMagnitude > Mathf.Epsilon; } else { var hwId = GetHardwareId(node); if (_activeTrackers.ContainsKey(hwId)) { Debug.LogWarning($"Tracker {hwId} is classified as {node.nodeType} but in activeTrackers"); } } }
/// <summary> /// Initialize the ZED's tracking with the current HMD position and HMD-ZED calibration. /// This causes the ZED's internal tracking to start where the HMD is, despite being initialized later than the HMD. /// </summary> /// <returns>Initial offset for the ZED's tracking. </returns> public Pose InitTrackingAR() { if (manager == null) { return(new Pose()); } Transform tmpHMD = transform; #if UNITY_2019_1_OR_NEWER InputTracking.GetNodeStates(nodeStates); XRNodeState nodeState = nodeStates.Find(node => node.nodeType == XRNode.Head); nodeState.TryGetRotation(out Quaternion rot); nodeState.TryGetPosition(out Vector3 pos); Pose hmdTransform = new Pose(pos, rot); #else tmpHMD.position = InputTracking.GetLocalPosition(XRNode.Head); tmpHMD.rotation = InputTracking.GetLocalRotation(XRNode.Head); #endif Quaternion r = Quaternion.identity; Vector3 t = Vector3.zero; Pose const_offset = new Pose(t, r); dllz_drift_corrector_set_calibration_const_offset_transform(ref const_offset); zedCamera.ResetTrackingWithOffset(tmpHMD.rotation, tmpHMD.position, HmdToZEDCalibration.rotation, HmdToZEDCalibration.translation); return(new Pose(tmpHMD.position, tmpHMD.rotation)); }
private void CheckPlayerPos() { // circle of bubble: // compare against center of sphere InputTracking.GetNodeStates(nodeStatesCache); Vector3 hmd_pos = new Vector3(); for (int i = 0; i < nodeStatesCache.Count; i++) { XRNodeState nodeState = nodeStatesCache[i]; if (nodeState.nodeType == XRNode.CenterEye) { nodeState.TryGetPosition(out hmd_pos); } } if (Vector2.Distance(new Vector2(hmd_pos.x, hmd_pos.y), new Vector2(0, 0)) < bubble_visual.transform.localScale.x / 1.5) { // within - fine } else { state_handler.SetState(GameState.GAMEOVER); } }
/// <inheritdoc /> public override void UpdateController() { if (!Enabled) { return; } Profiler.BeginSample("[MRTK] GenericOpenVRController.UpdateController"); InputTracking.GetNodeStates(nodeStates); for (int i = 0; i < nodeStates.Count; i++) { if (nodeStates[i].nodeType == nodeType) { var xrNodeState = nodeStates[i]; UpdateControllerData(xrNodeState); LastXrNodeStateReading = xrNodeState; break; } } base.UpdateController(); Profiler.EndSample(); // UpdateController }
protected override float GetAxisValue(XRNodeState node, InputAxis axis) { var controller = GetController(node); OVRPlugin.ControllerState4 state = OVRPlugin.GetControllerState4((uint)controller); switch (axis) { case InputAxis.MainTrigger: return(controller == OVRInput.Controller.LTouch ? state.LIndexTrigger : state.RIndexTrigger); case InputAxis.Grip: return(controller == OVRInput.Controller.LTouch ? state.LHandTrigger : state.RHandTrigger); case InputAxis.JoypadX: case InputAxis.JoypadY: { var joy = controller == OVRInput.Controller.LTouch ? state.LThumbstick : state.RThumbstick; return(axis == InputAxis.JoypadX ? joy.x : joy.y); } case InputAxis.Joypad: { var buttonId = controller == OVRInput.Controller.LTouch ? 0x00000400 : 0x00000004; //see enum ovrButton_ in OVER_CAPI.h return((state.Buttons & buttonId) != 0 ? 1 : 0); } default: return(0); } }
private Pose GetPoseInput(ulong action, XRNodeState node) { InputPoseActionData_t data = new InputPoseActionData_t(); var res = OpenVR.Input.GetPoseActionData( action, XRDevice.GetTrackingSpaceType() == TrackingSpaceType.RoomScale ? ETrackingUniverseOrigin.TrackingUniverseStanding : ETrackingUniverseOrigin.TrackingUniverseSeated, 0, ref data, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(InputPoseActionData_t)), node.nodeType == XRNode.LeftHand ? leftHand : rightHand ); if (res != EVRInputError.None) { throw new ApplicationException("Failed to get pose input data " + node.nodeType + ": " + res); } var matRaw = data.pose.mDeviceToAbsoluteTracking; var mat = new Matrix4x4( new Vector4(matRaw.m0, matRaw.m1, matRaw.m2, 0), new Vector4(matRaw.m4, matRaw.m5, matRaw.m6, 0), new Vector4(matRaw.m8, matRaw.m9, matRaw.m10, 0), new Vector4(0, 0, 0, 1) ); var rot = mat.rotation; // rot.x *= -1; rot.z *= -1; return(new Pose { pos = new Vector3(matRaw.m3, matRaw.m7, -matRaw.m11), rot = rot }); }
/// <summary> /// Before the ZED is ready, lock the quads in front of the cameras as latency correction isn't available yet. /// This allows us to see the loading messages (and other virtual objects if desired) while the ZED is still loading. /// Called by Camera.OnPreRender anytime any camera renders. /// </summary> /// <param name="cam">Cam.</param> public void PreRender(Camera cam) { if (cam == finalLeftEye || cam == finalRightEye) { if ((!manager.IsZEDReady && manager.IsStereoRig)) { #if UNITY_2019_1_OR_NEWER InputTracking.GetNodeStates(nodeStates); XRNodeState nodeState = nodeStates.Find(node => node.nodeType == XRNode.Head); nodeState.TryGetRotation(out Quaternion rot); nodeState.TryGetPosition(out Vector3 pos); quadLeft.localRotation = rot; quadLeft.localPosition = pos + quadLeft.localRotation * offset; quadRight.localRotation = rot; quadRight.localPosition = pos + quadRight.localRotation * offset; #else quadLeft.localRotation = InputTracking.GetLocalRotation(XRNode.Head); quadLeft.localPosition = InputTracking.GetLocalPosition(XRNode.Head) + quadLeft.localRotation * offset; quadRight.localRotation = InputTracking.GetLocalRotation(XRNode.Head); quadRight.localPosition = InputTracking.GetLocalPosition(XRNode.Head) + quadRight.localRotation * offset; #endif } } }
/// <inheritdoc /> public override void UpdateController() { using (UpdateControllerPerfMarker.Auto()) { if (!Enabled) { return; } InputTracking.GetNodeStates(nodeStates); for (int i = 0; i < nodeStates.Count; i++) { if (nodeStates[i].nodeType == nodeType) { var xrNodeState = nodeStates[i]; UpdateControllerData(xrNodeState); LastXrNodeStateReading = xrNodeState; break; } } base.UpdateController(); } }
private static PosRot GetTrackerWorldPosRot(XRNodeState tracker) { Vector3 pos = new Vector3(); Quaternion rot = new Quaternion(); try { var notes = new List <XRNodeState>(); InputTracking.GetNodeStates(notes); foreach (XRNodeState note in notes) { if (note.uniqueID != tracker.uniqueID) { continue; } if (note.TryGetPosition(out pos) && note.TryGetRotation(out rot)) { var roomCenter = BeatSaberUtil.GetRoomCenter(); var roomRotation = BeatSaberUtil.GetRoomRotation(); pos = roomRotation * pos; pos += roomCenter; rot = roomRotation * rot; } } } catch (Exception e) { Logger.Log(e.Message + "\n" + e.StackTrace, Logger.LogLevel.Error); } return(new PosRot(pos, rot)); }
public override JoyPadType GetJoypadTypes(XRNodeState node) { if (jpType != JoyPadType.Unknown) { return(jpType); } if (mode == InputMode.Direct) { var name = GetNodeName(node); if (name.Contains("Oculus Touch Controller") || name.StartsWith("Oculus Rift CV1")) { //OpenVR gives us "Oculus Rift CV1 (Left Controller)" etc. where I wish it would mention the type of controller (Touch) return(jpType = JoyPadType.Joystick); } else if (name.StartsWith("Vive Controller")) { return(jpType = JoyPadType.TouchPad); } else { Debug.LogWarning("Unknown controller type: " + name); return(jpType = JoyPadType.None); } } else { return(jpType = (JoyPadType.Joystick | JoyPadType.TouchPad)); } }
protected override float GetAxisValue(XRNodeState node, InputAxis axis) { ReadState(node); switch (axis) { case InputAxis.TouchPad: return((lastState.ulButtonTouched & 1ul << (int)EVRButtonId.k_EButton_SteamVR_Touchpad) != 0 ? 1 : 0); case InputAxis.MainTrigger: return(lastState.rAxis1.x); case InputAxis.Grip: return((lastState.ulButtonPressed & (1ul << (int)EVRButtonId.k_EButton_Grip)) != 0 ? 1 : 0); case InputAxis.JoypadX: return(lastState.rAxis0.x); case InputAxis.JoypadY: return(lastState.rAxis0.y); case InputAxis.Joypad: return((lastState.ulButtonPressed & (1ul << (int)EVRButtonId.k_EButton_SteamVR_Touchpad)) != 0 ? 1 : 0); case InputAxis.Application: return((lastState.ulButtonPressed & (1ul << (int)EVRButtonId.k_EButton_ApplicationMenu)) != 0 ? 1 : 0); default: throw new ArgumentOutOfRangeException("axis", axis, null); } }
private void UpdatePreCull(Camera cam) { if (lastFrame == Time.frameCount) { return; } lastFrame = Time.frameCount; InputTracking.GetNodeStates(states); for (int i = 0; i < states.Count; i++) { //Debug.Log("A thing: " + states[i].nodeType + " and " + InputTracking.GetNodeName(states[i].uniqueID)); if (states[i].nodeType != hand) { continue; } nodeState = states[i]; var pose = input.GetPose(nodeState); transform.localPosition = pose.pos; transform.localRotation = pose.rot; if (visualization) { visualization.SetActive(Tracked = nodeState.tracked); } } }
/// <summary> /// Collects the position of the HMD with a timestamp, to be looked up later to correct for latency. /// </summary> public void CollectPose() { if (manager == null) { return; } KeyPose k = new KeyPose(); #if UNITY_2019_1_OR_NEWER InputTracking.GetNodeStates(nodeStates); XRNodeState nodeState = nodeStates.Find(node => node.nodeType == XRNode.Head); nodeState.TryGetRotation(out k.Orientation); nodeState.TryGetPosition(out k.Translation); #else k.Orientation = InputTracking.GetLocalRotation(XRNode.Head); k.Translation = InputTracking.GetLocalPosition(XRNode.Head); #endif if (manager.zedCamera.IsCameraReady) { k.Timestamp = manager.zedCamera.GetCurrentTimeStamp(); if (k.Timestamp >= 0) { dllz_latency_corrector_add_key_pose(ref k.Translation, ref k.Orientation, k.Timestamp); //Poses are handled by the wrapper. } } }
protected void Direct_ReadState(XRNodeState node) { if (OpenVR.System == null) { Debug.LogWarning("OpenVR not active"); direct_lastState = default(VRControllerState_t); return; } var controllerId = GetDeviceId(node); if (controllerId < 0) { direct_lastState = default(VRControllerState_t); return; } //Debug.Log("Id is " + controllerId); var res = OpenVR.System.GetControllerState( (uint)controllerId, ref direct_lastState, (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VRControllerState_t)) ); if (!res) { Debug.LogWarning("Failed to get controller state"); } }
public static JoyPadType GetJoypadType(XRNodeState node) { JoyPadType ret; if (!nodeTypes.TryGetValue(node.uniqueID, out ret)) { ret = JoyPadType.None; if (impl == null) { impl = GetImpl(); } var name = impl.GetNodeName(node); if (name.Contains("Oculus Touch Controller") || name.StartsWith("Oculus Rift CV1")) { //OpenVR gives us "Oculus Rift CV1 (Left Controller)" etc. where I wish it would mention the type of controller (Touch) ret = JoyPadType.Joystick; } else if (name.StartsWith("Vive Controller")) { ret = JoyPadType.TouchPad; } else { Debug.LogWarning("Unknown controller type: " + name); } nodeTypes[node.uniqueID] = ret; } return(ret); }
private void TryCheckNodeState(TrackingAnchor anchor, XRNode xRNode) { XRNodeState xRNodeState = default(XRNodeState); for (int i = xRNodeStates.Count - 1; i >= 0; i--) { var nodeState = xRNodeStates[i]; if (nodeState.nodeType == xRNode) { if (nodeState.uniqueID == anchor.uniqueID) { return; } if (xRNodeState.uniqueID == 0) { xRNodeState = nodeState; } if (!anchor.connected) { InputTracking_nodeAdded(anchor, ref nodeState); return; } } } if (anchor.connected) { InputTracking_nodeRemoved(anchor); } if (xRNodeState.uniqueID > 0) { InputTracking_nodeAdded(anchor, ref xRNodeState); } }
public override float GetAxis(XRNodeState node, InputAxis axis) { var controller = GetController(node); OVRPlugin.ControllerState4 state = OVRPlugin.GetControllerState4((uint)controller); switch (axis) { case InputAxis.LeftClick: return(controller == OVRInput.Controller.LTouch ? state.LIndexTrigger : state.RIndexTrigger); case InputAxis.RightClick: return(controller == OVRInput.Controller.LTouch ? state.LHandTrigger : state.RHandTrigger); case InputAxis.MiddleClick: { var buttonId = controller == OVRInput.Controller.LTouch ? 0x00000400 : 0x00000004; //see enum ovrButton_ in OVR_CAPI.h return((state.Buttons & buttonId) != 0 ? 1 : 0); } case InputAxis.JoyStickX: case InputAxis.JoyStickY: { var joy = controller == OVRInput.Controller.LTouch ? state.LThumbstick : state.RThumbstick; return(axis == InputAxis.JoyStickX ? joy.x : joy.y); } default: return(0); } }
// handle reconnected device private void _OnNodeAdded(XRNodeState obj) { Debug.Log("Node added " + obj.nodeType); if (obj.nodeType == _XRNode) { _Init(); } }
private void OnTrackingChange(XRNodeState obj) { if (obj.nodeType == XRNode.RightHand) { _rightHandTracked = obj.tracked; ResetRightHandPointer(); } }
/// <summary> /// If the controller is capable, returns if (and sometimes how closely) the player is touching /// the given control. /// </summary> /// <param name="node"></param> /// <param name="axis"></param> /// <returns></returns> public static float GetTouch(XRNodeState node, InputAxis axis) { if (impl == null) { impl = GetImpl(); } return(impl.GetTouchValue(node, axis)); }
// handle reconnected device private void _OnNodeAdded(XRNodeState obj) { if (obj.nodeType == XRNode) { Debug.Log("Node added " + obj.nodeType); _InitDevice(); } }
// handle disonnected device private void _OnNodeRemoved(XRNodeState obj) { if (obj.nodeType == XRNode) { ShowHandModel(false); ShowRayPointer(false); } }
private void TrackingLost(XRNodeState xrNodeState) { var job = new TrackJob { state = xrNodeState, command = _trackingBarrier.CreateCommandBuffer(), tracked = false }; job.ScheduleSingle(this).Complete(); }
/// <summary> /// Returns where the hand is pointing right now. (z+ forward) /// </summary> /// <param name="node"></param> /// <returns></returns> public virtual Pose GetPose(XRNodeState node) { Pose ret = new Pose(); node.TryGetPosition(out ret.pos); node.TryGetRotation(out ret.rot); return(ret); }
void Update() { if (NodeTitle_Text != null) { NodeTitle_Text.text = m_Node.ToString(); } var nodeStates = new List <XRNodeState>(); UnityEngine.XR.InputTracking.GetNodeStates(nodeStates); XRNodeState?state = null; foreach (XRNodeState nodeState in nodeStates) { if (nodeState.nodeType == m_Node) { state = nodeState; break; } } if (state.HasValue) { XRNodeState node = state.Value; Vector3 tempVector; Quaternion tempQuaternion; // Translation Information SetImageColor(Position_Image, node.TryGetPosition(out tempVector)); Position_Text.text = Vector3ToFieldText(tempVector); SetImageColor(Velocity_Image, node.TryGetVelocity(out tempVector)); Velocity_Text.text = Vector3ToFieldText(tempVector); SetImageColor(Acceleration_Image, node.TryGetAcceleration(out tempVector)); Acceleration_Text.text = Vector3ToFieldText(tempVector); // Rotation Information SetImageColor(Rotation_Image, node.TryGetRotation(out tempQuaternion)); Rotation_Text.text = QuaternionToFieldText(tempQuaternion); SetImageColor(AngularVelocity_Image, node.TryGetAngularVelocity(out tempVector)); AngularVelocity_Text.text = Vector3ToFieldText(tempVector); SetImageColor(AngularAcceleration_Image, node.TryGetAngularAcceleration(out tempVector)); AngularAcceleration_Text.text = Vector3ToFieldText(tempVector); } else { // Translation Information SetImageColor(Position_Image, false); SetImageColor(Velocity_Image, false); SetImageColor(Acceleration_Image, false); // Rotation Information SetImageColor(Rotation_Image, false); SetImageColor(AngularVelocity_Image, false); SetImageColor(AngularAcceleration_Image, false); } }
public static bool TryGetNodeState(XRNode node, out XRNodeState nodeState) { List <XRNodeState> nodeStates = new List <XRNodeState>(); InputTracking.GetNodeStates(nodeStates); nodeState = nodeStates.Where(p => p.nodeType == node).FirstOrDefault(); return(nodeState.tracked); }
/// <summary> /// Update the "Controller" input from the device /// </summary> protected void UpdateControllerData(XRNodeState state) { Profiler.BeginSample("[MRTK] GenericOpenVRController.UpdateControllerData"); var lastState = TrackingState; LastControllerPose = CurrentControllerPose; if (nodeType == XRNode.LeftHand || nodeType == XRNode.RightHand) { // The source is either a hand or a controller that supports pointing. // We can now check for position and rotation. IsPositionAvailable = state.TryGetPosition(out CurrentControllerPosition); IsPositionApproximate = false; IsRotationAvailable = state.TryGetRotation(out CurrentControllerRotation); // Devices are considered tracked if we receive position OR rotation data from the sensors. TrackingState = (IsPositionAvailable || IsRotationAvailable) ? TrackingState.Tracked : TrackingState.NotTracked; CurrentControllerPosition = MixedRealityPlayspace.TransformPoint(CurrentControllerPosition); CurrentControllerRotation = MixedRealityPlayspace.Rotation * CurrentControllerRotation; } else { // The input source does not support tracking. TrackingState = TrackingState.NotApplicable; } CurrentControllerPose.Position = CurrentControllerPosition; CurrentControllerPose.Rotation = CurrentControllerRotation; // Raise input system events if it is enabled. if (lastState != TrackingState) { CoreServices.InputSystem?.RaiseSourceTrackingStateChanged(InputSource, this, TrackingState); } if (TrackingState == TrackingState.Tracked && LastControllerPose != CurrentControllerPose) { if (IsPositionAvailable && IsRotationAvailable) { CoreServices.InputSystem?.RaiseSourcePoseChanged(InputSource, this, CurrentControllerPose); } else if (IsPositionAvailable && !IsRotationAvailable) { CoreServices.InputSystem?.RaiseSourcePositionChanged(InputSource, this, CurrentControllerPosition); } else if (!IsPositionAvailable && IsRotationAvailable) { CoreServices.InputSystem?.RaiseSourceRotationChanged(InputSource, this, CurrentControllerRotation); } } Profiler.EndSample(); // UpdateControllerData }
public static Quaternion?Rotation(this XRNodeState s) { Quaternion result; if (s.TryGetRotation(out result)) { return(result); } return(null); }
private void InputTracking_trackingAcquired(XRNodeState nodeState) { XRUserController controller = _userControllers.Find(x => x.UniqueID == nodeState.uniqueID); if (controller != null) { Debug.Log("InputTracking_trackingAcquired " + controller + " " + nodeState.uniqueID + " " + nodeState.nodeType); _registrationEvents.TrackingAcquired.Invoke(controller); } }
void InputTracking_trackingAcquired(XRNodeState obj) { InputTracking.trackingAcquired -= InputTracking_trackingAcquired; defaultHeadRotationInverse = Quaternion.Inverse(mainCam.transform.rotation); basisVec = mainCam.transform.forward; basisVec.y = 0.0f; basisVec = basisVec.normalized * radius; }