From 391ffcb2ff08fb6ca73e7aedd4ef31a4586b0219 Mon Sep 17 00:00:00 2001 From: Andy Baker Date: Wed, 2 Oct 2024 16:24:58 +0100 Subject: [PATCH] Fix detection and model display for stylus --- Assets/Scenes/Main.unity | 25 ++++--- Assets/Scripts/GUI/BrushSettingsTray.cs | 42 +++++++---- Assets/Scripts/Input/UnityXRControllerInfo.cs | 35 ++++----- Assets/Scripts/InputManager.cs | 5 ++ Assets/ThirdParty/Logitech/MX_Ink.prefab | 71 ++++++++++++------- .../Logitech/Scripts/StylusHandler.cs | 6 +- .../Logitech/Scripts/VrStylusHandler.cs | 19 ++++- 7 files changed, 125 insertions(+), 78 deletions(-) diff --git a/Assets/Scenes/Main.unity b/Assets/Scenes/Main.unity index ba550ea9b4..5aea0e0c22 100644 --- a/Assets/Scenes/Main.unity +++ b/Assets/Scenes/Main.unity @@ -714,7 +714,7 @@ MonoBehaviour: lensDirtScatterFactor: 0.5 lensDirtIntensity: 0.05 lensDirtTexture: {fileID: 0} - inputIsHDR: 1 + inputIsHDR: 0 lowQuality: 1 depthBlending: 0 depthBlendFunction: 0 @@ -17110,6 +17110,10 @@ PrefabInstance: m_RemovedComponents: [] m_RemovedGameObjects: [] m_AddedGameObjects: + - targetCorrespondingSourceObject: {fileID: 4000013585580318, guid: dedd7823645ca60468aca5f2ff1b9a7f, + type: 3} + insertIndex: -1 + addedObject: {fileID: 1814796582} - targetCorrespondingSourceObject: {fileID: 4000011853176074, guid: dedd7823645ca60468aca5f2ff1b9a7f, type: 3} insertIndex: -1 @@ -30859,6 +30863,12 @@ MeshRenderer: type: 3} m_PrefabInstance: {fileID: 2124612094} m_PrefabAsset: {fileID: 0} +--- !u!4 &1814796582 stripped +Transform: + m_CorrespondingSourceObject: {fileID: 1857229286467065778, guid: cb1310f64dd794703964833b63e87d96, + type: 3} + m_PrefabInstance: {fileID: 1971022075} + m_PrefabAsset: {fileID: 0} --- !u!1 &1815866264 GameObject: m_ObjectHideFlags: 0 @@ -33202,7 +33212,7 @@ PrefabInstance: serializedVersion: 2 m_Modification: serializedVersion: 3 - m_TransformParent: {fileID: 0} + m_TransformParent: {fileID: 17776369} m_Modifications: - target: {fileID: 1077171487981709975, guid: cb1310f64dd794703964833b63e87d96, type: 3} @@ -33232,17 +33242,17 @@ PrefabInstance: - target: {fileID: 1857229286467065778, guid: cb1310f64dd794703964833b63e87d96, type: 3} propertyPath: m_LocalRotation.x - value: 0 + value: -0 objectReference: {fileID: 0} - target: {fileID: 1857229286467065778, guid: cb1310f64dd794703964833b63e87d96, type: 3} propertyPath: m_LocalRotation.y - value: 0 + value: -0 objectReference: {fileID: 0} - target: {fileID: 1857229286467065778, guid: cb1310f64dd794703964833b63e87d96, type: 3} propertyPath: m_LocalRotation.z - value: 0 + value: -0 objectReference: {fileID: 0} - target: {fileID: 1857229286467065778, guid: cb1310f64dd794703964833b63e87d96, type: 3} @@ -33606,7 +33616,7 @@ MonoBehaviour: lensDirtScatterFactor: 0.5 lensDirtIntensity: 0.05 lensDirtTexture: {fileID: 0} - inputIsHDR: 1 + inputIsHDR: 0 lowQuality: 1 depthBlending: 0 depthBlendFunction: 0 @@ -34509,7 +34519,7 @@ MonoBehaviour: lensDirtScatterFactor: 0.5 lensDirtIntensity: 0.05 lensDirtTexture: {fileID: 0} - inputIsHDR: 1 + inputIsHDR: 0 lowQuality: 1 depthBlending: 0 depthBlendFunction: 0 @@ -36944,4 +36954,3 @@ SceneRoots: - {fileID: 1802399861} - {fileID: 106206546} - {fileID: 1848773840} - - {fileID: 1971022075} diff --git a/Assets/Scripts/GUI/BrushSettingsTray.cs b/Assets/Scripts/GUI/BrushSettingsTray.cs index 973f637906..a7064ca565 100644 --- a/Assets/Scripts/GUI/BrushSettingsTray.cs +++ b/Assets/Scripts/GUI/BrushSettingsTray.cs @@ -12,7 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System; using UnityEngine; +using UnityEngine.XR; namespace TiltBrush { @@ -32,6 +34,29 @@ protected override void OnDestroy() App.Switchboard.ToolChanged -= UpdateSliderToMatchCurrentSize; } + private void DetectSupportedDevices() + { + // Currently only the Logitech stylus needs this panel + bool needsBrushSizeUI = VrStylusHandler.m_Instance.CurrentState.isActive; + + // DoAnimateIn performs a toggle so we have to also check the state + if (needsBrushSizeUI) + { + if (!m_AnimateIn) + { + DoAnimateIn(); + UpdateSliderToMatchCurrentSize(); + } + } + else + { + if (m_AnimateIn) + { + DoAnimateIn(); + } + } + } + private void UpdateSliderToMatchCurrentSize() { m_BrushSizeSlider.SetInitialValueAndUpdate( @@ -43,21 +68,8 @@ protected override void Start() { base.Start(); - bool needsBrushSizeUi = false; - -#if OCULUS_SUPPORTED - const string suffix = "mx_ink_stylus_logitech"; - var leftDeviceName = OVRPlugin.GetCurrentInteractionProfileName(OVRPlugin.Hand.HandLeft); - var rightDeviceName = OVRPlugin.GetCurrentInteractionProfileName(OVRPlugin.Hand.HandRight); - needsBrushSizeUi = leftDeviceName.EndsWith(suffix) || rightDeviceName.EndsWith(suffix); -#endif - - if (needsBrushSizeUi) - { - DoAnimateIn(); - } - - UpdateSliderToMatchCurrentSize(); + // Call DetectSupportedDevice every second + InvokeRepeating(nameof(DetectSupportedDevices), 0.0f, 1); } protected override void OnToolChanged() diff --git a/Assets/Scripts/Input/UnityXRControllerInfo.cs b/Assets/Scripts/Input/UnityXRControllerInfo.cs index 11ca9dbcb6..ad69ab4043 100644 --- a/Assets/Scripts/Input/UnityXRControllerInfo.cs +++ b/Assets/Scripts/Input/UnityXRControllerInfo.cs @@ -24,13 +24,13 @@ public class UnityXRControllerInfo : ControllerInfo private UnityEngine.XR.InputDevice device; private readonly UnityXRInputAction actionSet = new(); - private VrStylusHandler _logitechMxInk; - private Vector2 padAxisPrevious = new Vector2(); private const float kInputScrollScalar = 0.5f; private bool isBrush = false; + private StylusInputs stylusState => VrStylusHandler.m_Instance.CurrentState; + private string actionMap { get => isBrush ? "Brush" : "Wand"; @@ -53,21 +53,10 @@ private void Init() { device = InputDevices.GetDeviceAtXRNode(isBrush ? XRNode.RightHand : XRNode.LeftHand); SetActionMask(); - _logitechMxInk = null; if (isBrush) { actionSet.Brush.Enable(); actionSet.Wand.Disable(); - - try - { - _logitechMxInk = UnityEngine.Object.FindObjectsOfType()[0]; - } - catch (Exception) - { - _logitechMxInk = null; - } - } else { @@ -190,9 +179,9 @@ public override float GetScrollYDelta() public override float GetGripValue() { #if OCULUS_SUPPORTED - if (_logitechMxInk && _logitechMxInk.CurrentState.isActive) + if (stylusState.isActive) { - return _logitechMxInk.CurrentState.cluster_front_value ? 1.0f : 0; + return stylusState.cluster_front_value ? 1.0f : 0; } #endif return FindAction("GripAxis").ReadValue(); @@ -206,9 +195,9 @@ public override float GetTriggerRatio() public override float GetTriggerValue() { #if OCULUS_SUPPORTED - if (_logitechMxInk && _logitechMxInk.CurrentState.isActive) + if (stylusState.isActive) { - return Math.Max(_logitechMxInk.CurrentState.tip_value, _logitechMxInk.CurrentState.cluster_middle_value); + return Math.Max(stylusState.tip_value, stylusState.cluster_middle_value); } #endif return FindAction("TriggerAxis").ReadValue(); @@ -254,22 +243,22 @@ private bool MapVrInput(VrInput input) return FindAction("PadButton").IsPressed(); case VrInput.Trigger: #if OCULUS_SUPPORTED - if (_logitechMxInk && _logitechMxInk.CurrentState.isActive) - return _logitechMxInk.CurrentState.cluster_middle_value > 0.2 || _logitechMxInk.CurrentState.tip_value > 0.2; + if (stylusState.isActive) + return stylusState.cluster_middle_value > 0.2 || stylusState.tip_value > 0.2; #endif return FindAction("TriggerAxis").IsPressed(); case VrInput.Grip: #if OCULUS_SUPPORTED - if (_logitechMxInk && _logitechMxInk.CurrentState.isActive) - return _logitechMxInk.CurrentState.cluster_front_value; + if (stylusState.isActive) + return stylusState.cluster_front_value; #endif return FindAction("GripAxis").IsPressed(); case VrInput.Button01: case VrInput.Button04: case VrInput.Button06: #if OCULUS_SUPPORTED - if (_logitechMxInk && _logitechMxInk.CurrentState.isActive) - return _logitechMxInk.CurrentState.cluster_back_value; + if (stylusState.isActive) + return stylusState.cluster_back_value; #endif return FindAction("PrimaryButton").IsPressed(); case VrInput.Button02: diff --git a/Assets/Scripts/InputManager.cs b/Assets/Scripts/InputManager.cs index 666a87181b..e0b898a0fe 100644 --- a/Assets/Scripts/InputManager.cs +++ b/Assets/Scripts/InputManager.cs @@ -457,6 +457,11 @@ public void ShowControllers(bool show) } } + public void ShowController(bool show, int index) + { + m_ControllerInfos[index].ShowController(m_ControllerInfos[index].IsTrackedObjectValid && show); + } + void OnDestroy() { App.VrSdk.OnNewControllerPosesApplied -= OnControllerPosesApplied; diff --git a/Assets/ThirdParty/Logitech/MX_Ink.prefab b/Assets/ThirdParty/Logitech/MX_Ink.prefab index 56e44308b3..74db569f72 100644 --- a/Assets/ThirdParty/Logitech/MX_Ink.prefab +++ b/Assets/ThirdParty/Logitech/MX_Ink.prefab @@ -50,8 +50,6 @@ MonoBehaviour: _cluster_front: {fileID: 689178473153335378} _cluster_middle: {fileID: 8881577570454616313} _cluster_back: {fileID: 4121183609491545851} - _left_touch_controller: {fileID: 0} - _right_touch_controller: {fileID: 0} active_color: {r: 0.6886792, g: 0.6886792, b: 0.6886792, a: 1} double_tap_active_color: {r: 0, g: 1, b: 1, a: 1} default_color: {r: 0.14150941, g: 0.13550194, b: 0.13550194, a: 1} @@ -63,55 +61,74 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 1857229286467065778} m_Modifications: - - target: {fileID: 1324109529956063243, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + - target: {fileID: 1324109529956063243, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: m_Name value: logitech_vr_stylus_v1.0 objectReference: {fileID: 0} - - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} - propertyPath: m_LocalPosition.x + - target: {fileID: 1324109529956063243, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} + propertyPath: m_IsActive value: 0 objectReference: {fileID: 0} - - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} + propertyPath: m_LocalPosition.x + value: 0.0075 + objectReference: {fileID: 0} + - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: m_LocalPosition.y - value: 0 + value: -0.003 objectReference: {fileID: 0} - - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: m_LocalPosition.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: m_LocalRotation.w value: 1 objectReference: {fileID: 0} - - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: m_LocalRotation.x value: 0 objectReference: {fileID: 0} - - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: m_LocalRotation.y value: 0 objectReference: {fileID: 0} - - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: m_LocalRotation.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: m_LocalEulerAnglesHint.x value: 0 objectReference: {fileID: 0} - - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: m_LocalEulerAnglesHint.y value: 0 objectReference: {fileID: 0} - - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + - target: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - - target: {fileID: 4379063982285912482, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + - target: {fileID: 4379063982285912482, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: hapticClip value: - objectReference: {fileID: 2460798210113038985, guid: dde55e13c542f48c186587cca063eac8, type: 3} - - target: {fileID: 4379063982285912482, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + objectReference: {fileID: 2460798210113038985, guid: dde55e13c542f48c186587cca063eac8, + type: 3} + - target: {fileID: 4379063982285912482, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} propertyPath: legacy_mode value: 0 objectReference: {fileID: 0} @@ -122,31 +139,37 @@ PrefabInstance: m_SourcePrefab: {fileID: 100100000, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} --- !u!1 &689178473153335378 stripped GameObject: - m_CorrespondingSourceObject: {fileID: 9031821886481021817, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + m_CorrespondingSourceObject: {fileID: 9031821886481021817, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} m_PrefabInstance: {fileID: 8414709874766261035} m_PrefabAsset: {fileID: 0} --- !u!1 &4121183609491545851 stripped GameObject: - m_CorrespondingSourceObject: {fileID: 5617797037434992080, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + m_CorrespondingSourceObject: {fileID: 5617797037434992080, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} m_PrefabInstance: {fileID: 8414709874766261035} m_PrefabAsset: {fileID: 0} --- !u!1 &4338285541321202723 stripped GameObject: - m_CorrespondingSourceObject: {fileID: 5256723013491226376, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + m_CorrespondingSourceObject: {fileID: 5256723013491226376, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} m_PrefabInstance: {fileID: 8414709874766261035} m_PrefabAsset: {fileID: 0} --- !u!1 &7396916743439364896 stripped GameObject: - m_CorrespondingSourceObject: {fileID: 1324109529956063243, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + m_CorrespondingSourceObject: {fileID: 1324109529956063243, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} m_PrefabInstance: {fileID: 8414709874766261035} m_PrefabAsset: {fileID: 0} --- !u!4 &7920969980687411610 stripped Transform: - m_CorrespondingSourceObject: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + m_CorrespondingSourceObject: {fileID: 1813822785949909681, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} m_PrefabInstance: {fileID: 8414709874766261035} m_PrefabAsset: {fileID: 0} --- !u!1 &8881577570454616313 stripped GameObject: - m_CorrespondingSourceObject: {fileID: 1118790130344924114, guid: 90df24c7a15784ca7a0a300d072cba39, type: 3} + m_CorrespondingSourceObject: {fileID: 1118790130344924114, guid: 90df24c7a15784ca7a0a300d072cba39, + type: 3} m_PrefabInstance: {fileID: 8414709874766261035} m_PrefabAsset: {fileID: 0} diff --git a/Assets/ThirdParty/Logitech/Scripts/StylusHandler.cs b/Assets/ThirdParty/Logitech/Scripts/StylusHandler.cs index d70515e9f5..88654b0752 100644 --- a/Assets/ThirdParty/Logitech/Scripts/StylusHandler.cs +++ b/Assets/ThirdParty/Logitech/Scripts/StylusHandler.cs @@ -1,7 +1,6 @@ using UnityEngine; -#if OCULUS_SUPPORTED -public struct StylusInputs +public class StylusInputs { public float tip_value; public bool cluster_front_value; @@ -17,11 +16,9 @@ public struct StylusInputs public bool isOnRightHand; public bool docked; } -#endif public abstract class StylusHandler : MonoBehaviour { -#if OCULUS_SUPPORTED protected StylusInputs _stylus; public StylusInputs CurrentState @@ -33,5 +30,4 @@ public virtual bool CanDraw() { return true; } -#endif } diff --git a/Assets/ThirdParty/Logitech/Scripts/VrStylusHandler.cs b/Assets/ThirdParty/Logitech/Scripts/VrStylusHandler.cs index 022f113f88..97e5d7ef55 100644 --- a/Assets/ThirdParty/Logitech/Scripts/VrStylusHandler.cs +++ b/Assets/ThirdParty/Logitech/Scripts/VrStylusHandler.cs @@ -1,15 +1,24 @@ using UnityEngine; using System; +using TiltBrush; public class VrStylusHandler : StylusHandler { -#if OCULUS_SUPPORTED [SerializeField] private GameObject _mxInk_model; [SerializeField] private GameObject _tip; [SerializeField] private GameObject _cluster_front; [SerializeField] private GameObject _cluster_middle; [SerializeField] private GameObject _cluster_back; + static public VrStylusHandler m_Instance; + + void Awake() + { + _stylus = new StylusInputs(); + m_Instance = this; + } + +#if OCULUS_SUPPORTED private bool _inUiInteraction = false; public bool InUiInteraction @@ -29,6 +38,7 @@ public bool positionIsValid { get { return _positionIsValid; } } + public Color active_color = Color.green; public Color double_tap_active_color = Color.cyan; public Color default_color = Color.white; @@ -72,12 +82,15 @@ private void UpdatePose() // Find whether the Logitech MX Ink is on the left or the right hand bool stylusIsOnLeftHand = leftDevice.Contains("logitech"); bool stylusIsOnRightHand = rightDevice.Contains("logitech"); - + // Debug.Log($"Device: Left hand: {leftDevice}, Right hand: {rightDevice}"); // Flag the stylus as active/inactive, on right/left hand _stylus.isActive = stylusIsOnLeftHand || stylusIsOnRightHand; _stylus.isOnRightHand = stylusIsOnRightHand; // Hide the 3D model if not active _mxInk_model.SetActive(_stylus.isActive); + // Hacky + InputManager.m_Instance.ShowController(!_stylus.isActive, stylusIsOnLeftHand ? 0 : 1); + InputManager.m_Instance.ShowController(true, stylusIsOnLeftHand ? 1 : 0); // Select the right/left hand stylus pose to be used string MX_Ink_Pose = _stylus.isOnRightHand ? MX_Ink_Pose_Right : MX_Ink_Pose_Left; @@ -97,7 +110,7 @@ private void UpdatePose() } } - void Update() + void LateUpdate() { OVRInput.Update(); UpdatePose();