protonscr

[BUG] digital action bChanged always false when polling second actionset

steamvrclosed bug
ValveSoftware/SteamVR-for-Linux#236 · opened 2019-08-22 by ChristophHaag · updated 2021-02-24 · 3 comments · github
CChristophHaag 2019-08-22 github

This affects SteamVR beta 1.7.8, but works as expected in 1.7.6. It was likely broken in SteamVR beta 1.7.7 which contains

Fixed issue with the changed bit being incorrect when Get*ActionData is called more than once per frame.

When registering a boolean action, for example for /user/hand/*/trigger, the data for InputDigitalActionData_t.bChanged is always false, if another action set is updated before the actionset with this boolean action.

Here is example code demonstrating the issue:
https://gist.github.com/ChristophHaag/323974337969c119874c251ebbf0e14b

It has two action sets

  • /actions/test with a boolean action /actions/test/in/trigger
  • /actions/test2 with a pose action /actions/test2/in/hand_pose

For brevity only the right hand controller is used but it happens with both hands.

In a loop, first /actions/test2 is updated and the data is ignored. Then /actions/test is updated and the bState and bChanged data of /actions/test/in/trigger is printed.

When pressing the trigger on the right controller, bState changes correctly, but bChanged will remain 0.

When not updating of /actions/test2 and only updating /actions/test, then bChanged works as expected.

Only tested on Linux.

CChristophHaag 2019-08-28 github

It was pointed out to me that this behavior may be intentional.

In OpenXR, xrSyncActions considers all actionsets that are not passed to it as "inactive". So if alternatingly syncing two actionsets, the one that is not synced at the moment goes inactive. The trick: When an actionset is going from inactive to active, it doesn't consider any actions to be in changed status.

UpdateActionState allows to sync multiple actionsets at once, and of course my example code works fine if I replace the individual updating of the two action sets with one that updates both at the same time:

struct VRActiveActionSet_t both[2] = {0};
both[0].ulActionSet = test_handle;
both[1].ulActionSet = test2_handle;

...

inputerr = VRInput()->UpdateActionState(both, sizeof(active_test_action_set), 2);

Either way this change in 1.7.7 changes behavior that applications may already rely on.

Mmaxmakesmods 2019-10-19 github

Thanks for this, saved me a little headache!

CChristophHaag 2021-02-24 github

Closing because this probably isn't a bug, though the behavior should be (more visibly?) documented.

Nothing extracted yet.