Skip to content

Commit

Permalink
(#167) VR: Add camera lerping options
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Aug 9, 2024
1 parent c10654a commit b6b905f
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 1 deletion.
76 changes: 75 additions & 1 deletion src/mods/VR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1396,9 +1396,71 @@ void VR::on_pre_calculate_stereo_view_offset(void* stereo_device, const int32_t
return;
}

const auto now = std::chrono::high_resolution_clock::now();
const auto delta = std::chrono::duration<float, std::chrono::seconds::period>(now - m_last_lerp_update).count();

Rotator<double>* view_rotation_double = (Rotator<double>*)view_rotation;
Vector3d* view_location_double = (Vector3d*)view_location;

glm::vec3 target_rotation = is_double ? glm::vec3{*(glm::vec<3, double>*)view_rotation_double} : *(glm::vec<3, float>*)view_rotation;

const auto should_lerp_pitch = m_lerp_camera_pitch->value();
const auto should_lerp_yaw = m_lerp_camera_yaw->value();
const auto should_lerp_roll = m_lerp_camera_roll->value();

auto lerp_angle = [](auto a, auto b, auto t) {
const auto diff = b - a;
if constexpr (std::is_same_v<decltype(a), double>) {
if (diff > 180.0) {
b -= 360.0;
} else if (diff < -180.0) {
b += 360.0;
}
} else {
if (diff > 180.0f) {
b -= 360.0f;
} else if (diff < -180.0f) {
b += 360.0f;
}
}

return glm::lerp(a, b, t);
};

const auto lerp_t = m_lerp_camera_speed->value() * delta;

if (should_lerp_pitch) {
if (is_double) {
view_rotation_double->pitch = lerp_angle((double)m_camera_lerp.last_rotation.x, (double)target_rotation.x, (double)lerp_t);
} else {
view_rotation->pitch = lerp_angle(m_camera_lerp.last_rotation.x, target_rotation.x, lerp_t);
}
}

if (should_lerp_yaw) {
if (is_double) {
view_rotation_double->yaw = lerp_angle((double)m_camera_lerp.last_rotation.y, (double)target_rotation.y, (double)lerp_t);
} else {
view_rotation->yaw = lerp_angle(m_camera_lerp.last_rotation.y, target_rotation.y, lerp_t);
}
}

if (should_lerp_roll) {
if (is_double) {
view_rotation_double->roll = lerp_angle((double)m_camera_lerp.last_rotation.z, (double)target_rotation.z, (double)lerp_t);
} else {
view_rotation->roll = lerp_angle(m_camera_lerp.last_rotation.z, target_rotation.z, lerp_t);
}
}

if (is_double) {
m_camera_lerp.last_rotation = glm::vec3{ (float)view_rotation_double->pitch, (float)view_rotation_double->yaw, (float)view_rotation_double->roll };
} else {
m_camera_lerp.last_rotation = glm::vec3{ view_rotation->pitch, view_rotation->yaw, view_rotation->roll };
}

m_last_lerp_update = std::chrono::high_resolution_clock::now();

if (m_camera_freeze.position_wants_freeze) {
if (is_double) {
m_camera_freeze.position = glm::vec3{ (float)view_location_double->x, (float)view_location_double->y, (float)view_location_double->z };
Expand Down Expand Up @@ -2439,7 +2501,7 @@ void VR::on_draw_sidebar_entry(std::string_view name) {

if (selected_page == PAGE_CAMERA) {
ImGui::SetNextItemOpen(true, ImGuiCond_::ImGuiCond_Once);
if (ImGui::TreeNode("Camera")) {
if (ImGui::TreeNode("Camera Freeze")) {
float camera_offset[] = {m_camera_forward_offset->value(), m_camera_right_offset->value(), m_camera_up_offset->value()};
if (ImGui::SliderFloat3("Camera Offset", camera_offset, -4000.0f, 4000.0f)) {
m_camera_forward_offset->value() = camera_offset[0];
Expand Down Expand Up @@ -2483,6 +2545,18 @@ void VR::on_draw_sidebar_entry(std::string_view name) {
ImGui::TreePop();
}

ImGui::SetNextItemOpen(true, ImGuiCond_::ImGuiCond_Once);
if (ImGui::TreeNode("Camera Lerp")) {
m_lerp_camera_pitch->draw("Lerp Pitch");
ImGui::SameLine();
m_lerp_camera_yaw->draw("Lerp Yaw");
ImGui::SameLine();
m_lerp_camera_roll->draw("Lerp Roll");
m_lerp_camera_speed->draw("Lerp Speed");

ImGui::TreePop();
}

ImGui::SetNextItemOpen(true, ImGuiCond_::ImGuiCond_Once);
if (ImGui::TreeNode("Decoupled Pitch")) {
m_decoupled_pitch->draw("Enabled");
Expand Down
16 changes: 16 additions & 0 deletions src/mods/VR.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,13 @@ class VR : public Mod {

const ModString::Ptr m_requested_runtime_name{ ModString::create("Frontend_RequestedRuntime", "unset") };

const ModToggle::Ptr m_lerp_camera_pitch{ ModToggle::create(generate_name("LerpCameraPitch"), false) };
const ModToggle::Ptr m_lerp_camera_yaw{ ModToggle::create(generate_name("LerpCameraYaw"), false) };
const ModToggle::Ptr m_lerp_camera_roll{ ModToggle::create(generate_name("LerpCameraRoll"), false) };
const ModSlider::Ptr m_lerp_camera_speed{ ModSlider::create(generate_name("LerpCameraSpeed"), 0.01f, 10.0f, 1.0f) };

std::chrono::high_resolution_clock::time_point m_last_lerp_update{};

struct DecoupledPitchData {
mutable std::shared_mutex mtx{};
glm::quat pre_flattened_rotation{};
Expand All @@ -964,6 +971,11 @@ class VR : public Mod {
bool rotation_wants_freeze{false};
} m_camera_freeze{};

struct CameraLerp {
glm::vec3 last_position{};
glm::vec3 last_rotation{};
} m_camera_lerp{};

struct CameraData {
glm::vec3 offset{};
float world_scale{1.0f};
Expand Down Expand Up @@ -1040,6 +1052,10 @@ class VR : public Mod {
*m_show_fps,
*m_show_statistics,
*m_controllers_allowed,
*m_lerp_camera_pitch,
*m_lerp_camera_yaw,
*m_lerp_camera_roll,
*m_lerp_camera_speed,
};

add_components_vr();
Expand Down
6 changes: 6 additions & 0 deletions src/mods/vr/FFakeStereoRenderingHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4126,6 +4126,12 @@ __forceinline void FFakeStereoRenderingHook::calculate_stereo_view_offset(
}

if (true_index == 0 && !is_full_pass) {
if (has_double_precision) {
g_hook->m_last_pre_rotation_double = *rot_d;
} else {
g_hook->m_last_pre_rotation = *view_rotation;
}

//vr->wait_for_present();

if (!g_hook->m_has_view_extension_hook && !g_hook->m_has_game_viewport_client_draw_hook) {
Expand Down
11 changes: 11 additions & 0 deletions src/mods/vr/FFakeStereoRenderingHook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,14 @@ class FFakeStereoRenderingHook : public ModComponent {
return m_ignore_next_viewport_draw;
}

auto& get_last_pre_rotation() {
return m_last_pre_rotation;
}

auto& get_last_pre_rotation_double() {
return m_last_pre_rotation_double;
}

// Do not call these directly
static void setup_viewpoint(ISceneViewExtension* extension, void* player_controller, void* view_info);
static void localplayer_setup_viewpoint(void* localplayer, void* view_info, void* pass);
Expand Down Expand Up @@ -409,6 +417,9 @@ class FFakeStereoRenderingHook : public ModComponent {
Rotator<float> m_last_afr_rotation{};
Rotator<double> m_last_afr_rotation_double{};

Rotator<float> m_last_pre_rotation{};
Rotator<double> m_last_pre_rotation_double{};

std::atomic<Rotator<float>> m_last_rotation{};
std::atomic<Rotator<double>> m_last_rotation_double{};

Expand Down

0 comments on commit b6b905f

Please sign in to comment.