Add VR locomotion: move/turn with thumbsticks while the menu is open
build / build (push) Successful in 2m25s

- Left thumbstick snap-turns, right thumbstick smooth-moves, letting the
  player line themselves up with the fixed game quad ("virtual screen")
  without needing physical room-scale space to do it in. Implemented via
  a second OpenXR reference space (a "play space") derived from the real
  LOCAL space by the inverse of the player's transform, so every existing
  quad/hit-testing/rendering call site just needed g_local_space swapped
  for it - no manual coordinate-transform math required elsewhere
- Generalized the ray/quad hit-testing in xr_input.c to a proper
  oriented-plane intersection (needed once quads can rotate); verified it
  degenerates to the old axis-aligned formula when unrotated, so the
  keyboard and non-recentered menu are unaffected
- The menu launcher now re-centers in front of the player, correctly
  oriented to face them, each time it's freshly reopened
- "Reset Position" (Main Menu tab) recenters using the player's current
  real head pose - not a plain reset-to-origin, which only undid
  thumbstick movement and ignored physical drift since the session
  started. The same recenter runs once automatically at startup too, as a
  fallback for when there's no complete saved position to use instead
- Position/orientation persists in questshock.config.json's new
  player_position group (independent of savegames), including new
  numeric-value support in the config file's hand-rolled JSON parser
  (previously string-enums only)
This commit is contained in:
ml
2026-09-05 15:47:54 +02:00
parent c0619a55ab
commit 360a1f7e3d
12 changed files with 812 additions and 46 deletions
+30
View File
@@ -66,6 +66,36 @@ void xr_input_sync_and_draw(XrSpace baseSpace, XrTime time, bool draw);
// frame.
bool xr_input_get_beam_layer(int hand, XrCompositionLayerQuad *out_quad);
// Recenters the player so the game quad ("virtual screen") appears directly
// ahead of wherever they're currently really standing/facing - a pure,
// live "return to a sane view of the screen" action, unrelated to any
// stored/config value (unlike xr_session_set_player_transform()'s other
// callers, this never reads or writes questshock.config.json - it's driven
// entirely by the player's current real head pose, the same way
// xr_input_sync_and_draw()'s own menu re-center is). Called from the Main
// Menu tab's "Reset Position" button (via qs_config.c's cross-thread
// dispatch - see qs_config_request_reset_position()), but doesn't touch
// anything else qs_config.c owns; also called once automatically, from
// inside xr_input_sync_and_draw() itself, on whichever frame first has a
// valid head pose after startup (see g_pending_startup_recenter's own
// comment) - but only as a *fallback* default for when there's no
// complete saved player_position to fall back on instead (see
// xr_input_skip_startup_recenter() below), since a config-loaded value
// describes a transform relative to a *previous* session's real-space
// origin, which is only meaningful if that previous position was actually
// captured (LOCAL space's own origin isn't a stable point across
// launches). Returns false (no-op otherwise) if no valid head pose was
// available to recenter onto yet.
bool xr_input_recenter_player_to_screen(void);
// Called once, from qs_config_load_startup() (qs_config.c), when a
// complete saved player_position was actually loaded from
// questshock.config.json - cancels the pending automatic startup recenter
// above so it doesn't immediately override the value that was just
// applied. Safe to call regardless of whether xr_input_init() has even run
// yet (this only touches the plain file-local flag, no XR calls).
void xr_input_skip_startup_recenter(void);
void xr_input_shutdown(void);
#ifdef __cplusplus