- 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>
- Now that holding the wheel engages the race controls, closing the other hand on the rim could
bring thumb and index together on the way and fire an item. A pinch uses an item only while the
hand's grasp is under 0.5; a relaxed hand reads about 0, a hand closed on a rim about 0.9.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- On a Quest 3 the race controls never engaged: grabbing the wheel gave no gas and a right pinch
stayed A. They waited for the game to switch the remote's pointer off, and MKW keeps it on in a
race (the log only ever said "the game's pointer is on").
- The race controls now apply while a bare hand holds the wheel: that holds the gas, and a free
hand's pinch (either hand) uses an item. With no bare hand on the wheel a right pinch stays A,
which is what the pause menu and the results need. The flick still works in the whole cockpit.
- The game-pointer publication (KPAD hook and bridge) is gone. The "tracked hands" source line is
logged at most once a second: camera-tracked hands drop in and out of view often.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- New [vr] hand_tracking (default off, Quest only for now): the Quest launcher's Settings > VR and
the headset panel's VR tab, under hand steering. Two XR_EXT_hand_tracking trackers are located
every XR frame: with the controllers held the Quest builds the joints from their touch sensors
(XR_EXT_hand_tracking_data_source's controller source), once they are put down from its
cameras. The trackers exist only while the option and hand steering are on and also serve the
runtime hand mesh; the extensions (plus XR_FB_hand_tracking_aim) are asked for when either is
on at launch.
- Aurora skins the runtime mesh with the joints themselves (tracked pose times inverse bind pose,
no curl, no grip); runtimes with joints but no mesh get a skeleton; non-finite joints put only
that hand back on its grip curl. AuroraCockpitHand carries the 26 seated-frame joints and radii.
- The manifest declares horizonos.permission.HAND_TRACKING (and the deprecated
com.oculus.permission.HAND_TRACKING), both normal permissions with no prompt on a Quest 3, and
oculus.software.handtracking as optional; without it Horizon OS keeps the app controllers-only.
Bare hands then drive khr/simple_controller, so on Android a hand whose squeeze action is
inactive and select active is treated as bare: with the option off it presses nothing but the
menu gesture, is not drawn and feeds no Wii Remote motion.
- Interaction-profile changes and tracker sources are logged. The pure rules (grasp from finger
flexion, bare latch, pinch gate, bare-hand buttons, flick) live in the OpenXR-free
vr/openxr_hand_tracking.h with mkw_vr_hand_tracking_tests; the driving and flick parts are
wired in the next commits. Docs: OPENXR.md, docs/quest-port.md, README.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>