Skip to content

Commit

Permalink
Add universal snapturn option; add get/set control rotation to contro…
Browse files Browse the repository at this point in the history
…ller class
  • Loading branch information
narknon committed Sep 12, 2023
1 parent 66bf4a1 commit d73332a
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 26 deletions.
26 changes: 26 additions & 0 deletions shared/sdk/AActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ glm::vec3 AActor::get_actor_location() {

return *(glm::vec<3, double>*)params.data();
}

bool AActor::set_actor_rotation(const glm::vec3& rotation, bool teleport) {
static const auto func = static_class()->find_function(L"K2_SetActorRotation");
const auto frotator = sdk::ScriptRotator::static_struct();
Expand Down Expand Up @@ -98,5 +99,30 @@ bool AActor::set_actor_rotation(const glm::vec3& rotation, bool teleport) {
this->process_event(func, params.data());

return ret;
}

glm::vec3 AActor::get_actor_rotation() {
static const auto func = static_class()->find_function(L"K2_GetActorRotation");
const auto frotator = sdk::ScriptVector::static_struct();

const auto is_ue5 = frotator->get_struct_size() == sizeof(glm::vec<3, double>);

std::vector<uint8_t> params{};

// add a vec3
if (!is_ue5) {
params.insert(params.end(), sizeof(glm::vec3), 0);
} else {
params.insert(params.end(), sizeof(glm::vec<3, double>), 0);
}

this->process_event(func, params.data());

if (!is_ue5) {
return *(glm::vec3*)params.data();
}

return *(glm::vec<3, double>*)params.data();
};

}
1 change: 1 addition & 0 deletions shared/sdk/AActor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class AActor : public UObject {
glm::vec3 get_actor_location();

bool set_actor_rotation(const glm::vec3& rotation, bool teleport);
glm::vec3 get_actor_rotation();

protected:
};
Expand Down
55 changes: 54 additions & 1 deletion shared/sdk/APlayerController.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,60 @@
#include <vector>
#include "UObjectArray.hpp"
#include "ScriptVector.hpp"
#include "ScriptRotator.hpp"

#include "APlayerController.hpp"

namespace sdk {
UClass* AController::static_class() {
return sdk::find_uobject<UClass>(L"Class /Script/Engine.Controller");
}

void AController::set_control_rotation(const glm::vec3& newrotation) {
static const auto func = static_class()->find_function(L"SetControlRotation");
const auto frotator = sdk::ScriptRotator::static_struct();

const auto is_ue5 = frotator->get_struct_size() == sizeof(glm::vec<3, double>);

// Need to dynamically allocate the params because of unknown FRotator size
std::vector<uint8_t> params{};
// add a vec3
if (!is_ue5) {
params.insert(params.end(), (uint8_t*)&newrotation, (uint8_t*)&newrotation + sizeof(glm::vec3));
} else {
glm::vec<3, double> rot = newrotation;
params.insert(params.end(), (uint8_t*)&rot, (uint8_t*)&rot + sizeof(glm::vec<3, double>));
}

this->process_event(func, params.data());
}

glm::vec3 AController::get_control_rotation() {
static const auto func = static_class()->find_function(L"GetControlRotation");
const auto frotator = sdk::ScriptVector::static_struct();

const auto is_ue5 = frotator->get_struct_size() == sizeof(glm::vec<3, double>);
std::vector<uint8_t> params{};

// add a vec3
if (!is_ue5) {
params.insert(params.end(), sizeof(glm::vec3), 0);
} else {
params.insert(params.end(), sizeof(glm::vec<3, double>), 0);
}
this->process_event(func, params.data());

if (!is_ue5) {
return *(glm::vec3*)params.data();
}
return *(glm::vec<3, double>*)params.data();
}

UClass* APlayerController::static_class() {
return sdk::find_uobject<UClass>(L"Class /Script/Engine.PlayerController");
}

APawn* APlayerController::get_acknowledged_pawn() const {
return get_property<APawn*>(L"AcknowledgedPawn");
}
}
}
18 changes: 16 additions & 2 deletions shared/sdk/APlayerController.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,27 @@

#include "UObject.hpp"

#include <glm/vec3.hpp>

namespace sdk {
class APawn;

class APlayerController : public UObject {
class AController : public UObject {
public:
static UClass* static_class();

void set_control_rotation(const glm::vec3& newrotation);
glm::vec3 get_control_rotation();

protected:
};

class APlayerController : public AController {
public:
static UClass* static_class();

APawn* get_acknowledged_pawn() const;

protected:
};
}
}
114 changes: 91 additions & 23 deletions src/mods/vr/FFakeStereoRenderingHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4047,36 +4047,104 @@ __forceinline void FFakeStereoRenderingHook::calculate_stereo_view_offset(
}
}

