Hand a put-down controller's side to the cameras

- Started with the controllers connected, a race stayed on them: Horizon OS switches all input
  between controllers and hands, and back to the controllers as soon as one lying on a table moves
  (a Quest 3 log went touch_controller, simple_controller, touch_controller within seconds). An
  app cannot disconnect the controllers.
- With tracked hands on, the input now resumes XR_META_simultaneous_hands_and_controllers (Meta's
  multimodal), which overrides that switching: a controller not in a hand no longer owns it, so the
  cameras track that hand at once, and a held controller keeps working. Paused again when the
  option goes off; a refused resume is logged and not retried until the option is toggled.
- A hand is bare when its squeeze action is inactive and it either drives khr/simple_controller or
  has camera-tracked joints, since a free hand under simultaneous tracking may get a profile our
  actions are not bound in. Docs: OPENXR.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
iChris4andClaude Opus 5.5 committed 2026-09-25 01:30:18 +02:00
1 parent 38b7f89d74
commit 1d7f2549bd
8 files changed
+112 -14

No files matched your search

+5
View File
@@ -143,6 +143,11 @@ void TestGestures() {
left.secondary = true;
right.primary = true;
Check(SelectOf(left, 0) && SelectOf(right, 1), "simple_controller's select per hand");
Check(!HandDriven(true, true, true), "a hand holding a controller is not bare");
Check(HandDriven(false, true, false), "a hand driving simple_controller is bare");
Check(HandDriven(false, false, true), "a camera-tracked hand with no profile of ours is bare");
Check(!HandDriven(false, false, false), "a hand with nothing active is not");
}
std::array<wii_remote::HandInputs, 2> PinchingHands() {