Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Assets/Tests/InputSystem/CoreTests_Controls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1428,7 +1428,7 @@ public void Controls_OptimizedControls_TrivialControlsAreOptimized()
Assert.That(mouse.position.x.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatFloat));
Assert.That(mouse.position.y.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatFloat));
Assert.That(mouse.position.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatVector2));
Assert.That(mouse.leftButton.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatInvalid));
Assert.That(mouse.leftButton.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatBit));

InputSystem.settings.SetInternalFeatureFlag(InputFeatureNames.kUseOptimizedControls, false);
Assert.That(mouse.position.x.optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatInvalid));
Expand Down
46 changes: 46 additions & 0 deletions Assets/Tests/InputSystem/Plugins/XRTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,52 @@ public void Controls_OptimizedControls_PoseControl_IsOptimized()
Assert.That((device["posecontrol"] as PoseControl).optimizedControlDataType, Is.EqualTo(InputStateBlock.FormatPose));
}

[Test]
[Category("Controls")]
[TestCase(true)]
[TestCase(false)]
public void Controls_PoseControl_IsTracked_ReadsCorrectly(bool useOptimizedControls)
{
InputSystem.settings.SetInternalFeatureFlag(InputFeatureNames.kUseOptimizedControls, useOptimizedControls);

runtime.ReportNewInputDevice(PoseDeviceState.CreateDeviceDescription().ToJson());

InputSystem.Update();

var device = InputSystem.devices[0];
var poseControl = device["posecontrol"] as PoseControl;

// Queue state with isTracked = true (byte value 1)
InputSystem.QueueStateEvent(device, new PoseDeviceState
{
isTracked = 1,
trackingState = (uint)(InputTrackingState.Position | InputTrackingState.Rotation),
position = new Vector3(1, 2, 3),
rotation = Quaternion.identity,
});
InputSystem.Update();

// Reading isTracked as a ButtonControl should return true
Assert.That(poseControl.isTracked.isPressed, Is.True, "isTracked.isPressed should be true when tracked");
Assert.That(poseControl.isTracked.ReadValue(), Is.EqualTo(1.0f).Within(0.001f), "isTracked.ReadValue() should be 1.0f when tracked");

// Reading the full PoseState should also have isTracked = true
var poseState = poseControl.ReadValue();
Assert.That(poseState.isTracked, Is.True, "PoseState.isTracked should be true when tracked");

// Queue state with isTracked = false (byte value 0)
InputSystem.QueueStateEvent(device, new PoseDeviceState
{
isTracked = 0,
trackingState = 0,
});
InputSystem.Update();

Assert.That(poseControl.isTracked.isPressed, Is.False, "isTracked.isPressed should be false when not tracked");
Assert.That(poseControl.isTracked.ReadValue(), Is.EqualTo(0.0f).Within(0.001f), "isTracked.ReadValue() should be 0.0f when not tracked");
Assert.That(poseControl.ReadValue().isTracked, Is.False, "PoseState.isTracked should be false when not tracked");
}

// ISXB-405
[Test]
[Category("Devices")]
Expand Down
1 change: 1 addition & 0 deletions Packages/com.unity.inputsystem/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixed `InputAction.IsPressed`, `WasPressedThisFrame`, and `WasReleasedThisFrame` using a `ButtonControl`'s `pressPoint` when a binding also had an explicit `PressInteraction` with its own `pressPoint`, which could make those APIs disagree with the interaction's press and release behavior. Action-level press APIs now follow the interaction threshold when both are set explicitly.
- Fixed `IndexOutOfRangeException` in `InputDeviceBuilder` when connecting an HID gamepad whose report descriptor declares a hat switch with Report Size 8 (e.g. ESP32-BLE-Gamepad). The HID layer now anchors the hat's directional sub-controls to the hat's own byte instead of letting the layout system auto-allocate a fresh byte for each [UUM-143659](https://jira.unity3d.com/browse/UUM-143659).
- Fixed Input Debugger window's incorrect name. It is now called 'Input Debugger' instead of 'Input Debug' [UUM-137124](https://jira.unity3d.com/browse/UUM-137124).
- Fixed `PoseControl.isTracked` always returning false when read through non-optimized code paths (e.g. Input Debugger) due to `sizeInBits = 8` causing the value to be normalized as `1/255` instead of `1.0`.

### Changed
- Action-level `IsPressed`, `WasPressedThisFrame`, and `WasReleasedThisFrame` for bindings to `Vector2Control` / `StickControl` no longer consult a per-control `pressPoint` on the vector (that field was removed). Use a `Press` interaction to set a custom threshold, or rely on `defaultButtonPressPoint`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ private float EvaluateMagnitude(float value)
return NormalizeProcessor.Normalize(clampedValue, min, max, 0);
}

