Drive with bare hands in the cockpit

- With tracked hands on, a hand driving khr/simple_controller with camera-tracked joints is bare:
  latched through wheel_tracking_grace (Meta drops the select action while a hand is lost),
  cleared as soon as a controller's squeeze is back. Its palm joint stands in for the grip and a
  grasp from the middle, ring and little fingers' flexion (0 below 1.2 rad, 1 from 3.0) for the
  squeeze, so closing a hand on the rim takes hold under the wheel's own press and release. The
  grasp never reaches the game's buttons.
- In a cockpit race a bare hand holding the wheel holds the gas (A / South) and a pinch from a free
  bare hand uses an item (Z / L) once the hand has been off the wheel for 0.15 s. Only while the
  game has the remote's pointer off: KPAD publishes the game's pointer switch for the VR remote,
  so the pause menu and the results keep a right pinch as A. The pacing thread logs each change,
  to confirm on the headset that MKW turns the pointer off while driving.
- A held bare hand keeps its last joints drawn through a short loss; bare hands get no haptics.
  The headset panel's readout shows grasp, hold and pinch. 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 00:08:25 +02:00
1 parent a21e22b605
commit 5a38377f61
8 files changed
+129 -9

No files matched your search

+5
View File
@@ -237,6 +237,11 @@ private:
std::array<bool, kHands> m_squeeze_active{};
std::array<bool, kHands> m_hand_driven{};
std::array<bool, kHands> m_pinch{};
// Bare-hand driving: each hand's bare latch (camera joints, last grasp) and
// item pinch gate, and the game's pointer switch as last logged.
std::array<hand_tracking::BareLatch, kHands> m_bare_latch{};
std::array<hand_tracking::PinchGate, kHands> m_pinch_gate{};
int m_logged_game_pointer = -2;
uint64_t m_profile_serial = 0;
bool m_created = false;
+8
View File
@@ -56,10 +56,18 @@ bool OpenXRReadWiiRemote(OpenXRWiiRemoteSample& sample) noexcept;
// WPADControlMotor for the emulated remote.
void OpenXRSetWiiRemoteRumble(bool active) noexcept;
// Guest side: whether the game has the remote's pointer switched on, as KPAD
// reads it each time the game polls the VR remote (Input::WiiController::
// TogglePointer flips it). Tracked bare hands use it to tell driving from a
// menu inside a race; OpenXRInput logs every change.
void OpenXRPublishGamePointer(bool enabled) noexcept;
// XR side.
void OpenXRPublishWiiRemote(uint32_t sdl_joystick_id, const OpenXRWiiRemoteSample& sample) noexcept;
void OpenXRWithdrawWiiRemote() noexcept;
bool OpenXRWiiRemoteRumbleRequested() noexcept;
// The game's pointer switch: 1 on, 0 off, -1 not known (no remote polled yet).
int OpenXRGamePointerState() noexcept;
// The geometry and signal conditioning behind a sample, kept free of OpenXR
// types so it can be checked headlessly (tests/vr_wii_remote_tests.cpp).