Skip to content

Commit a20158f

Browse files
author
David Kline
authored
Merge pull request #3003 from StephenHodgson/vNEXT-OpenVR-MouseInputFixes
Mouse Input Fixes
2 parents 0df80d9 + 9f354b3 commit a20158f

File tree

14 files changed

+238
-86
lines changed

14 files changed

+238
-86
lines changed

Assets/MixedRealityToolkit-SDK/Features/Input/Handlers/ControllerPoseSynchronizer.cs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,8 @@ public virtual void OnSourceDetected(SourceStateEventData eventData) { }
9696
/// <inheritdoc />
9797
public virtual void OnSourceLost(SourceStateEventData eventData)
9898
{
99-
if (Controller == null ||
100-
eventData.Controller == null ||
101-
eventData.Controller.InputSource.SourceId != Controller.InputSource.SourceId)
102-
{
103-
return;
104-
}
105-
106-
if (eventData.Controller?.ControllerHandedness == Handedness)
99+
if (eventData.SourceId == Controller?.InputSource.SourceId &&
100+
eventData.Controller?.ControllerHandedness == Handedness)
107101
{
108102
IsTracked = false;
109103
TrackingState = TrackingState.NotTracked;
@@ -125,7 +119,7 @@ public virtual void OnSourceLost(SourceStateEventData eventData)
125119
/// <inheritdoc />
126120
public virtual void OnSourcePoseChanged(SourcePoseEventData<TrackingState> eventData)
127121
{
128-
if (eventData.SourceData != TrackingState)
122+
if (eventData.SourceId == Controller?.InputSource.SourceId)
129123
{
130124
IsTracked = eventData.SourceData == TrackingState.Tracked;
131125
TrackingState = eventData.SourceData;
@@ -144,17 +138,13 @@ public virtual void OnSourcePoseChanged(SourcePoseEventData<Quaternion> eventDat
144138
/// <inheritdoc />
145139
public virtual void OnSourcePoseChanged(SourcePoseEventData<MixedRealityPose> eventData)
146140
{
147-
if (Controller == null ||
148-
eventData.Controller == null ||
149-
eventData.Controller.InputSource.SourceId != Controller.InputSource.SourceId)
150-
{
151-
return;
152-
}
153-
154-
if (UseSourcePoseData && TrackingState == TrackingState.Tracked)
141+
if (eventData.SourceId == Controller?.InputSource.SourceId)
155142
{
156-
transform.localPosition = eventData.SourceData.Position;
157-
transform.localRotation = eventData.SourceData.Rotation;
143+
if (UseSourcePoseData && TrackingState == TrackingState.Tracked)
144+
{
145+
transform.localPosition = eventData.SourceData.Position;
146+
transform.localRotation = eventData.SourceData.Rotation;
147+
}
158148
}
159149
}
160150

Assets/MixedRealityToolkit-SDK/Features/UX/Prefabs/Pointers/MousePointer.prefab

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ Prefab:
88
m_TransformParent: {fileID: 0}
99
m_Modifications: []
1010
m_RemovedComponents: []
11-
m_ParentPrefab: {fileID: 0}
11+
m_SourcePrefab: {fileID: 0}
1212
m_RootGameObject: {fileID: 1247086986094436}
13-
m_IsPrefabParent: 1
13+
m_IsPrefabAsset: 1
1414
--- !u!1 &1247086986094436
1515
GameObject:
1616
m_ObjectHideFlags: 0
17-
m_PrefabParentObject: {fileID: 0}
17+
m_CorrespondingSourceObject: {fileID: 0}
1818
m_PrefabInternal: {fileID: 100100000}
19-
serializedVersion: 5
19+
serializedVersion: 6
2020
m_Component:
2121
- component: {fileID: 4215223911988956}
2222
- component: {fileID: 114035756607602504}
@@ -30,7 +30,7 @@ GameObject:
3030
--- !u!4 &4215223911988956
3131
Transform:
3232
m_ObjectHideFlags: 1
33-
m_PrefabParentObject: {fileID: 0}
33+
m_CorrespondingSourceObject: {fileID: 0}
3434
m_PrefabInternal: {fileID: 100100000}
3535
m_GameObject: {fileID: 1247086986094436}
3636
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
@@ -43,7 +43,7 @@ Transform:
4343
--- !u!114 &114035756607602504
4444
MonoBehaviour:
4545
m_ObjectHideFlags: 1
46-
m_PrefabParentObject: {fileID: 0}
46+
m_CorrespondingSourceObject: {fileID: 0}
4747
m_PrefabInternal: {fileID: 100100000}
4848
m_GameObject: {fileID: 1247086986094436}
4949
m_Enabled: 1
@@ -55,11 +55,13 @@ MonoBehaviour:
5555
destroyOnSourceLost: 0
5656
useSourcePoseData: 1
5757
poseAction:
58-
id: 0
59-
description: None
60-
axisConstraint: 0
58+
id: 12
59+
description: Mouse Delta
60+
axisConstraint: 4
6161
cursorPrefab: {fileID: 1151083198953756, guid: 667821d88830305449757690d22f71e0,
6262
type: 2}
63+
disableCursorOnStart: 1
64+
setCursorVisibilityOnSourceDetected: 0
6365
raycastOrigin: {fileID: 0}
6466
activeHoldAction:
6567
id: 0
@@ -73,3 +75,6 @@ MonoBehaviour:
7375
overrideGlobalPointerExtent: 0
7476
pointerExtent: 10
7577
pointerOrientation: 0
78+
hideCursorWhenInactive: 1
79+
movementThresholdToUnHide: 0.5
80+
hideTimeout: 3

Assets/MixedRealityToolkit-SDK/Features/UX/Scripts/Cursors/BaseCursor.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ public virtual void SetVisibility(bool visible)
110110
}
111111
}
112112

113+
/// <inheritdoc />
114+
public bool IsVisible => PrimaryCursorVisual != null ? PrimaryCursorVisual.gameObject.activeInHierarchy : gameObject.activeInHierarchy;
115+
113116
/// <inheritdoc />
114117
public bool SetVisibilityOnSourceDetected { get; set; } = false;
115118

@@ -322,7 +325,6 @@ protected virtual void UpdateCursorTransform()
322325
if (newTargetedObject == null)
323326
{
324327
TargetedObject = null;
325-
326328
targetPosition = RayStep.GetPointByDistance(Pointer.Rays, defaultCursorDistance);
327329
lookForward = -RayStep.GetDirectionByDistance(Pointer.Rays, defaultCursorDistance);
328330
targetRotation = lookForward.magnitude > 0 ? Quaternion.LookRotation(lookForward, Vector3.up) : transform.rotation;

Assets/MixedRealityToolkit-SDK/Features/UX/Scripts/Cursors/MeshCursor.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ private void SetCursorState(MeshCursorDatum stateDatum)
7878
// Return if we do not have an animator
7979
if (TargetRenderer != null)
8080
{
81-
MeshFilter mf = TargetRenderer.gameObject.GetComponent<MeshFilter>();
82-
if (mf != null && stateDatum.CursorMesh != null)
81+
var filter = TargetRenderer.gameObject.GetComponent<MeshFilter>();
82+
if (filter != null && stateDatum.CursorMesh != null)
8383
{
84-
mf.mesh = stateDatum.CursorMesh;
84+
filter.mesh = stateDatum.CursorMesh;
8585
}
8686

8787
TargetRenderer.transform.localPosition = stateDatum.LocalOffset;

Assets/MixedRealityToolkit-SDK/Features/UX/Scripts/Pointers/BaseControllerPointer.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public abstract class BaseControllerPointer : ControllerPoseSynchronizer, IMixed
3030
[SerializeField]
3131
private bool disableCursorOnStart = false;
3232

33+
protected bool DisableCursorOnStart => disableCursorOnStart;
34+
3335
[SerializeField]
3436
private bool setCursorVisibilityOnSourceDetected = false;
3537

@@ -163,7 +165,7 @@ protected override void OnDisable()
163165

164166
#region IMixedRealityPointer Implementation
165167

166-
/// <inheritdoc />
168+
/// <inheritdoc cref="IMixedRealityController" />
167169
public override IMixedRealityController Controller
168170
{
169171
get { return base.Controller; }

Assets/MixedRealityToolkit-SDK/Features/UX/Scripts/Pointers/MousePointer.cs

Lines changed: 131 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,43 @@ namespace Microsoft.MixedReality.Toolkit.SDK.UX.Pointers
1717
/// </summary>
1818
public class MousePointer : BaseControllerPointer, IMixedRealityMousePointer
1919
{
20-
private Vector3 newRotation = Vector3.zero;
20+
private float timeoutTimer = 0.0f;
2121

2222
private bool isInteractionEnabled = false;
2323

24+
private bool cursorWasDisabledOnDown = false;
25+
26+
private bool isDisabled = true;
27+
28+
#region IMixedRealityMousePointer Implementaiton
29+
30+
[SerializeField]
31+
[Tooltip("Should the mouse cursor be hidden when no active input is received?")]
32+
private bool hideCursorWhenInactive = true;
33+
34+
/// <inheritdoc />
35+
bool IMixedRealityMousePointer.HideCursorWhenInactive => hideCursorWhenInactive;
36+
37+
[SerializeField]
38+
[Range(0.01f, 1f)]
39+
[Tooltip("What is the movement threshold to reach before un-hiding mouse cursor?")]
40+
private float movementThresholdToUnHide = 0.1f;
41+
42+
/// <inheritdoc />
43+
float IMixedRealityMousePointer.MovementThresholdToUnHide => movementThresholdToUnHide;
44+
45+
[SerializeField]
46+
[Range(0f, 10f)]
47+
[Tooltip("How long should it take before the mouse cursor is hidden?")]
48+
private float hideTimeout = 3.0f;
49+
50+
/// <inheritdoc />
51+
float IMixedRealityMousePointer.HideTimeout => hideTimeout;
52+
53+
#endregion IMixedRealityMousePointer Implementation
54+
55+
#region IMixedRealityPointer Implementaiton
56+
2457
/// <inheritdoc />
2558
public override bool IsInteractionEnabled => isInteractionEnabled;
2659

@@ -57,6 +90,38 @@ public override void OnPreRaycast()
5790
}
5891
}
5992

93+
#endregion IMixedRealityPointer Implementaiton
94+
95+
#region IMixedRealitySourcePoseHandler Implementaiton
96+
97+
/// <inheritdoc />
98+
public override void OnSourceDetected(SourceStateEventData eventData)
99+
{
100+
if (RayStabilizer != null)
101+
{
102+
RayStabilizer = null;
103+
}
104+
105+
base.OnSourceDetected(eventData);
106+
107+
if (eventData.SourceId == Controller?.InputSource.SourceId)
108+
{
109+
isInteractionEnabled = true;
110+
}
111+
}
112+
113+
/// <inheritdoc />
114+
public override void OnSourceLost(SourceStateEventData eventData)
115+
{
116+
base.OnSourceLost(eventData);
117+
118+
if (eventData.SourceId == Controller?.InputSource.SourceId)
119+
{
120+
isInteractionEnabled = false;
121+
}
122+
}
123+
124+
/// <inheritdoc />
60125
public override void OnSourcePoseChanged(SourcePoseEventData<Vector2> eventData)
61126
{
62127
if (Controller == null ||
@@ -68,10 +133,36 @@ public override void OnSourcePoseChanged(SourcePoseEventData<Vector2> eventData)
68133

69134
if (UseSourcePoseData)
70135
{
71-
newRotation = transform.rotation.eulerAngles;
72-
newRotation.x += eventData.SourceData.y;
73-
newRotation.y += eventData.SourceData.x;
74-
transform.rotation = Quaternion.Euler(newRotation);
136+
UpdateMousePosition(eventData.SourceData.x, eventData.SourceData.y);
137+
}
138+
}
139+
140+
#endregion IMixedRealitySourcePoseHandler Implementaiton
141+
142+
#region IMixedRealityInputHandler Implementaiton
143+
144+
/// <inheritdoc />
145+
public override void OnInputDown(InputEventData eventData)
146+
{
147+
cursorWasDisabledOnDown = !BaseCursor.IsVisible;
148+
149+
if (cursorWasDisabledOnDown)
150+
{
151+
BaseCursor?.SetVisibility(true);
152+
transform.rotation = CameraCache.Main.transform.rotation;
153+
}
154+
else
155+
{
156+
base.OnInputDown(eventData);
157+
}
158+
}
159+
160+
/// <inheritdoc />
161+
public override void OnInputUp(InputEventData eventData)
162+
{
163+
if (BaseCursor.IsVisible && !cursorWasDisabledOnDown)
164+
{
165+
base.OnInputUp(eventData);
75166
}
76167
}
77168

@@ -83,18 +174,19 @@ public override void OnPositionInputChanged(InputEventData<Vector2> eventData)
83174
if (!UseSourcePoseData &&
84175
PoseAction == eventData.MixedRealityInputAction)
85176
{
86-
IsTracked = true;
87-
TrackingState = TrackingState.Tracked;
88-
newRotation = transform.rotation.eulerAngles;
89-
newRotation.x += eventData.InputData.x;
90-
newRotation.y += eventData.InputData.y;
91-
transform.rotation = Quaternion.Euler(newRotation);
177+
UpdateMousePosition(eventData.InputData.x, eventData.InputData.y);
92178
}
93179
}
94180
}
95181

182+
#endregion IMixedRealityInputHandler Implementaiton
183+
184+
#region Monobehaviour Implementaiton
185+
96186
protected override void Start()
97187
{
188+
isDisabled = DisableCursorOnStart;
189+
98190
base.Start();
99191

100192
if (RayStabilizer != null)
@@ -112,34 +204,44 @@ protected override void Start()
112204
}
113205
}
114206

115-
/// <inheritdoc />
116-
public override void OnSourceDetected(SourceStateEventData eventData)
207+
private void Update()
117208
{
118-
if (RayStabilizer != null)
119-
{
120-
RayStabilizer = null;
121-
}
209+
if (!hideCursorWhenInactive || isDisabled) { return; }
122210

123-
base.OnSourceDetected(eventData);
211+
timeoutTimer += Time.unscaledDeltaTime;
124212

125-
if (eventData.InputSource.SourceId == Controller.InputSource.SourceId)
213+
if (timeoutTimer >= hideTimeout)
126214
{
127-
Debug.Log("Pointer detected");
128-
isInteractionEnabled = true;
215+
timeoutTimer = 0.0f;
216+
BaseCursor?.SetVisibility(false);
217+
isDisabled = true;
129218
}
130219
}
131220

132-
/// <inheritdoc />
133-
public override void OnSourceLost(SourceStateEventData eventData)
134-
{
135-
base.OnSourceLost(eventData);
221+
#endregion Monobehaviour Implementaiton
136222

137-
if (Controller != null &&
138-
eventData.Controller != null &&
139-
eventData.Controller.InputSource.SourceId == Controller.InputSource.SourceId)
223+
private void UpdateMousePosition(float mouseX, float mouseY)
224+
{
225+
if (Mathf.Abs(mouseX) >= movementThresholdToUnHide ||
226+
Mathf.Abs(mouseY) >= movementThresholdToUnHide)
140227
{
141-
isInteractionEnabled = false;
228+
if (isDisabled)
229+
{
230+
BaseCursor?.SetVisibility(true);
231+
transform.rotation = CameraCache.Main.transform.rotation;
232+
}
233+
else
234+
{
235+
timeoutTimer = 0.0f;
236+
}
237+
238+
isDisabled = false;
142239
}
240+
241+
var newRotation = Vector3.zero;
242+
newRotation.x += mouseX;
243+
newRotation.y += mouseY;
244+
transform.Rotate(newRotation, Space.World);
143245
}
144246
}
145247
}

Assets/MixedRealityToolkit-SDK/Inspectors/UX/Pointers/BaseControllerPointerInspector.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ public override void OnInspectorGUI()
5151

5252
if (basePointerFoldout)
5353
{
54+
EditorGUI.indentLevel++;
55+
5456
EditorGUILayout.PropertyField(cursorPrefab);
5557
EditorGUILayout.PropertyField(disableCursorOnStart);
5658
EditorGUILayout.PropertyField(setCursorVisibilityOnSourceDetected);
@@ -69,7 +71,9 @@ public override void OnInspectorGUI()
6971
}
7072
}
7173

74+
EditorGUI.indentLevel--;
7275
}
76+
7377
serializedObject.ApplyModifiedProperties();
7478
}
7579
}

0 commit comments

Comments
 (0)