mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 05:00:27 +02:00
Sit in the cockpit with hands on the wheel by default
First person already seats you in the cockpit, so hand steering belongs with it: the stick keeps steering until a grip actually takes hold of the wheel, and nothing else changes until it does. "yaw_pitch" becomes the default anchor for the same reason - from the driver's seat the vehicle's own climb reads as the ground rising, where a level horizon reads as the kart sinking away. Both defaults move together in runtime_config.h, the fresh-config template, the F10 menu's reset, and both launchers, which mirror the runtime's constants. The menu's reset also puts the rotation combo back on the default rather than on "yaw", and now covers hand steering with the other cockpit keys. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4438a300b8
commit
1d66ae87bf
5 files changed
+41
-27
No files matched your search
@@ -57,10 +57,10 @@ first_person_head_forward_meters = 0.0
|
|||||||
first_person_head_right_meters = 0.0
|
first_person_head_right_meters = 0.0
|
||||||
first_person_hide_driver = true
|
first_person_hide_driver = true
|
||||||
first_person_hidden_model = 0
|
first_person_hidden_model = 0
|
||||||
first_person_rotation = "yaw"
|
first_person_rotation = "yaw_pitch"
|
||||||
steering_wheel = true
|
steering_wheel = true
|
||||||
native_steering_wheel = true
|
native_steering_wheel = true
|
||||||
hand_steering = false
|
hand_steering = true
|
||||||
performance_level = "boost"
|
performance_level = "boost"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -349,15 +349,18 @@ own per-eye delta. The kart's *physics* pose is used deliberately, not the anima
|
|||||||
animated frame would bob and lurch the camera.
|
animated frame would bob and lurch the camera.
|
||||||
|
|
||||||
`first_person_rotation` decides where the view's orientation comes from, mirroring DolphinXR's
|
`first_person_rotation` decides where the view's orientation comes from, mirroring DolphinXR's
|
||||||
camera-anchor modes. `"yaw"`, the default, keeps the horizon level through a chase-camera tilt or a
|
camera-anchor modes. `"yaw"` keeps the horizon level through a chase-camera tilt or a banked corner.
|
||||||
banked corner. `"yaw_pitch"` adds the kart's climb, so a slope or a wheelie tips the view while a
|
`"yaw_pitch"`, the default, adds the kart's climb, so a slope or a wheelie tips the view while a
|
||||||
banked corner still never rolls it. `"full"` takes the kart's whole orientation, banking included.
|
banked corner still never rolls it: sitting in the cockpit, the vehicle's own climb reads as the
|
||||||
|
ground rising rather than as the view tipping. `"full"` takes the kart's whole orientation, banking included.
|
||||||
All three are the same construction from a forward and an up axis, differing only in which pair
|
All three are the same construction from a forward and an up axis, differing only in which pair
|
||||||
they take: pairing a forward with world up is what removes roll. The headset always adds free look
|
they take: pairing a forward with world up is what removes roll. The headset always adds free look
|
||||||
on top of whichever is chosen, and only the translation onto the head is common to all three.
|
on top of whichever is chosen, and only the translation onto the head is common to all three.
|
||||||
|
|
||||||
In the cockpit, `"yaw"` takes the kart's own driving direction rather than the chase camera's
|
In the cockpit, `"yaw"` takes the kart's own driving direction rather than the chase camera's
|
||||||
lagging heading, from the level seat frame. With the custom seat, the head's place in the kart is
|
lagging heading, from the level seat frame, which also damps a damage spin. `"yaw_pitch"`, the
|
||||||
|
default, and `"full"` take the kart's live orientation about that same seat, keeping only its
|
||||||
|
stabilised position, so a wheelie, a slope or a spin moves the view with the vehicle. With the custom seat, the head's place in the kart is
|
||||||
`first_person_head_up_meters` and its two companions, measured in the kart's own frame; the F10
|
`first_person_head_up_meters` and its two companions, measured in the kart's own frame; the F10
|
||||||
sliders exist because the comfortable value is a matter of taste and is best judged from inside the
|
sliders exist because the comfortable value is a matter of taste and is best judged from inside the
|
||||||
headset.
|
headset.
|
||||||
@@ -424,9 +427,10 @@ copied array, those that bound one outside the window it was set for, the matche
|
|||||||
closest position matrix was from the expected one; the first such line with a bound draw also prints
|
closest position matrix was from the expected one; the first such line with a bound draw also prints
|
||||||
both matrices.
|
both matrices.
|
||||||
|
|
||||||
**Hand steering.** `hand_steering = true` (off by default; also in WheelWizard's OpenXR VR settings
|
**Hand steering.** `hand_steering` (on by default, and in WheelWizard's OpenXR VR settings and the
|
||||||
and the Quest launcher's Settings > VR, beside the seat)
|
Quest launcher's Settings > VR, beside the seat)
|
||||||
lets you take hold of the wheel or handlebar with the tracked controllers. Squeeze a grip near it:
|
lets you take hold of the wheel or handlebar with the tracked controllers. It costs nothing until a
|
||||||
|
grip actually takes hold: until then the stick steers as it always has. Squeeze a grip near it:
|
||||||
past 55 % squeeze, within `wheel_grab_distance` metres of its plane (default 0.35) and near the rim,
|
past 55 % squeeze, within `wheel_grab_distance` metres of its plane (default 0.35) and near the rim,
|
||||||
or near a bar end, scaled by `wheel_grab_assist`. Once taken, only letting go of the grip releases
|
or near a bar end, scaled by `wheel_grab_assist`. Once taken, only letting go of the grip releases
|
||||||
it. One hand steers by its angle around the hub; two hands steer by the line between them, so leaning
|
it. One hand steers by its angle around the hub; two hands steer by the line between them, so leaning
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ build, without CPU readback. Menus and
|
|||||||
unsupported scenes appear as a head-locked virtual screen; a validated single-camera race switches
|
unsupported scenes appear as a head-locked virtual screen; a validated single-camera race switches
|
||||||
to immersive stereo rendering. VR is opt-in and falls back to the normal desktop renderer if the
|
to immersive stereo rendering. VR is opt-in and falls back to the normal desktop renderer if the
|
||||||
runtime or headset is unavailable. In first person you sit in the cockpit, where the steering wheel
|
runtime or headset is unavailable. In first person you sit in the cockpit, where the steering wheel
|
||||||
or handlebar turns with your steering, and optional hand steering by heurazy lets you grab it with
|
or handlebar turns with your steering, and hand steering by heurazy lets you grab it with the
|
||||||
the tracked controllers and turn it. See [`OPENXR.md`](OPENXR.md) for setup, configuration, and the
|
tracked controllers and turn it. See [`OPENXR.md`](OPENXR.md) for setup, configuration, and the
|
||||||
current limitations.
|
current limitations.
|
||||||
|
|
||||||
**Music ducking.**
|
**Music ducking.**
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ class SettingsPage(
|
|||||||
choice(
|
choice(
|
||||||
R.string.vr_rotation, R.string.vr_rotation_helper,
|
R.string.vr_rotation, R.string.vr_rotation_helper,
|
||||||
listOf(R.string.vr_rotation_yaw, R.string.vr_rotation_yaw_pitch, R.string.vr_rotation_full),
|
listOf(R.string.vr_rotation_yaw, R.string.vr_rotation_yaw_pitch, R.string.vr_rotation_full),
|
||||||
read = { stringIndex(it, "vr", "first_person_rotation", ROTATIONS) },
|
read = { stringIndex(it, "vr", "first_person_rotation", ROTATIONS, ROTATION_DEFAULT) },
|
||||||
write = { c, index -> c.setString("vr", "first_person_rotation", ROTATIONS[index]) },
|
write = { c, index -> c.setString("vr", "first_person_rotation", ROTATIONS[index]) },
|
||||||
enabledIf = firstPerson,
|
enabledIf = firstPerson,
|
||||||
)
|
)
|
||||||
@@ -160,10 +160,10 @@ class SettingsPage(
|
|||||||
write = { c, index -> c.setString("vr", "first_person_seat", SEATS[index]) },
|
write = { c, index -> c.setString("vr", "first_person_seat", SEATS[index]) },
|
||||||
enabledIf = firstPerson,
|
enabledIf = firstPerson,
|
||||||
)
|
)
|
||||||
// heurazy's grab-and-turn wheel: runtime_config.h's kVrHandSteeringDefault is off.
|
// heurazy's grab-and-turn wheel: runtime_config.h's kVrHandSteeringDefault is on.
|
||||||
toggle(
|
toggle(
|
||||||
R.string.vr_hand_steering, R.string.vr_hand_steering_helper,
|
R.string.vr_hand_steering, R.string.vr_hand_steering_helper,
|
||||||
read = { it.bool("vr", "hand_steering") ?: false },
|
read = { it.bool("vr", "hand_steering") ?: true },
|
||||||
write = { c, value -> c.setBool("vr", "hand_steering", value) },
|
write = { c, value -> c.setBool("vr", "hand_steering", value) },
|
||||||
enabledIf = cockpit,
|
enabledIf = cockpit,
|
||||||
)
|
)
|
||||||
@@ -703,6 +703,9 @@ class SettingsPage(
|
|||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
val ROTATIONS = listOf("yaw", "yaw_pitch", "full")
|
val ROTATIONS = listOf("yaw", "yaw_pitch", "full")
|
||||||
|
|
||||||
|
/** runtime_config.h's kVrFirstPersonRotationDefault. */
|
||||||
|
val ROTATION_DEFAULT = ROTATIONS.indexOf("yaw_pitch")
|
||||||
// The runtime's default ("cockpit") first.
|
// The runtime's default ("cockpit") first.
|
||||||
val SEATS = listOf("cockpit", "custom")
|
val SEATS = listOf("cockpit", "custom")
|
||||||
// The runtime's default ("boost") first: an absent key reads as index 0.
|
// The runtime's default ("boost") first: an absent key reads as index 0.
|
||||||
@@ -726,8 +729,9 @@ class SettingsPage(
|
|||||||
config.number(section, key)?.takeIf { it in min..max } ?: default
|
config.number(section, key)?.takeIf { it in min..max } ?: default
|
||||||
|
|
||||||
/** Unrecognised strings fall back to the first (default) option, as in the runtime. */
|
/** Unrecognised strings fall back to the first (default) option, as in the runtime. */
|
||||||
fun stringIndex(config: TomlConfig, section: String, key: String, values: List<String>): Int =
|
fun stringIndex(config: TomlConfig, section: String, key: String, values: List<String>,
|
||||||
values.indexOf(config.string(section, key)).coerceAtLeast(0)
|
default: Int = 0): Int =
|
||||||
|
values.indexOf(config.string(section, key)).takeIf { it >= 0 } ?: default
|
||||||
|
|
||||||
fun resolution(config: TomlConfig): Double =
|
fun resolution(config: TomlConfig): Double =
|
||||||
config.number("video", "resolution_multiplier")?.takeIf { it in SUPPORTED_RESOLUTIONS } ?: 1.0
|
config.number("video", "resolution_multiplier")?.takeIf { it in SUPPORTED_RESOLUTIONS } ?: 1.0
|
||||||
|
|||||||
@@ -201,8 +201,10 @@ inline constexpr float kVrFirstPersonHeadRightDefault = 0.0f;
|
|||||||
inline constexpr bool kVrFirstPersonHideDriverDefault = true;
|
inline constexpr bool kVrFirstPersonHideDriverDefault = true;
|
||||||
inline constexpr int32_t kVrFirstPersonHiddenModelDefault = 0;
|
inline constexpr int32_t kVrFirstPersonHiddenModelDefault = 0;
|
||||||
inline constexpr float kVrFirstPersonHeadOffsetLimit = 10.0f;
|
inline constexpr float kVrFirstPersonHeadOffsetLimit = 10.0f;
|
||||||
// "yaw", "yaw_pitch" or "full", matching FirstPersonRotation.
|
// "yaw", "yaw_pitch" or "full", matching FirstPersonRotation. The cockpit seat
|
||||||
inline constexpr const char* kVrFirstPersonRotationDefault = "yaw";
|
// is the first-person default, and sitting in the vehicle reads better with its
|
||||||
|
// climb than with a level horizon, so "yaw_pitch" is the default anchor.
|
||||||
|
inline constexpr const char* kVrFirstPersonRotationDefault = "yaw_pitch";
|
||||||
|
|
||||||
inline bool IsSupportedVrFirstPersonRotation(std::string_view value) {
|
inline bool IsSupportedVrFirstPersonRotation(std::string_view value) {
|
||||||
return value == "yaw" || value == "yaw_pitch" || value == "full";
|
return value == "yaw" || value == "yaw_pitch" || value == "full";
|
||||||
@@ -221,11 +223,12 @@ inline constexpr float kVrCockpitUnitsPerMeterMax = 400.0f;
|
|||||||
// The vehicle's steering wheel or handlebar turns with the steering; the
|
// The vehicle's steering wheel or handlebar turns with the steering; the
|
||||||
// vehicle's own model is animated unless native_steering_wheel is off, which
|
// vehicle's own model is animated unless native_steering_wheel is off, which
|
||||||
// draws a separate VR wheel instead. Hand steering (grabbing that wheel with
|
// draws a separate VR wheel instead. Hand steering (grabbing that wheel with
|
||||||
// the tracked controllers, by heurazy) is opt-in. The WheelWizard VR launcher
|
// the tracked controllers, by heurazy) comes with it: the stick still steers
|
||||||
// registers hand_steering with this same default.
|
// until a grip actually takes hold of the wheel. Both launchers register
|
||||||
|
// hand_steering with this same default.
|
||||||
inline constexpr bool kVrSteeringWheelDefault = true;
|
inline constexpr bool kVrSteeringWheelDefault = true;
|
||||||
inline constexpr bool kVrNativeSteeringWheelDefault = true;
|
inline constexpr bool kVrNativeSteeringWheelDefault = true;
|
||||||
inline constexpr bool kVrHandSteeringDefault = false;
|
inline constexpr bool kVrHandSteeringDefault = true;
|
||||||
// Hand steering tuning ranges; the defaults are mkw::vr::WheelTuning's.
|
// Hand steering tuning ranges; the defaults are mkw::vr::WheelTuning's.
|
||||||
inline constexpr float kVrWheelDegreesMin = 20.0f, kVrWheelDegreesMax = 180.0f;
|
inline constexpr float kVrWheelDegreesMin = 20.0f, kVrWheelDegreesMax = 180.0f;
|
||||||
inline constexpr float kVrWheelGrabDistanceMin = 0.15f, kVrWheelGrabDistanceMax = 0.8f;
|
inline constexpr float kVrWheelGrabDistanceMin = 0.15f, kVrWheelGrabDistanceMax = 0.8f;
|
||||||
@@ -531,7 +534,7 @@ inline void EnsureConfigFile() {
|
|||||||
"# Where the view's orientation comes from: \"yaw\" levels the\n"
|
"# Where the view's orientation comes from: \"yaw\" levels the\n"
|
||||||
"# horizon, \"yaw_pitch\" adds the kart's climb but no roll, and\n"
|
"# horizon, \"yaw_pitch\" adds the kart's climb but no roll, and\n"
|
||||||
"# \"full\" takes the kart's whole orientation so the view banks.\n"
|
"# \"full\" takes the kart's whole orientation so the view banks.\n"
|
||||||
"first_person_rotation = \"yaw\"\n"
|
"first_person_rotation = \"yaw_pitch\"\n"
|
||||||
"# In the cockpit the vehicle's steering wheel or handlebar turns\n"
|
"# In the cockpit the vehicle's steering wheel or handlebar turns\n"
|
||||||
"# with the steering. native_steering_wheel animates the vehicle's\n"
|
"# with the steering. native_steering_wheel animates the vehicle's\n"
|
||||||
"# own model; false draws a separate VR wheel instead.\n"
|
"# own model; false draws a separate VR wheel instead.\n"
|
||||||
@@ -545,7 +548,7 @@ inline void EnsureConfigFile() {
|
|||||||
"# the wheel, how quickly the wheel follows the hands, how long\n"
|
"# the wheel, how quickly the wheel follows the hands, how long\n"
|
||||||
"# (seconds) a hand that loses tracking keeps hold, and a short\n"
|
"# (seconds) a hand that loses tracking keeps hold, and a short\n"
|
||||||
"# pulse on grab and release. All changeable live from the F10 menu.\n"
|
"# pulse on grab and release. All changeable live from the F10 menu.\n"
|
||||||
"hand_steering = false\n"
|
"hand_steering = true\n"
|
||||||
"wheel_kart_degrees = 90.0\n"
|
"wheel_kart_degrees = 90.0\n"
|
||||||
"wheel_bike_degrees = 45.0\n"
|
"wheel_bike_degrees = 45.0\n"
|
||||||
"wheel_grab_distance = 0.35\n"
|
"wheel_grab_distance = 0.35\n"
|
||||||
|
|||||||
@@ -207,15 +207,15 @@ int g_vrControllerMode = [] {
|
|||||||
return 0;
|
return 0;
|
||||||
}();
|
}();
|
||||||
constexpr std::array<const char*, 3> kVrFirstPersonRotationNames{"yaw", "yaw_pitch", "full"};
|
constexpr std::array<const char*, 3> kVrFirstPersonRotationNames{"yaw", "yaw_pitch", "full"};
|
||||||
int g_vrFirstPersonRotation = [] {
|
int VrFirstPersonRotationIndex(std::string_view mode) {
|
||||||
const std::string mode = RuntimeConfigFile::VrFirstPersonRotation();
|
|
||||||
for (size_t i = 0; i < kVrFirstPersonRotationNames.size(); ++i) {
|
for (size_t i = 0; i < kVrFirstPersonRotationNames.size(); ++i) {
|
||||||
if (mode == kVrFirstPersonRotationNames[i]) {
|
if (mode == kVrFirstPersonRotationNames[i]) {
|
||||||
return static_cast<int>(i);
|
return static_cast<int>(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}();
|
}
|
||||||
|
int g_vrFirstPersonRotation = VrFirstPersonRotationIndex(RuntimeConfigFile::VrFirstPersonRotation());
|
||||||
// SDL_SCANCODE_UNKNOWN means unbound, which is also what an unrecognised
|
// SDL_SCANCODE_UNKNOWN means unbound, which is also what an unrecognised
|
||||||
// name in the config file resolves to rather than silently picking a key.
|
// name in the config file resolves to rather than silently picking a key.
|
||||||
SDL_Scancode g_vrRecenterScancode = [] {
|
SDL_Scancode g_vrRecenterScancode = [] {
|
||||||
@@ -1618,17 +1618,20 @@ void DrawVrSettings() {
|
|||||||
g_vrCockpitUnitsPerMeter = RuntimeConfigFile::kVrCockpitUnitsPerMeterDefault;
|
g_vrCockpitUnitsPerMeter = RuntimeConfigFile::kVrCockpitUnitsPerMeterDefault;
|
||||||
g_vrSteeringWheel = RuntimeConfigFile::kVrSteeringWheelDefault;
|
g_vrSteeringWheel = RuntimeConfigFile::kVrSteeringWheelDefault;
|
||||||
g_vrNativeSteeringWheel = RuntimeConfigFile::kVrNativeSteeringWheelDefault;
|
g_vrNativeSteeringWheel = RuntimeConfigFile::kVrNativeSteeringWheelDefault;
|
||||||
|
g_vrHandSteering = RuntimeConfigFile::kVrHandSteeringDefault;
|
||||||
RuntimeConfigFile::SetVrFirstPersonSeat(RuntimeConfigFile::kVrFirstPersonSeatDefault);
|
RuntimeConfigFile::SetVrFirstPersonSeat(RuntimeConfigFile::kVrFirstPersonSeatDefault);
|
||||||
RuntimeConfigFile::SetVrCockpitUnitsPerMeter(g_vrCockpitUnitsPerMeter);
|
RuntimeConfigFile::SetVrCockpitUnitsPerMeter(g_vrCockpitUnitsPerMeter);
|
||||||
RuntimeConfigFile::SetVrSteeringWheel(g_vrSteeringWheel);
|
RuntimeConfigFile::SetVrSteeringWheel(g_vrSteeringWheel);
|
||||||
RuntimeConfigFile::SetVrNativeSteeringWheel(g_vrNativeSteeringWheel);
|
RuntimeConfigFile::SetVrNativeSteeringWheel(g_vrNativeSteeringWheel);
|
||||||
|
RuntimeConfigFile::SetVrHandSteering(g_vrHandSteering);
|
||||||
g_vrFirstPersonUnitsPerMeter = RuntimeConfigFile::kVrFirstPersonUnitsPerMeterDefault;
|
g_vrFirstPersonUnitsPerMeter = RuntimeConfigFile::kVrFirstPersonUnitsPerMeterDefault;
|
||||||
g_vrFirstPersonHeadUp = RuntimeConfigFile::kVrFirstPersonHeadUpDefault;
|
g_vrFirstPersonHeadUp = RuntimeConfigFile::kVrFirstPersonHeadUpDefault;
|
||||||
g_vrFirstPersonHeadForward = RuntimeConfigFile::kVrFirstPersonHeadForwardDefault;
|
g_vrFirstPersonHeadForward = RuntimeConfigFile::kVrFirstPersonHeadForwardDefault;
|
||||||
g_vrFirstPersonHeadRight = RuntimeConfigFile::kVrFirstPersonHeadRightDefault;
|
g_vrFirstPersonHeadRight = RuntimeConfigFile::kVrFirstPersonHeadRightDefault;
|
||||||
g_vrFirstPersonHideDriver = RuntimeConfigFile::kVrFirstPersonHideDriverDefault;
|
g_vrFirstPersonHideDriver = RuntimeConfigFile::kVrFirstPersonHideDriverDefault;
|
||||||
g_vrFirstPersonHiddenModel = RuntimeConfigFile::kVrFirstPersonHiddenModelDefault;
|
g_vrFirstPersonHiddenModel = RuntimeConfigFile::kVrFirstPersonHiddenModelDefault;
|
||||||
g_vrFirstPersonRotation = 0;
|
g_vrFirstPersonRotation =
|
||||||
|
VrFirstPersonRotationIndex(RuntimeConfigFile::kVrFirstPersonRotationDefault);
|
||||||
RuntimeConfigFile::SetVrFirstPersonRotation(
|
RuntimeConfigFile::SetVrFirstPersonRotation(
|
||||||
RuntimeConfigFile::kVrFirstPersonRotationDefault);
|
RuntimeConfigFile::kVrFirstPersonRotationDefault);
|
||||||
RuntimeConfigFile::SetVrFirstPersonUnitsPerMeter(g_vrFirstPersonUnitsPerMeter);
|
RuntimeConfigFile::SetVrFirstPersonUnitsPerMeter(g_vrFirstPersonUnitsPerMeter);
|
||||||
|
|||||||
Reference in new issue
Block a user