/// <inheritdoc />
protected override FourCC CalculateOptimizedControlDataType()
{
var noProcessingNeeded =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Runtime.CompilerServices;
using UnityEngine.InputSystem.LowLevel;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Scripting;

////REVIEW: introduce separate base class for ButtonControl and AxisControl instead of deriving ButtonControl from AxisControl?
Expand Down Expand Up @@ -378,6 +379,21 @@

#endif // UNITY_EDITOR

/// <inheritdoc />
protected override FourCC CalculateOptimizedControlDataType()
{
if (clamp == Clamp.None &&

Check warning on line 385 in Packages/com.unity.inputsystem/InputSystem/Runtime/Controls/ButtonControl.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Runtime/Controls/ButtonControl.cs#L384-L385

Added lines #L384 - L385 were not covered by tests
invert == false &&
normalize == false &&
scale == false &&
m_StateBlock.format == InputStateBlock.FormatBit &&
m_StateBlock.sizeInBits == 1 &&
m_StateBlock.bitOffset == 0)
return InputStateBlock.FormatBit;

Check warning on line 392 in Packages/com.unity.inputsystem/InputSystem/Runtime/Controls/ButtonControl.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Runtime/Controls/ButtonControl.cs#L392

Added line #L392 was not covered by tests

return base.CalculateOptimizedControlDataType();
}

Check warning on line 395 in Packages/com.unity.inputsystem/InputSystem/Runtime/Controls/ButtonControl.cs

View check run for this annotation

Codecov GitHub.com / codecov/patch

Packages/com.unity.inputsystem/InputSystem/Runtime/Controls/ButtonControl.cs#L394-L395

Added lines #L394 - L395 were not covered by tests

// We make the current global default button press point available as a static so that we don't have to
// constantly make the hop from InputSystem.settings -> InputManager.m_Settings -> defaultButtonPressPoint.
internal static float s_GlobalDefaultButtonPressPoint;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public PoseState(bool isTracked, TrackingState trackingState, Vector3 position,
/// <remarks>
/// Fully tracked means that the pose is accurate and not using any simulated or extrapolated positions, and the system tracking this pose is able to confidently track this object.
/// </remarks>
[FieldOffset(0), InputControl(displayName = "Is Tracked", layout = "Button", sizeInBits = 8 /* needed to ensure optimization kicks-in */)]
[FieldOffset(0), InputControl(displayName = "Is Tracked", layout = "Button", sizeInBits = 1)]
public bool isTracked;

/// <summary>
Expand Down Expand Up @@ -252,7 +252,7 @@ protected override FourCC CalculateOptimizedControlDataType()
if (
m_StateBlock.sizeInBits == PoseState.kSizeInBytes * 8 &&
m_StateBlock.bitOffset == 0 &&
isTracked.optimizedControlDataType == InputStateBlock.kFormatByte &&
isTracked.optimizedControlDataType == InputStateBlock.kFormatBit &&
trackingState.optimizedControlDataType == InputStateBlock.kFormatInt &&
position.optimizedControlDataType == InputStateBlock.kFormatVector3 &&
rotation.optimizedControlDataType == InputStateBlock.kFormatQuaternion &&
Expand Down
Loading