// Roomscale movement
// only do it on the right eye pass
// Snapturn frame check
// we check if this is enabled and if the required input is active here
// so that the variables shared between it and roomscale do not have to be found twice per frame
bool snapturn_on_frame{false};
if (vr->is_snapturn_enabled()) {
const auto left_thumbrest_handle = vr->get_action_handle(VR::s_action_thumbrest_touch_left);
const auto right_thumbrest_handle = vr->get_action_handle(VR::s_action_thumbrest_touch_right);

const auto dpad_method = vr->get_dpad_method();
const auto snapturn_deadzone = vr->get_snapturn_js_deadzone();
if (!m_was_snapturn_run_on_input) {
if (dpad_method == VR::RIGHT_TOUCH && vr->is_action_active(left_thumbrest_handle)) {
if (abs(vr->get_right_stick_axis().x) >= snapturn_deadzone) {
snapturn_on_frame = true;
m_was_snapturn_run_on_input = true;
}
}
else if (dpad_method == VR::LEFT_TOUCH && vr->is_action_active(right_thumbrest_handle)) {
if (abs(vr->get_left_stick_axis().x) >= snapturn_deadzone) {
snapturn_on_frame = true;
m_was_snapturn_run_on_input = true;
}
}
}
else {
if (dpad_method == VR::RIGHT_TOUCH) {
if (abs(vr->get_right_stick_axis().x) < snapturn_deadzone) {
m_was_snapturn_run_on_input = false;
}
}
else if (dpad_method == VR::LEFT_TOUCH) {
if (abs(vr->get_left_stick_axis().x) < snapturn_deadzone) {
m_was_snapturn_run_on_input = false;
}
}
}
}



// Roomscale frame check
// only do roomscale movement on the right eye pass
// if we did it on the left, there would be eye desyncs when the right eye is rendered
if (true_index == 1 && vr->is_roomscale_enabled()) {
const auto world = sdk::UEngine::get()->get_world();
// we check this here to avoid duplicate code later
bool roomscale_movement_on_frame = true_index == 1 && vr->is_roomscale_enabled();


// Roomscale and snap turn movement
// we handle both of these within one if statement to avoid duplicative searches
// TODO: consider if commonly used variables such as player controller should get cached globally if any more universal systems using these are added, to avoid this code growing unwieldy
//
if (roomscale_movement_on_frame || snapturn_on_frame) {
const auto world = sdk::UEngine::get()->get_world();
if (const auto controller = sdk::UGameplayStatics::get()->get_player_controller(world, 0); controller != nullptr) {
if (const auto pawn = controller->get_acknowledged_pawn(); pawn != nullptr) {
const auto pawn_pos = pawn->get_actor_location();
const auto new_pos = pawn_pos - head_offset_flat;

pawn->set_actor_location(new_pos, false, false);

// Recenter the standing origin
auto current_standing_origin = vr->get_standing_origin();
const auto hmd_pos = vr->get_position(0);
// dont touch the Y axis
current_standing_origin.x = hmd_pos.x;
current_standing_origin.z = hmd_pos.z;
vr->set_standing_origin(current_standing_origin);
if (roomscale_movement_on_frame) {
const auto pawn_pos = pawn->get_actor_location();
const auto new_pos = pawn_pos - head_offset_flat;

pawn->set_actor_location(new_pos, false, false);

// Recenter the standing origin
auto current_standing_origin = vr->get_standing_origin();
const auto hmd_pos = vr->get_position(0);
// dont touch the Y axis
current_standing_origin.x = hmd_pos.x;
current_standing_origin.z = hmd_pos.z;
vr->set_standing_origin(current_standing_origin);

// testing
if (vr->is_roomscale_using_actor_rotation()) {
if (!has_double_precision) {
pawn->set_actor_rotation(*(glm::vec3*)view_rotation, false);
} else {
pawn->set_actor_rotation(glm::vec3{rot_d->pitch, rot_d->yaw, rot_d->roll}, false);
// testing
if (vr->is_roomscale_using_actor_rotation()) {
if (!has_double_precision) {
pawn->set_actor_rotation(*(glm::vec3*)view_rotation, false);
} else {
pawn->set_actor_rotation(glm::vec3{rot_d->pitch, rot_d->yaw, rot_d->roll}, false);
}

vr->recenter_view();
}
}

vr->recenter_view();
if (snapturn_on_frame) {
auto controller_rot = controller->get_control_rotation();
const auto dpad_method = vr->get_dpad_method();

auto turn_degrees = vr->get_snapturn_degrees();
if (dpad_method == VR::RIGHT_TOUCH) {
if (vr->get_right_stick_axis().x < 0) {
turn_degrees = -turn_degrees;
}
}
else if (dpad_method == VR::LEFT_TOUCH) {
if (vr->get_left_stick_axis().x < 0) {
turn_degrees = -turn_degrees;
}
}
controller_rot.y += turn_degrees;
controller->set_control_rotation(controller_rot);
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/mods/vr/FFakeStereoRenderingHook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ class FFakeStereoRenderingHook : public ModComponent {

std::chrono::time_point<std::chrono::high_resolution_clock> m_analyze_view_extensions_start_time{};

// UE Framework Globals
static inline bool m_was_snapturn_run_on_input{false};

/*FFakeStereoRendering m_stereo_recreation {
90.0f,
(int32_t)1920,
Expand Down

0 comments on commit d73332a

Please sign in to comment.