Skip to content

Commit

Permalink
Input: Add Controller Pitch Offset option
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Jan 23, 2024
1 parent 6a19118 commit 167a1af
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 12 deletions.
2 changes: 2 additions & 0 deletions src/mods/VR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2375,6 +2375,8 @@ void VR::on_draw_sidebar_entry(std::string_view name) {
ImGui::SetNextItemOpen(true, ImGuiCond_::ImGuiCond_Once);
if (ImGui::TreeNode("Controller")) {
m_joystick_deadzone->draw("VR Joystick Deadzone");
m_controller_pitch_offset->draw("Controller Pitch Offset");

m_dpad_shifting->draw("DPad Shifting");
ImGui::SameLine();
m_swap_controllers->draw("Left-handed Controller Inputs");
Expand Down
7 changes: 7 additions & 0 deletions src/mods/VR.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,10 @@ class VR : public Mod {
return m_snapturn_angle->value();
}

float get_controller_pitch_offset() const {
return m_controller_pitch_offset->value();
}

bool should_skip_post_init_properties() const {
return m_compatibility_skip_pip->value();
}
Expand Down Expand Up @@ -792,6 +796,8 @@ class VR : public Mod {
bool m_snapturn_left{false};
bool m_was_snapturn_run_on_input{false};

const ModSlider::Ptr m_controller_pitch_offset{ ModSlider::create(generate_name("ControllerPitchOffset"), -90.0f, 90.0f, 0.0f) };

// Aim method and movement orientation are not the same thing, but they can both have the same options
const ModCombo::Ptr m_aim_method{ ModCombo::create(generate_name("AimMethod"), s_aim_method_names, AimMethod::GAME) };
const ModCombo::Ptr m_movement_orientation{ ModCombo::create(generate_name("MovementOrientation"), s_aim_method_names, AimMethod::GAME) };
Expand Down Expand Up @@ -908,6 +914,7 @@ class VR : public Mod {
*m_snapturn,
*m_snapturn_joystick_deadzone,
*m_snapturn_angle,
*m_controller_pitch_offset,
*m_aim_method,
*m_movement_orientation,
*m_aim_use_pawn_control_rotation,
Expand Down
38 changes: 28 additions & 10 deletions src/mods/vr/runtimes/OpenVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,23 @@ VRRuntime::Error OpenVR::update_poses(bool from_view_extensions, uint32_t frame_

std::unique_lock _{ this->pose_mtx };

const auto& vr = VR::get();
const auto pitch_offset = vr->get_controller_pitch_offset();

auto correct_rotation = [pitch_offset](const glm::mat4& mat) {
if (pitch_offset == 0.0f) {
return mat;
}

const auto rot = glm::extractMatrixRotation(mat);
const auto rot_corrected = glm::rotate(rot, glm::radians(pitch_offset), glm::vec3{ 1.0f, 0.0f, 0.0f });

auto new_mat = rot_corrected;
new_mat[3] = mat[3];

return new_mat;
};

memcpy(this->render_poses.data(), this->real_render_poses.data(), sizeof(this->render_poses));

// Update grip and aim poses independently of render poses
Expand All @@ -49,47 +66,48 @@ VRRuntime::Error OpenVR::update_poses(bool from_view_extensions, uint32_t frame_
const auto res1_grip = vr::VRInput()->GetPoseActionDataForNextFrame(this->grip_pose_action, vr::TrackingUniverseStanding, &left_grip_pose_data, sizeof(left_grip_pose_data), this->left_controller_handle);
const auto res2_grip = vr::VRInput()->GetPoseActionDataForNextFrame(this->grip_pose_action, vr::TrackingUniverseStanding, &right_grip_pose_data, sizeof(right_grip_pose_data), this->right_controller_handle);


if (this->left_controller_index < this->render_poses.size()) {
if (res1_aim == vr::VRInputError_None) {
const auto matrix = Matrix4x4f{ *(Matrix3x4f*)&left_aim_pose_data.pose.mDeviceToAbsoluteTracking };
this->aim_matrices[VRRuntime::Hand::LEFT] = glm::rowMajor4(matrix);
this->aim_matrices[VRRuntime::Hand::LEFT] = correct_rotation(glm::rowMajor4(matrix));
} else {
const auto matrix = Matrix4x4f{ *(Matrix3x4f*)&this->render_poses[this->left_controller_index].mDeviceToAbsoluteTracking.m };
this->aim_matrices[VRRuntime::Hand::LEFT] = glm::rowMajor4(matrix);
this->aim_matrices[VRRuntime::Hand::LEFT] = correct_rotation(glm::rowMajor4(matrix));
}

if (res1_grip == vr::VRInputError_None) {
const auto matrix = Matrix4x4f{ *(Matrix3x4f*)&left_grip_pose_data.pose.mDeviceToAbsoluteTracking };
this->grip_matrices[VRRuntime::Hand::LEFT] = glm::rowMajor4(matrix);
this->grip_matrices[VRRuntime::Hand::LEFT] = correct_rotation(glm::rowMajor4(matrix));
} else {
const auto matrix = Matrix4x4f{ *(Matrix3x4f*)&this->render_poses[this->left_controller_index].mDeviceToAbsoluteTracking.m };
this->grip_matrices[VRRuntime::Hand::LEFT] = glm::rowMajor4(matrix);
this->grip_matrices[VRRuntime::Hand::LEFT] = correct_rotation(glm::rowMajor4(matrix));
}
}

if (this->right_controller_index < this->render_poses.size()) {
if (res2_aim == vr::VRInputError_None) {
const auto matrix = Matrix4x4f{ *(Matrix3x4f*)&right_aim_pose_data.pose.mDeviceToAbsoluteTracking };
this->aim_matrices[VRRuntime::Hand::RIGHT] = glm::rowMajor4(matrix);
this->aim_matrices[VRRuntime::Hand::RIGHT] = correct_rotation(glm::rowMajor4(matrix));
} else {
const auto matrix = Matrix4x4f{ *(Matrix3x4f*)&this->render_poses[this->right_controller_index].mDeviceToAbsoluteTracking.m };
this->aim_matrices[VRRuntime::Hand::RIGHT] = glm::rowMajor4(matrix);
this->aim_matrices[VRRuntime::Hand::RIGHT] = correct_rotation(glm::rowMajor4(matrix));
}

if (res2_grip == vr::VRInputError_None) {
const auto matrix = Matrix4x4f{ *(Matrix3x4f*)&right_grip_pose_data.pose.mDeviceToAbsoluteTracking };
this->grip_matrices[VRRuntime::Hand::RIGHT] = glm::rowMajor4(matrix);
this->grip_matrices[VRRuntime::Hand::RIGHT] = correct_rotation(glm::rowMajor4(matrix));
} else {
const auto matrix = Matrix4x4f{ *(Matrix3x4f*)&this->render_poses[this->right_controller_index].mDeviceToAbsoluteTracking.m };
this->grip_matrices[VRRuntime::Hand::RIGHT] = glm::rowMajor4(matrix);
this->grip_matrices[VRRuntime::Hand::RIGHT] = correct_rotation(glm::rowMajor4(matrix));
}
}
} else if (left_controller_index < this->render_poses.size() && right_controller_index < this->render_poses.size()) {
const auto left_matrix = Matrix4x4f{ *(Matrix3x4f*)&this->render_poses[this->left_controller_index].mDeviceToAbsoluteTracking.m };
const auto right_matrix = Matrix4x4f{ *(Matrix3x4f*)&this->render_poses[this->right_controller_index].mDeviceToAbsoluteTracking.m };

this->grip_matrices[VRRuntime::Hand::LEFT] = glm::rowMajor4(left_matrix);
this->grip_matrices[VRRuntime::Hand::RIGHT] = glm::rowMajor4(right_matrix);
this->grip_matrices[VRRuntime::Hand::LEFT] = correct_rotation(glm::rowMajor4(left_matrix));
this->grip_matrices[VRRuntime::Hand::RIGHT] = correct_rotation(glm::rowMajor4(right_matrix));
}

bool should_enqueue = false;
Expand Down
18 changes: 16 additions & 2 deletions src/mods/vr/runtimes/OpenXR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ VRRuntime::Error OpenXR::update_poses(bool from_view_extensions, uint32_t frame_
return VRRuntime::Error::SUCCESS;
}

const auto& vr = VR::get();

/*if (!this->needs_pose_update) {
return VRRuntime::Error::SUCCESS;
}*/
Expand Down Expand Up @@ -296,7 +298,13 @@ VRRuntime::Error OpenXR::update_poses(bool from_view_extensions, uint32_t frame_
return (VRRuntime::Error)result;
}

this->aim_matrices[i] = Matrix4x4f{runtimes::OpenXR::to_glm(hand.aim_location.pose.orientation)};
auto orientation_aim = runtimes::OpenXR::to_glm(hand.aim_location.pose.orientation);

if (const auto pitch = vr->get_controller_pitch_offset(); pitch != 0.0f) {
orientation_aim = glm::rotate(orientation_aim, glm::radians(pitch), Vector3f{1.0f, 0.0f, 0.0f});
}

this->aim_matrices[i] = Matrix4x4f{orientation_aim};
this->aim_matrices[i][3] = Vector4f{*(Vector3f*)&hand.aim_location.pose.position, 1.0f};

hand.grip_location.next = &hand.grip_velocity;
Expand All @@ -307,7 +315,13 @@ VRRuntime::Error OpenXR::update_poses(bool from_view_extensions, uint32_t frame_
return (VRRuntime::Error)result;
}

this->grip_matrices[i] = Matrix4x4f{runtimes::OpenXR::to_glm(hand.grip_location.pose.orientation)};
auto orientation_grip = runtimes::OpenXR::to_glm(hand.grip_location.pose.orientation);

if (const auto pitch = vr->get_controller_pitch_offset(); pitch != 0.0f) {
orientation_grip = glm::rotate(orientation_grip, glm::radians(pitch), Vector3f{1.0f, 0.0f, 0.0f});
}

this->grip_matrices[i] = Matrix4x4f{orientation_grip};
this->grip_matrices[i][3] = Vector4f{*(Vector3f*)&hand.grip_location.pose.position, 1.0f};
}

Expand Down

0 comments on commit 167a1af

Please sign in to comment.