- 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>
- A bare hand already feeds no Wii Remote motion (camera-tracked poses are too noisy to
differentiate twice). In a cockpit race, both hands on the wheel rising together or a free bare
hand rising fast now plays one shake on the remote's accelerometer: 150 ms, so the guest sees it
on at least three frames, one cycle up to +2 g and down to the -3.6 g limit, as Dolphin's
emulated shake does. A turn (one hand up, the other down) never flicks, nor does a lone hand on
the wheel; a rise must last three samples and cover 5 cm within 150 ms, tracking jumps reset it,
and flicks are 0.5 s apart. Wii Remote presentation only.
- debug.wiicompiled.inject <n>:flick plays the same shake, with the controllers or unattended, to
tune it apart from the gesture. Docs: OPENXR.md, docs/quest-port.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 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>
- 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>
Clicking the right thumbstick flips first person exactly as the F10
checkbox does, and saves it the same way. It works on the VR controllers
in either presentation (with a short tick on the right controller) and on
any other gamepad while VR is running. It never reached the game: SDL's
stick click only lands in Aurora's extended buttons.
A click counts on release, and only if the left thumbstick stayed up and
the headset settings panel stayed closed throughout, so the two-thumbstick
panel chord in gamepad mode never toggles the camera. A gamepad whose
right stick click is bound to a GameCube control on its port, as a button
or in an input expression, keeps it for the game. The XR side only posts
a request; the toggle itself runs on the game thread with the checkbox.
[vr] first_person_toggle_click (default true) and a checkbox under the
camera toggle turn the click off. mkw_vr_camera_toggle_tests covers the
click rule.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ported from heurazy's mario-kart-wii-VR-port. F10 > Controllers > USB
wheel and pedals (also in the headset panel) picks and calibrates the
steering axis and both pedals by moving them, and assigns buttons by
pressing them, over raw SDL joysticks: no per-model table or gamepad
mapping, and separate pedals, reversed axes and combined pedal axes all
calibrate the same way. Settings live in PhysicalWheel.toml beside
Config.toml; heurazy's five-button files load unchanged.
The wheel is player 1's GameCube controller. In a race it owns port 0
(steering on the stick, the accelerator on A, the brake pedal braking then
reversing over A and drift, the paddles on R and L), keeping only the
other source's pause and item aim. In menus it adds only deliberate
presses. It arms once every pedal and button is released, stays neutral
in a race while its setup is incomplete, and nothing is opened until it
is enabled. Optional light rumble follows the game's own, capped at 15 %.
Added here: its confirm, a new back button and the steering device's
first hat (D-pad) work the menus, since our VR controllers default to a
Wii Remote and the wheel needs to navigate on its own. Devices SDL
classifies as wheels are marked in the list.
In the VR cockpit the wheel follows the hardware steering and hand
steering steps aside while it drives. README documents setup and
Logitech notes (G HUB, the G29's PS3 switch, shifter gears as buttons);
not yet tried on a physical wheel.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every XR frame in the cockpit seat the pacing thread locates both grips in
the seated frame (the immersive base turned by the lean-back angle, the
frame the eye transforms place the vehicle in) and publishes a driving
snapshot. The wheel or handlebar shows the left stick's steering at the
configured full-lock angle, eased; the vehicle's own wheel reads that angle
on the guest thread.
With hand_steering on (off by default), squeezing a grip near the wheel or
handlebar takes hold of it (a short pulse on grab and release); one or two
hands turn it through heurazy's SteeringWheel, and while it is held the
wheel replaces the left stick's X axis in both the Wii Remote and gamepad
presentations, the stick's Y still aims items, and a holding grip no
longer presses C or a shoulder. The settings panel withholds it like any
other input.
The stereo packet carries the cockpit overlay: the hands, in the runtime's
hand mesh (XR_EXT_hand_tracking + XR_FB_hand_tracking_mesh, requested only
when hand steering is on at launch) or procedural gloves, and the separate
VR wheel or handlebar whenever the vehicle's own is not the one turning.