Skip to content

Commit 48485d3

Browse files
committed
Modified solution to only enable position and/or rotation in tracking state if position and/or rotation actions have a resolved control that could drive input. Additionally fixed so that ignoreTrackingState == true, doesn't reset to identity, but preserve the configured transform of the associated GameObject.
1 parent c0b3418 commit 48485d3

File tree

1 file changed

+54
-55
lines changed

1 file changed

+54
-55
lines changed

Packages/com.unity.inputsystem/InputSystem/Plugins/XR/TrackedPoseDriver.cs

Lines changed: 54 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ void BindTrackingState()
308308
}
309309
}
310310

311-
private void RenameAndEnable(InputAction action, string name)
311+
private static void RenameAndEnable(InputAction action, string name)
312312
{
313313
#if UNITY_EDITOR
314314
Editor.InputExitPlayModeAnalytic.suppress = true;
@@ -469,12 +469,17 @@ protected void UpdateCallback()
469469
if (m_IsFirstUpdate)
470470
{
471471
// Update current input values if this is the first update since becoming enabled
472-
// since the performed callbacks may not have been executed
473-
if (m_PositionInput.action != null)
472+
// since the performed callbacks may not have been executed. In case there is no bound control
473+
// we preserve current transform by extracting transform values as initial values instead.
474+
if (HasResolvedControl(m_PositionInput.action))
474475
m_CurrentPosition = m_PositionInput.action.ReadValue<Vector3>();
476+
else
477+
m_CurrentPosition = transform.localPosition;
475478

476-
if (m_RotationInput.action != null)
479+
if (HasResolvedControl(m_RotationInput.action))
477480
m_CurrentRotation = m_RotationInput.action.ReadValue<Quaternion>();
481+
else
482+
m_CurrentRotation = transform.localRotation;
478483

479484
ReadTrackingState();
480485

@@ -501,70 +506,28 @@ void ReadTrackingState()
501506
{
502507
// Treat an Input Action Reference with no reference the same as
503508
// an enabled Input Action with no authored bindings, and allow driving the Transform pose.
504-
var positionInputAction = m_PositionInput.action;
505-
var hasPositionInputActionWithBindings =
506-
positionInputAction != null && positionInputAction.m_BindingsCount > 0;
507-
508-
var rotationInputAction = m_RotationInput.action;
509-
var hasRotationInputActionWithBindings =
510-
rotationInputAction != null && rotationInputAction.m_BindingsCount > 0;
509+
var hasPositionInputActionWithBindings = HasResolvedControl(positionInput.action);
510+
var hasRotationInputActionWithBindings = HasResolvedControl(rotationInput.action);
511511

512512
// Check if we have transform and rotation controls to drive the pose.
513513
if (hasPositionInputActionWithBindings && hasRotationInputActionWithBindings)
514-
{
515514
m_CurrentTrackingState = TrackingStates.Position | TrackingStates.Rotation;
516-
}
517515
else if (hasPositionInputActionWithBindings)
518-
{
519516
m_CurrentTrackingState = TrackingStates.Position;
520-
}
521517
else if (hasRotationInputActionWithBindings)
522-
{
523518
m_CurrentTrackingState = TrackingStates.Rotation;
524-
}
525519
else
526-
{
527520
m_CurrentTrackingState = TrackingStates.None;
528-
}
529-
return;
530521
}
531-
532-
// Grab state.
533-
var actionMap = trackingStateAction.GetOrCreateActionMap();
534-
actionMap.ResolveBindingsIfNecessary();
535-
var state = actionMap.m_State;
536-
537-
// Get list of resolved controls to determine if a device actually has tracking state.
538-
var hasResolvedControl = false;
539-
if (state != null)
522+
else if (HasResolvedControl(trackingStateAction))
540523
{
541-
var actionIndex = trackingStateAction.m_ActionIndexInState;
542-
var totalBindingCount = state.totalBindingCount;
543-
for (var i = 0; i < totalBindingCount; ++i)
544-
{
545-
unsafe
546-
{
547-
ref var bindingState = ref state.bindingStates[i];
548-
if (bindingState.actionIndex != actionIndex)
549-
continue;
550-
if (bindingState.isComposite)
551-
continue;
552-
553-
if (bindingState.controlCount > 0)
554-
{
555-
hasResolvedControl = true;
556-
break;
557-
}
558-
}
559-
}
524+
// Retain the current value if there is no resolved binding.
525+
// Since the field initializes to allowing position and rotation,
526+
// this allows for driving the Transform pose always when the device
527+
// doesn't support reporting the tracking state.
528+
if (HasResolvedControl(trackingStateAction))
529+
m_CurrentTrackingState = (TrackingStates)trackingStateAction.ReadValue<int>();
560530
}
561-
562-
// Retain the current value if there is no resolved binding.
563-
// Since the field initializes to allowing position and rotation,
564-
// this allows for driving the Transform pose always when the device
565-
// doesn't support reporting the tracking state.
566-
if (hasResolvedControl)
567-
m_CurrentTrackingState = (TrackingStates)trackingStateAction.ReadValue<int>();
568531
}
569532

570533
/// <summary>
@@ -610,6 +573,8 @@ protected virtual void PerformUpdate()
610573
/// <param name="newRotation">The new local rotation to possibly set.</param>
611574
protected virtual void SetLocalTransform(Vector3 newPosition, Quaternion newRotation)
612575
{
576+
// Note that tracking state will be set to reflect whether the position and/or rotation
577+
// actions can provide applicable values.
613578
var positionValid = m_IgnoreTrackingState || (m_CurrentTrackingState & TrackingStates.Position) != 0;
614579
var rotationValid = m_IgnoreTrackingState || (m_CurrentTrackingState & TrackingStates.Rotation) != 0;
615580

@@ -641,6 +606,40 @@ bool HasStereoCamera(out Camera cameraComponent)
641606
return TryGetComponent(out cameraComponent) && cameraComponent.stereoEnabled;
642607
}
643608

609+
// Evaluates whether the given action has at least one resolved control and may generate input.
610+
private static bool HasResolvedControl(InputAction action)
611+
{
612+
// Action cannot have controls if null.
613+
if (action == null)
614+
return false;
615+
616+
// Attempt to grab state and resolve bindings unless already resolved.
617+
var actionMap = action.GetOrCreateActionMap();
618+
actionMap.ResolveBindingsIfNecessary();
619+
var state = actionMap.m_State;
620+
if (state == null)
621+
return false;
622+
623+
// Get list of resolved controls to determine if a device actually has a tracking state.
624+
var actionIndex = action.m_ActionIndexInState;
625+
var totalBindingCount = state.totalBindingCount;
626+
for (var i = 0; i < totalBindingCount; ++i)
627+
{
628+
unsafe
629+
{
630+
ref var bindingState = ref state.bindingStates[i];
631+
if (bindingState.actionIndex != actionIndex)
632+
continue;
633+
if (bindingState.isComposite)
634+
continue;
635+
if (bindingState.controlCount > 0)
636+
return true;
637+
}
638+
}
639+
640+
return false;
641+
}
642+
644643
#region DEPRECATED
645644

646645
// Disable warnings that these fields are never assigned to. They are set during Unity deserialization and migrated.

0 commit comments

Comments
 (0)