mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 01:00:14 +02:00
Add placeholder steering wheel option for VR driving
This commit is contained in:
1 parent
ebc97ef9ce
commit
85fab2fa09
10 files changed
+101
-22
No files matched your search
@@ -60,6 +60,7 @@ first_person_hidden_model = 0
|
||||
first_person_rotation = "yaw_pitch"
|
||||
steering_wheel = true
|
||||
native_steering_wheel = true
|
||||
placeholder_steering_wheel = false
|
||||
object_culling = false
|
||||
hand_steering = true
|
||||
cockpit_item_hand = "left"
|
||||
@@ -599,9 +600,16 @@ guest's own vertices are never written, and the copies are dropped after the fra
|
||||
turn their handle part in the game already; its copy is only re-seated on the cockpit frame so the
|
||||
bars stay with your hands while the bike banks. The wheel rides in the same frame as the view: the
|
||||
level seat for `"yaw"`, the kart's own orientation for `"yaw_pitch"` and `"full"`. While no draw takes
|
||||
the copy (for 30 frames running; the race's opening pan does this) a separate VR wheel stands in,
|
||||
which is also what `native_steering_wheel = false` draws. The copy keeps being published, so the
|
||||
vehicle's own wheel returns as soon as draws take it again, and the log notes both switches.
|
||||
the copy (for 30 frames running; the race's opening pan does this) the vehicle's own is drawn as
|
||||
the game poses it. The copy keeps being published, so the vehicle's own wheel turns again as soon as
|
||||
draws take it again, and the log notes both switches.
|
||||
|
||||
**The placeholder wheel.** `placeholder_steering_wheel = true` (off by default; F10 and the Quest
|
||||
launcher's Settings > VR) draws a separate VR wheel for karts, or handlebar for bikes, whenever the
|
||||
vehicle's own is not the one turning: with `native_steering_wheel = false`, and during the stretches
|
||||
above where no draw takes the copy. Off, only the vehicle's own is seen, and the hands reach for it wherever its geometry is known,
|
||||
turning or not; where it is not (a kart whose grips were not found), they reach for where the
|
||||
placeholder would stand, in front of the seat.
|
||||
|
||||
Validated on the extracted PAL disc's 216 single-player kart/character and Mii combinations
|
||||
(all 18 kart types): each resolves its node-0 bone as the runtime does and selects the complete
|
||||
|
||||
@@ -182,6 +182,13 @@ class SettingsPage(
|
||||
write = { c, index -> c.setString("vr", "first_person_seat", SEATS[index]) },
|
||||
enabledIf = firstPerson,
|
||||
)
|
||||
// runtime_config.h's kVrPlaceholderSteeringWheelDefault is off.
|
||||
toggle(
|
||||
R.string.vr_placeholder_wheel, R.string.vr_placeholder_wheel_helper,
|
||||
read = { it.bool("vr", "placeholder_steering_wheel") ?: false },
|
||||
write = { c, value -> c.setBool("vr", "placeholder_steering_wheel", value) },
|
||||
enabledIf = cockpit,
|
||||
)
|
||||
// heurazy's grab-and-turn wheel: runtime_config.h's kVrHandSteeringDefault is on.
|
||||
toggle(
|
||||
R.string.vr_hand_steering, R.string.vr_hand_steering_helper,
|
||||
|
||||
@@ -533,6 +533,8 @@
|
||||
<string name="vr_seat_helper">The cockpit puts you at the driver\'s eyes, life-size, with the steering wheel or handlebar turning within reach. Custom uses the head offsets from the in-headset settings.</string>
|
||||
<string name="vr_seat_cockpit">Cockpit</string>
|
||||
<string name="vr_seat_custom">Custom</string>
|
||||
<string name="vr_placeholder_wheel">Placeholder wheel or handlebar</string>
|
||||
<string name="vr_placeholder_wheel_helper">In the cockpit, draws a separate VR steering wheel (karts) or handlebar (bikes) whenever the vehicle\'s own is not the one turning, as in the race\'s opening pan. Off, you only see the vehicle\'s own.</string>
|
||||
<string name="vr_hand_steering">Hand steering</string>
|
||||
<string name="vr_hand_steering_helper">In the cockpit, squeeze a grip near the steering wheel or handlebar to grab it, and turn it to steer. Releasing both grips gives steering back to the stick. Hand steering by heurazy.</string>
|
||||
<string name="vr_cockpit_item_hand">Item in cockpit hand</string>
|
||||
|
||||
@@ -76,6 +76,7 @@ struct RuntimeUserConfig {
|
||||
std::optional<float> vrCockpitUnitsPerMeter;
|
||||
std::optional<bool> vrSteeringWheel;
|
||||
std::optional<bool> vrNativeSteeringWheel;
|
||||
std::optional<bool> vrPlaceholderSteeringWheel;
|
||||
std::optional<bool> vrObjectCulling;
|
||||
std::optional<bool> vrHandSteering;
|
||||
std::optional<std::string> vrCockpitItemHand;
|
||||
@@ -231,13 +232,17 @@ inline constexpr float kVrCockpitUnitsPerMeterDefault = 100.0f;
|
||||
inline constexpr float kVrCockpitUnitsPerMeterMin = 20.0f;
|
||||
inline constexpr float kVrCockpitUnitsPerMeterMax = 400.0f;
|
||||
// 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
|
||||
// draws a separate VR wheel instead. Hand steering (grabbing that wheel with
|
||||
// the tracked controllers, by heurazy) comes with it: the stick still steers
|
||||
// until a grip actually takes hold of the wheel. Both launchers register
|
||||
// hand_steering with this same default.
|
||||
// vehicle's own model is animated unless native_steering_wheel is off.
|
||||
// placeholder_steering_wheel draws a separate VR wheel or handlebar whenever
|
||||
// the vehicle's own is not the one turning (native_steering_wheel off, or a
|
||||
// draw that does not take the animated copy); off, the vehicle's own is all
|
||||
// there is. Hand steering (grabbing that wheel with the tracked controllers,
|
||||
// by heurazy) comes with it: the stick still steers 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 kVrNativeSteeringWheelDefault = true;
|
||||
inline constexpr bool kVrPlaceholderSteeringWheelDefault = false;
|
||||
inline constexpr bool kVrHandSteeringDefault = true;
|
||||
inline constexpr const char* kVrCockpitItemHandDefault = "left";
|
||||
// A quick swing of the item hand forward or back throws the item that way.
|
||||
@@ -594,9 +599,11 @@ inline void EnsureConfigFile() {
|
||||
"first_person_rotation = \"yaw_pitch\"\n"
|
||||
"# In the cockpit the vehicle's steering wheel or handlebar turns\n"
|
||||
"# with the steering. native_steering_wheel animates the vehicle's\n"
|
||||
"# own model; false draws a separate VR wheel instead.\n"
|
||||
"# own model. placeholder_steering_wheel draws a separate VR wheel\n"
|
||||
"# or handlebar whenever the vehicle's own is not the one turning.\n"
|
||||
"steering_wheel = true\n"
|
||||
"native_steering_wheel = true\n"
|
||||
"placeholder_steering_wheel = false\n"
|
||||
"# The game hides karts and objects its own camera cannot see.\n"
|
||||
"# object_culling = false draws them anyway, so a head turn or a\n"
|
||||
"# look over the shoulder shows them; it costs GPU time.\n"
|
||||
@@ -887,6 +894,7 @@ inline RuntimeUserConfig ParseConfigDocument(const toml::value& document) {
|
||||
readRangedFloat("cockpit_units_per_meter", kVrCockpitUnitsPerMeterMin, kVrCockpitUnitsPerMeterMax);
|
||||
config.vrSteeringWheel = FindConfigValue<bool>(document, "vr", "steering_wheel");
|
||||
config.vrNativeSteeringWheel = FindConfigValue<bool>(document, "vr", "native_steering_wheel");
|
||||
config.vrPlaceholderSteeringWheel = FindConfigValue<bool>(document, "vr", "placeholder_steering_wheel");
|
||||
config.vrObjectCulling = FindConfigValue<bool>(document, "vr", "object_culling");
|
||||
config.vrHandSteering = FindConfigValue<bool>(document, "vr", "hand_steering");
|
||||
config.vrCockpitItemHand = FindConfigValue<std::string>(document, "vr", "cockpit_item_hand");
|
||||
@@ -1283,6 +1291,11 @@ inline bool SetVrNativeSteeringWheel(bool value) {
|
||||
return WriteSetting("vr", "native_steering_wheel", value ? "true" : "false");
|
||||
}
|
||||
|
||||
inline bool SetVrPlaceholderSteeringWheel(bool value) {
|
||||
Mutable().vrPlaceholderSteeringWheel = value;
|
||||
return WriteSetting("vr", "placeholder_steering_wheel", value ? "true" : "false");
|
||||
}
|
||||
|
||||
inline bool SetVrObjectCulling(bool value) {
|
||||
Mutable().vrObjectCulling = value;
|
||||
return WriteSetting("vr", "object_culling", value ? "true" : "false");
|
||||
@@ -1787,6 +1800,10 @@ inline bool VrNativeSteeringWheel(bool fallback = kVrNativeSteeringWheelDefault)
|
||||
return Get().vrNativeSteeringWheel.value_or(fallback);
|
||||
}
|
||||
|
||||
inline bool VrPlaceholderSteeringWheel(bool fallback = kVrPlaceholderSteeringWheelDefault) {
|
||||
return Get().vrPlaceholderSteeringWheel.value_or(fallback);
|
||||
}
|
||||
|
||||
inline bool VrObjectCulling(bool fallback = kVrObjectCullingDefault) {
|
||||
return Get().vrObjectCulling.value_or(fallback);
|
||||
}
|
||||
|
||||
@@ -91,6 +91,15 @@ inline float MaxWheelAngle(bool bike, const WheelTuning& tuning) noexcept {
|
||||
return clamped * 0.01745329252f;
|
||||
}
|
||||
|
||||
// Whether the overlay draws a separate VR wheel or handlebar: only when
|
||||
// placeholder_steering_wheel asks for one and the vehicle's own is not the one
|
||||
// turning. Without it the hands reach for the vehicle's own wherever its
|
||||
// geometry is known, turning or not.
|
||||
inline bool DrawsPlaceholderControl(bool steering_wheel, bool native_steering_wheel, bool native_mesh_prepared,
|
||||
bool placeholder) noexcept {
|
||||
return placeholder && steering_wheel && !(native_steering_wheel && native_mesh_prepared);
|
||||
}
|
||||
|
||||
// Grips only grab. As a Wii Remote they press nothing at all (C, the game's
|
||||
// look-behind, is right B); as a gamepad they are the shoulders, so a holding
|
||||
// hand's squeeze is released for the game. The wheel replaces the left stick's
|
||||
|
||||
@@ -168,6 +168,7 @@ int g_vrFirstPersonSeat = RuntimeConfigFile::VrFirstPersonSeat() == "custom" ? 1
|
||||
float g_vrCockpitUnitsPerMeter = RuntimeConfigFile::VrCockpitUnitsPerMeter();
|
||||
bool g_vrSteeringWheel = RuntimeConfigFile::VrSteeringWheel();
|
||||
bool g_vrNativeSteeringWheel = RuntimeConfigFile::VrNativeSteeringWheel();
|
||||
bool g_vrPlaceholderSteeringWheel = RuntimeConfigFile::VrPlaceholderSteeringWheel();
|
||||
bool g_vrObjectCulling = RuntimeConfigFile::VrObjectCulling();
|
||||
bool g_vrHandSteering = RuntimeConfigFile::VrHandSteering();
|
||||
constexpr std::array<const char*, 3> kVrCockpitItemHands{"Left", "Right", "Off"};
|
||||
@@ -1214,9 +1215,15 @@ void DrawVrSteeringWheelSettings() {
|
||||
mkw::vr::MkwVRFirstPersonApplyConfiguredSettings();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Turns the wheel or handlebar of the vehicle's own model. Off draws a "
|
||||
"separate VR wheel instead, which is also what appears when a vehicle's "
|
||||
"own wheel cannot be animated.");
|
||||
ImGui::SetTooltip("Turns the wheel or handlebar of the vehicle's own model.");
|
||||
}
|
||||
if (ImGui::Checkbox("Placeholder wheel or handlebar", &g_vrPlaceholderSteeringWheel)) {
|
||||
RuntimeConfigFile::SetVrPlaceholderSteeringWheel(g_vrPlaceholderSteeringWheel);
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Draws a separate VR wheel (karts) or handlebar (bikes) whenever the "
|
||||
"vehicle's own is not the one turning: with the option above off, or while "
|
||||
"the game's draws do not take its animation, as in the race's opening pan.");
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
if (ImGui::Checkbox("Hand steering (by heurazy)", &g_vrHandSteering)) {
|
||||
@@ -1317,7 +1324,8 @@ void DrawVrSteeringWheelSettings() {
|
||||
anchor.bike ? "handlebar" : "wheel",
|
||||
!anchor.native_wheel.valid ? "grips not found"
|
||||
: anchor.native_mesh_prepared ? "vehicle's own"
|
||||
: "VR wheel",
|
||||
: g_vrSteeringWheel && g_vrPlaceholderSteeringWheel ? "placeholder"
|
||||
: "vehicle's own, not animated",
|
||||
anchor.units_per_meter, GxNativeWheel::LastDrawCount());
|
||||
}
|
||||
}
|
||||
@@ -1769,6 +1777,7 @@ void DrawVrCameraSettings() {
|
||||
g_vrCockpitUnitsPerMeter = RuntimeConfigFile::kVrCockpitUnitsPerMeterDefault;
|
||||
g_vrSteeringWheel = RuntimeConfigFile::kVrSteeringWheelDefault;
|
||||
g_vrNativeSteeringWheel = RuntimeConfigFile::kVrNativeSteeringWheelDefault;
|
||||
g_vrPlaceholderSteeringWheel = RuntimeConfigFile::kVrPlaceholderSteeringWheelDefault;
|
||||
g_vrHandSteering = RuntimeConfigFile::kVrHandSteeringDefault;
|
||||
g_vrCockpitItemHand = 0;
|
||||
g_vrCockpitItemThrow = RuntimeConfigFile::kVrCockpitItemThrowDefault;
|
||||
@@ -1776,6 +1785,7 @@ void DrawVrCameraSettings() {
|
||||
RuntimeConfigFile::SetVrCockpitUnitsPerMeter(g_vrCockpitUnitsPerMeter);
|
||||
RuntimeConfigFile::SetVrSteeringWheel(g_vrSteeringWheel);
|
||||
RuntimeConfigFile::SetVrNativeSteeringWheel(g_vrNativeSteeringWheel);
|
||||
RuntimeConfigFile::SetVrPlaceholderSteeringWheel(g_vrPlaceholderSteeringWheel);
|
||||
RuntimeConfigFile::SetVrHandSteering(g_vrHandSteering);
|
||||
RuntimeConfigFile::SetVrCockpitItemHand(RuntimeConfigFile::kVrCockpitItemHandDefault);
|
||||
RuntimeConfigFile::SetVrCockpitItemThrow(g_vrCockpitItemThrow);
|
||||
|
||||
@@ -1176,9 +1176,10 @@ bool ComputeCockpitAnchorLocked(const Mtx34& view_from_world, const KartPoseRead
|
||||
return true;
|
||||
}
|
||||
|
||||
// After the frame's draws: drop the wheel copies, and let the VR wheel stand
|
||||
// in while no draw takes them (the race's opening pan, for one). Copies keep
|
||||
// being published, so the vehicle's own wheel returns as soon as they match.
|
||||
// After the frame's draws: drop the wheel copies, and let the placeholder VR
|
||||
// wheel stand in (when enabled) while no draw takes them (the race's opening
|
||||
// pan, for one). Copies keep being published, so the vehicle's own wheel
|
||||
// returns as soon as they match.
|
||||
void FinishNativeWheelFrameLocked() noexcept {
|
||||
if (!g_state.wheel_arrays_posted) {
|
||||
return;
|
||||
@@ -1206,8 +1207,11 @@ void FinishNativeWheelFrameLocked() noexcept {
|
||||
++g_state.native_wheel_switch_logs;
|
||||
RT_LOG(RT_TAG_RUNTIME) << "[mkw-vr] native steering wheel: no draw took the animated copy of vehicle 0x"
|
||||
<< std::hex << g_state.cockpit.body << std::dec << " in "
|
||||
<< kNativeWheelUnmatchedFrames
|
||||
<< " frames; drawing the VR steering wheel until one does" << std::endl;
|
||||
<< kNativeWheelUnmatchedFrames << " frames; "
|
||||
<< (RuntimeConfigFile::VrPlaceholderSteeringWheel()
|
||||
? "drawing the placeholder VR wheel until one does"
|
||||
: "the vehicle's own is drawn as the game poses it until one does")
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1408,6 +1408,7 @@ void OpenXRInput::UpdateDriving(XrTime display_time, const driving::SeatFrame& s
|
||||
const bool hand_steering = RuntimeConfigFile::VrHandSteering();
|
||||
const bool steering_wheel = RuntimeConfigFile::VrSteeringWheel();
|
||||
const bool native_steering_wheel = RuntimeConfigFile::VrNativeSteeringWheel();
|
||||
const bool placeholder_steering_wheel = RuntimeConfigFile::VrPlaceholderSteeringWheel();
|
||||
const float dt = m_wheel_time != 0 && display_time > m_wheel_time
|
||||
? static_cast<float>(display_time - m_wheel_time) * 1.0e-9f
|
||||
: 1.0f / 90.0f;
|
||||
@@ -1417,10 +1418,10 @@ void OpenXRInput::UpdateDriving(XrTime display_time, const driving::SeatFrame& s
|
||||
snapshot.cockpit_active = true;
|
||||
snapshot.hand_steering = hand_steering;
|
||||
snapshot.bike = anchor.bike;
|
||||
// The vehicle's own control is the one turning (or none is shown at all),
|
||||
// so the overlay adds no separate wheel.
|
||||
snapshot.synthetic_control =
|
||||
steering_wheel && !(native_steering_wheel && anchor.native_mesh_prepared);
|
||||
// A separate wheel only when asked for and the vehicle's own is not the one
|
||||
// turning.
|
||||
snapshot.synthetic_control = driving::DrawsPlaceholderControl(
|
||||
steering_wheel, native_steering_wheel, anchor.native_mesh_prepared, placeholder_steering_wheel);
|
||||
|
||||
// Which control the hands reach for: the vehicle's own wherever its
|
||||
// geometry is known and no separate wheel is drawn, a handlebar always
|
||||
|
||||
@@ -26,6 +26,11 @@ int main() {
|
||||
Require(Parse("[vr]\ncockpit_item_throw = false\n").vrCockpitItemThrow == false);
|
||||
Require(Parse("[vr]\ncockpit_item_throw = true\n").vrCockpitItemThrow == true);
|
||||
Require(!Parse("[vr]\n").vrCockpitItemThrow.has_value());
|
||||
// [vr] placeholder_steering_wheel: the separate VR wheel or handlebar is opt-in.
|
||||
Require(!RuntimeConfigFile::kVrPlaceholderSteeringWheelDefault);
|
||||
Require(Parse("[vr]\nplaceholder_steering_wheel = true\n").vrPlaceholderSteeringWheel == true);
|
||||
Require(Parse("[vr]\nplaceholder_steering_wheel = false\n").vrPlaceholderSteeringWheel == false);
|
||||
Require(!Parse("[vr]\n").vrPlaceholderSteeringWheel.has_value());
|
||||
// [vr] foveation: the Quest's foveated rendering level, index-matched to
|
||||
// aurora_set_stereo_foveation.
|
||||
for (std::string_view level : RuntimeConfigFile::kVrFoveationLevels) {
|
||||
|
||||
@@ -108,6 +108,21 @@ void TestSeatFrame() {
|
||||
CheckNear(m[11], -1.0f, "lean turns up into forward", 1e-5f);
|
||||
}
|
||||
|
||||
void TestPlaceholderControl() {
|
||||
// Arguments: steering_wheel, native_steering_wheel, native_mesh_prepared, placeholder.
|
||||
Check(!driving::DrawsPlaceholderControl(true, true, false, false),
|
||||
"no placeholder while the vehicle's own is not animated, unless asked for");
|
||||
Check(!driving::DrawsPlaceholderControl(true, false, false, false),
|
||||
"no placeholder with the vehicle's own wheel off, unless asked for");
|
||||
Check(driving::DrawsPlaceholderControl(true, true, false, true),
|
||||
"the placeholder stands in while the vehicle's own is not animated");
|
||||
Check(driving::DrawsPlaceholderControl(true, false, true, true),
|
||||
"the placeholder replaces the vehicle's own wheel when that is off");
|
||||
Check(!driving::DrawsPlaceholderControl(true, true, true, true),
|
||||
"no placeholder while the vehicle's own is the one turning");
|
||||
Check(!driving::DrawsPlaceholderControl(false, false, false, true), "no wheel turns at all");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
@@ -115,6 +130,7 @@ int main() {
|
||||
TestMaxAngle();
|
||||
TestVisual();
|
||||
TestSeatFrame();
|
||||
TestPlaceholderControl();
|
||||
if (g_failures != 0) {
|
||||
std::cerr << g_failures << " check(s) failed\n";
|
||||
return 1;
|
||||
|
||||
Reference in new issue
Block a user