Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add controller rotation / position offsets #165

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
8 changes: 4 additions & 4 deletions src/mods/UObjectHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,8 @@ void UObjectHook::tick_attachments(Rotator<float>* view_rotation, const float wo
return;
}

glm::vec3 right_hand_position = vr->get_grip_position(vr->get_right_controller_index());
glm::quat right_hand_rotation = vr->get_aim_rotation(vr->get_right_controller_index());
glm::vec3 right_hand_position = vr->get_controller_position_with_offset(VRRuntime::Hand::RIGHT);
glm::quat right_hand_rotation = vr->get_controller_rotation_with_offset(VRRuntime::Hand::RIGHT);// vr->get_aim_rotation(vr->get_right_controller_index());

const float lerp_speed = m_attach_lerp_speed->value() * m_last_delta_time;

Expand All @@ -452,8 +452,8 @@ void UObjectHook::tick_attachments(Rotator<float>* view_rotation, const float wo
const auto original_right_hand_rotation = right_hand_rotation;
const auto original_right_hand_position = right_hand_position - hmd_origin;

glm::vec3 left_hand_position = vr->get_grip_position(vr->get_left_controller_index());
glm::quat left_hand_rotation = vr->get_aim_rotation(vr->get_left_controller_index());
glm::vec3 left_hand_position = vr->get_controller_position_with_offset(VRRuntime::Hand::LEFT);
glm::quat left_hand_rotation = vr->get_controller_rotation_with_offset(VRRuntime::Hand::LEFT); // vr->get_aim_rotation(vr->get_left_controller_index());

if (m_attach_lerp_enabled->value()) {
auto spherical_distance_left = glm::dot(left_hand_rotation, m_last_left_aim_rotation);
Expand Down
57 changes: 56 additions & 1 deletion src/mods/VR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2376,7 +2376,9 @@ 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");

// JB: pitch offset is settable in the separate 'offsets' submenu
// m_controller_pitch_offset->draw("Controller Pitch Offset");

m_dpad_shifting->draw("DPad Shifting");
ImGui::SameLine();
Expand Down Expand Up @@ -2405,6 +2407,59 @@ void VR::on_draw_sidebar_entry(std::string_view name) {
ImGui::TreePop();
}

if (ImGui::TreeNode("Motion Controller Aim Offsets")) {
float left_controller_rotation_offset[] = {m_left_controller_rotation_offset_x->value(),
m_left_controller_rotation_offset_y->value(), m_left_controller_rotation_offset_z->value()};
if (ImGui::SliderFloat3("Left Rotation", left_controller_rotation_offset, -180.0f, 180.0f)) {
m_left_controller_rotation_offset_x->value() = left_controller_rotation_offset[0];
m_left_controller_rotation_offset_y->value() = left_controller_rotation_offset[1];
m_left_controller_rotation_offset_z->value() = left_controller_rotation_offset[2];
}
if (ImGui::Button("Reset Left Rotation")) {
m_left_controller_rotation_offset_x->value() = 0.0f;
m_left_controller_rotation_offset_y->value() = 0.0f;
m_left_controller_rotation_offset_z->value() = 0.0f;
}
float right_controller_rotation_offset[] = {m_right_controller_rotation_offset_x->value(),
m_right_controller_rotation_offset_y->value(), m_right_controller_rotation_offset_z->value()};
if (ImGui::SliderFloat3("Right Rotation", right_controller_rotation_offset, -180.0f, 180.0f)) {
m_right_controller_rotation_offset_x->value() = right_controller_rotation_offset[0];
m_right_controller_rotation_offset_y->value() = right_controller_rotation_offset[1];
m_right_controller_rotation_offset_z->value() = right_controller_rotation_offset[2];
}
if (ImGui::Button("Reset Right Rotation")) {
m_right_controller_rotation_offset_x->value() = 0.0f;
m_right_controller_rotation_offset_y->value() = 0.0f;
m_right_controller_rotation_offset_z->value() = 0.0f;
}
ImGui::NewLine();
float left_controller_position_offset[] = {m_left_controller_position_offset_x->value(),
m_left_controller_position_offset_y->value(), m_left_controller_position_offset_z->value()};
if (ImGui::SliderFloat3("Left Position", left_controller_position_offset, -1.0f, 1.0f)) {
m_left_controller_position_offset_x->value() = left_controller_position_offset[0];
m_left_controller_position_offset_y->value() = left_controller_position_offset[1];
m_left_controller_position_offset_z->value() = left_controller_position_offset[2];
}
if (ImGui::Button("Reset Left Position")) {
m_left_controller_position_offset_x->value() = 0.0f;
m_left_controller_position_offset_y->value() = 0.0f;
m_left_controller_position_offset_z->value() = 0.0f;
}
float right_controller_position_offset[] = {m_right_controller_position_offset_x->value(),
m_right_controller_position_offset_y->value(), m_right_controller_position_offset_z->value()};
if (ImGui::SliderFloat3("Right Position", right_controller_position_offset, -1.0f, 1.0f)) {
m_right_controller_position_offset_x->value() = right_controller_position_offset[0];
m_right_controller_position_offset_y->value() = right_controller_position_offset[1];
m_right_controller_position_offset_z->value() = right_controller_position_offset[2];
}
if (ImGui::Button("Reset Right Position")) {
m_right_controller_position_offset_x->value() = 0.0f;
m_right_controller_position_offset_y->value() = 0.0f;
m_right_controller_position_offset_z->value() = 0.0f;
}
ImGui::TreePop();
}

ImGui::SetNextItemOpen(true, ImGuiCond_::ImGuiCond_Once);
if (ImGui::TreeNode("Snap Turn")) {
m_snapturn->draw("Enabled");
Expand Down
110 changes: 102 additions & 8 deletions src/mods/VR.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,20 +161,42 @@ class VR : public Mod {
Matrix4x4f get_transform(uint32_t index, bool grip = true) const;
vr::HmdMatrix34_t get_raw_transform(uint32_t index) const;

Vector4f get_grip_position(uint32_t index) const {
return get_position(index, true);
}

Vector4f get_aim_position(uint32_t index) const {
return get_position(index, false);
}

Matrix4x4f get_grip_rotation(uint32_t index) const {
return get_rotation(index, true);
glm::vec3 get_controller_position_with_offset(VRRuntime::Hand hand) {
float x_offset = (hand == VRRuntime::Hand::LEFT) ? get_left_controller_position_offset_x() : get_right_controller_position_offset_x();
float y_offset = (hand == VRRuntime::Hand::LEFT) ? get_left_controller_position_offset_y() : get_right_controller_position_offset_y();
float z_offset = (hand == VRRuntime::Hand::LEFT) ? get_left_controller_position_offset_z() : get_right_controller_position_offset_z();
// if there's no offsets defined, return the original:
auto const position = get_position((hand == VRRuntime::Hand::LEFT) ? get_left_controller_index() : get_right_controller_index(), false);
if (x_offset == 0 && y_offset == 0 && z_offset == 0) {
return position;
} else {
// if we offset the controller by some specified distance we need a frame of reference - what direction is "x"?. If we use
// the HMD direction then turning your head will make the gun move in the world independently of your hand position. If
// we use the controller's direction then the gun will move around when you rotate it (i.e. it will be on the end of an
// invisible 'stick' that's attached to the rotating controller). As there's no other frame of reference that makes any sense here,
// a stick it is. Whether the stick orientation is the offset or raw orientation is another complication
auto const actual_controller_rotation = get_rotation((hand == VRRuntime::Hand::LEFT) ? get_left_controller_index() : get_right_controller_index(), false);
return position - actual_controller_rotation * glm::vec4{-x_offset, -y_offset, z_offset, 0};
}
}

Matrix4x4f get_aim_rotation(uint32_t index) const {
return get_rotation(index, false);
Matrix4x4f get_controller_rotation_with_offset(VRRuntime::Hand hand) {
float x_offset_degrees = (hand == VRRuntime::Hand::LEFT) ? get_left_controller_rotation_offset_x() : get_right_controller_rotation_offset_x();
float y_offset_degrees = (hand == VRRuntime::Hand::LEFT) ? get_left_controller_rotation_offset_y() : get_right_controller_rotation_offset_y();
float z_offset_degrees = (hand == VRRuntime::Hand::LEFT) ? get_left_controller_rotation_offset_z() : get_right_controller_rotation_offset_z();
// if there's no offsets defined, return the original:
auto const rotation = get_rotation((hand == VRRuntime::Hand::LEFT) ? get_left_controller_index() : get_right_controller_index(), false);
if (x_offset_degrees == 0 && y_offset_degrees == 0 && z_offset_degrees == 0) {
return rotation;
} else {
auto const requested_rotation_offset =
utility::math::ue_rotation_matrix(glm::vec3{y_offset_degrees, z_offset_degrees, -x_offset_degrees});
return rotation * requested_rotation_offset;
}
}

Matrix4x4f get_grip_transform(uint32_t hand_index) const;
Expand Down Expand Up @@ -447,7 +469,55 @@ class VR : public Mod {
float get_aim_speed() const {
return m_aim_speed->value();
}

float get_left_controller_rotation_offset_x() const {
return m_left_controller_rotation_offset_x->value();
}

float get_left_controller_rotation_offset_y() const {
return m_left_controller_rotation_offset_y->value();
}

float get_left_controller_rotation_offset_z() const {
return m_left_controller_rotation_offset_z->value();
}

float get_right_controller_rotation_offset_x() const {
return m_right_controller_rotation_offset_x->value();
}

float get_right_controller_rotation_offset_y() const {
return m_right_controller_rotation_offset_y->value();
}

float get_right_controller_rotation_offset_z() const {
return m_right_controller_rotation_offset_z->value();
}

float get_left_controller_position_offset_x() const {
return m_left_controller_position_offset_x->value();
}

float get_left_controller_position_offset_y() const {
return m_left_controller_position_offset_y->value();
}

float get_left_controller_position_offset_z() const {
return m_left_controller_position_offset_z->value();
}

float get_right_controller_position_offset_x() const {
return m_right_controller_position_offset_x->value();
}

float get_right_controller_position_offset_y() const {
return m_right_controller_position_offset_y->value();
}

float get_right_controller_position_offset_z() const {
return m_right_controller_position_offset_z->value();
}

bool is_aim_multiplayer_support_enabled() const {
return m_aim_multiplayer_support->value();
}
Expand Down Expand Up @@ -814,6 +884,18 @@ class VR : public Mod {
const ModSlider::Ptr m_aim_speed{ ModSlider::create(generate_name("AimSpeed"), 0.01f, 25.0f, 15.0f) };
const ModToggle::Ptr m_dpad_shifting{ ModToggle::create(generate_name("DPadShifting"), true) };
const ModCombo::Ptr m_dpad_shifting_method{ ModCombo::create(generate_name("DPadShiftingMethod"), s_dpad_method_names, DPadMethod::RIGHT_TOUCH) };
const ModSlider::Ptr m_left_controller_rotation_offset_x{ModSlider::create(generate_name("LeftControllerRotationOffsetX"), -180.0f, 180.0f, 0.0f)};
const ModSlider::Ptr m_left_controller_rotation_offset_y{ModSlider::create(generate_name("LeftControllerRotationOffsetY"), -180.0f, 180.0f, 0.0f)};
const ModSlider::Ptr m_left_controller_rotation_offset_z{ModSlider::create(generate_name("LeftControllerRotationOffsetZ"), -180.0f, 180.0f, 0.0f)};
const ModSlider::Ptr m_right_controller_rotation_offset_x{ModSlider::create(generate_name("RightControllerRotationOffsetX"), -180.0f, 180.0f, 0.0f)};
const ModSlider::Ptr m_right_controller_rotation_offset_y{ModSlider::create(generate_name("RightControllerRotationOffsetY"), -180.0f, 180.0f, 0.0f)};
const ModSlider::Ptr m_right_controller_rotation_offset_z{ModSlider::create(generate_name("RightControllerRotationOffsetZ"), -180.0f, 180.0f, 0.0f)};
const ModSlider::Ptr m_left_controller_position_offset_x{ModSlider::create(generate_name("LeftControllerPositionOffsetX"), -1.0f, 1.0f, 0.0f)};
const ModSlider::Ptr m_left_controller_position_offset_y{ModSlider::create(generate_name("LeftControllerPositionOffsetY"), -1.0f, 1.0f, 0.0f)};
const ModSlider::Ptr m_left_controller_position_offset_z{ModSlider::create(generate_name("LeftControllerPositionOffsetZ"), -1.0f, 1.0f, 0.0f)};
const ModSlider::Ptr m_right_controller_position_offset_x{ModSlider::create(generate_name("RightControllerPositionOffsetX"), -1.0f, 1.0f, 0.0f)};
const ModSlider::Ptr m_right_controller_position_offset_y{ModSlider::create(generate_name("RightControllerPositionOffsetY"), -1.0f, 1.0f, 0.0f)};
const ModSlider::Ptr m_right_controller_position_offset_z{ModSlider::create(generate_name("RightControllerPositionOffsetZ"), -1.0f, 1.0f, 0.0f)};

struct DPadGestureState {
std::recursive_mutex mtx{};
Expand Down Expand Up @@ -928,6 +1010,18 @@ class VR : public Mod {
*m_aim_modify_player_control_rotation,
*m_aim_multiplayer_support,
*m_aim_speed,
*m_left_controller_rotation_offset_x,
*m_left_controller_rotation_offset_y,
*m_left_controller_rotation_offset_z,
*m_right_controller_rotation_offset_x,
*m_right_controller_rotation_offset_y,
*m_right_controller_rotation_offset_z,
*m_left_controller_position_offset_x,
*m_left_controller_position_offset_y,
*m_left_controller_position_offset_z,
*m_right_controller_position_offset_x,
*m_right_controller_position_offset_y,
*m_right_controller_position_offset_z,
*m_aim_interp,
*m_dpad_shifting,
*m_dpad_shifting_method,
Expand Down
4 changes: 3 additions & 1 deletion src/mods/vr/IXRTrackingSystemHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1900,7 +1900,9 @@ void IXRTrackingSystemHook::update_view_rotation(sdk::UObject* reference_obj, Ro

if (aim_type == VR::AimMethod::RIGHT_CONTROLLER || aim_type == VR::AimMethod::LEFT_CONTROLLER) {
const auto controller_index = aim_type == VR::AimMethod::RIGHT_CONTROLLER ? vr->get_right_controller_index() : vr->get_left_controller_index();
og_controller_rot = glm::quat{vr->get_aim_rotation(controller_index)};
og_controller_rot = aim_type == VR::AimMethod::RIGHT_CONTROLLER ?
glm::quat{ vr->get_controller_rotation_with_offset(VRRuntime::Hand::RIGHT) } :
glm::quat{ vr->get_controller_rotation_with_offset(VRRuntime::Hand::LEFT) }; // glm::quat{vr->get_aim_rotation(controller_index)};
og_controller_pos = glm::vec3{vr->get_aim_position(controller_index)};
right_controller_forward = og_controller_rot * glm::vec3{0.0f, 0.0f, 1.0f};
} else if (aim_type == VR::AimMethod::TWO_HANDED_RIGHT) { // two handed modes are for imitating rifle aiming
Expand Down