Merge pull request #8767 from iwubcode/freelook-camera-type

Expand freelook camera with control options
This commit is contained in:
Pierre Bourdon 2020-05-17 17:33:04 +02:00 committed by GitHub
commit cea779cc84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 410 additions and 49 deletions

View File

@ -41,6 +41,8 @@ const Info<bool> GFX_DUMP_EFB_TARGET{{System::GFX, "Settings", "DumpEFBTarget"},
const Info<bool> GFX_DUMP_XFB_TARGET{{System::GFX, "Settings", "DumpXFBTarget"}, false}; const Info<bool> GFX_DUMP_XFB_TARGET{{System::GFX, "Settings", "DumpXFBTarget"}, false};
const Info<bool> GFX_DUMP_FRAMES_AS_IMAGES{{System::GFX, "Settings", "DumpFramesAsImages"}, false}; const Info<bool> GFX_DUMP_FRAMES_AS_IMAGES{{System::GFX, "Settings", "DumpFramesAsImages"}, false};
const Info<bool> GFX_FREE_LOOK{{System::GFX, "Settings", "FreeLook"}, false}; const Info<bool> GFX_FREE_LOOK{{System::GFX, "Settings", "FreeLook"}, false};
const Info<FreelookControlType> GFX_FREE_LOOK_CONTROL_TYPE{
{System::GFX, "Settings", "FreeLookControlType"}, FreelookControlType::SixAxis};
const Info<bool> GFX_USE_FFV1{{System::GFX, "Settings", "UseFFV1"}, false}; const Info<bool> GFX_USE_FFV1{{System::GFX, "Settings", "UseFFV1"}, false};
const Info<std::string> GFX_DUMP_FORMAT{{System::GFX, "Settings", "DumpFormat"}, "avi"}; const Info<std::string> GFX_DUMP_FORMAT{{System::GFX, "Settings", "DumpFormat"}, "avi"};
const Info<std::string> GFX_DUMP_CODEC{{System::GFX, "Settings", "DumpCodec"}, ""}; const Info<std::string> GFX_DUMP_CODEC{{System::GFX, "Settings", "DumpCodec"}, ""};

View File

@ -11,6 +11,7 @@
enum class AspectMode : int; enum class AspectMode : int;
enum class ShaderCompilationMode : int; enum class ShaderCompilationMode : int;
enum class StereoMode : int; enum class StereoMode : int;
enum class FreelookControlType : int;
namespace Config namespace Config
{ {
@ -41,6 +42,7 @@ extern const Info<bool> GFX_DUMP_EFB_TARGET;
extern const Info<bool> GFX_DUMP_XFB_TARGET; extern const Info<bool> GFX_DUMP_XFB_TARGET;
extern const Info<bool> GFX_DUMP_FRAMES_AS_IMAGES; extern const Info<bool> GFX_DUMP_FRAMES_AS_IMAGES;
extern const Info<bool> GFX_FREE_LOOK; extern const Info<bool> GFX_FREE_LOOK;
extern const Info<FreelookControlType> GFX_FREE_LOOK_CONTROL_TYPE;
extern const Info<bool> GFX_USE_FFV1; extern const Info<bool> GFX_USE_FFV1;
extern const Info<std::string> GFX_DUMP_FORMAT; extern const Info<std::string> GFX_DUMP_FORMAT;
extern const Info<std::string> GFX_DUMP_CODEC; extern const Info<std::string> GFX_DUMP_CODEC;

View File

@ -28,7 +28,7 @@ bool IsSettingSaveable(const Config::Location& config_location)
return true; return true;
} }
static constexpr std::array<const Config::Location*, 96> s_setting_saveable = { static constexpr std::array<const Config::Location*, 97> s_setting_saveable = {
// Main.Core // Main.Core
&Config::MAIN_DEFAULT_ISO.location, &Config::MAIN_DEFAULT_ISO.location,
@ -73,6 +73,7 @@ bool IsSettingSaveable(const Config::Location& config_location)
&Config::GFX_DUMP_EFB_TARGET.location, &Config::GFX_DUMP_EFB_TARGET.location,
&Config::GFX_DUMP_FRAMES_AS_IMAGES.location, &Config::GFX_DUMP_FRAMES_AS_IMAGES.location,
&Config::GFX_FREE_LOOK.location, &Config::GFX_FREE_LOOK.location,
&Config::GFX_FREE_LOOK_CONTROL_TYPE.location,
&Config::GFX_USE_FFV1.location, &Config::GFX_USE_FFV1.location,
&Config::GFX_DUMP_FORMAT.location, &Config::GFX_DUMP_FORMAT.location,
&Config::GFX_DUMP_CODEC.location, &Config::GFX_DUMP_CODEC.location,

View File

@ -72,16 +72,27 @@ void AdvancedWidget::CreateWidgets()
m_dump_efb_target = new GraphicsBool(tr("Dump EFB Target"), Config::GFX_DUMP_EFB_TARGET); m_dump_efb_target = new GraphicsBool(tr("Dump EFB Target"), Config::GFX_DUMP_EFB_TARGET);
m_disable_vram_copies = m_disable_vram_copies =
new GraphicsBool(tr("Disable EFB VRAM Copies"), Config::GFX_HACK_DISABLE_COPY_TO_VRAM); new GraphicsBool(tr("Disable EFB VRAM Copies"), Config::GFX_HACK_DISABLE_COPY_TO_VRAM);
m_enable_freelook = new GraphicsBool(tr("Free Look"), Config::GFX_FREE_LOOK);
utility_layout->addWidget(m_load_custom_textures, 0, 0); utility_layout->addWidget(m_load_custom_textures, 0, 0);
utility_layout->addWidget(m_prefetch_custom_textures, 0, 1); utility_layout->addWidget(m_prefetch_custom_textures, 0, 1);
utility_layout->addWidget(m_enable_freelook, 1, 0); utility_layout->addWidget(m_disable_vram_copies, 1, 0);
utility_layout->addWidget(m_disable_vram_copies, 1, 1); utility_layout->addWidget(m_dump_textures, 1, 1);
utility_layout->addWidget(m_dump_textures, 2, 0); utility_layout->addWidget(m_dump_efb_target, 2, 0);
utility_layout->addWidget(m_dump_efb_target, 2, 1);
// Freelook
auto* freelook_box = new QGroupBox(tr("Free Look"));
auto* freelook_layout = new QGridLayout();
freelook_box->setLayout(freelook_layout);
m_enable_freelook = new GraphicsBool(tr("Enable"), Config::GFX_FREE_LOOK);
m_freelook_control_type = new GraphicsChoice({tr("Six Axis"), tr("First Person"), tr("Orbital")},
Config::GFX_FREE_LOOK_CONTROL_TYPE);
freelook_layout->addWidget(m_enable_freelook, 0, 0);
freelook_layout->addWidget(new QLabel(tr("Control Type:")), 1, 0);
freelook_layout->addWidget(m_freelook_control_type, 1, 1);
// Frame dumping // Frame dumping
auto* dump_box = new QGroupBox(tr("Frame Dumping")); auto* dump_box = new QGroupBox(tr("Frame Dumping"));
@ -132,6 +143,7 @@ void AdvancedWidget::CreateWidgets()
main_layout->addWidget(debugging_box); main_layout->addWidget(debugging_box);
main_layout->addWidget(utility_box); main_layout->addWidget(utility_box);
main_layout->addWidget(freelook_box);
main_layout->addWidget(dump_box); main_layout->addWidget(dump_box);
main_layout->addWidget(misc_box); main_layout->addWidget(misc_box);
main_layout->addWidget(experimental_box); main_layout->addWidget(experimental_box);
@ -145,6 +157,7 @@ void AdvancedWidget::ConnectWidgets()
connect(m_load_custom_textures, &QCheckBox::toggled, this, &AdvancedWidget::SaveSettings); connect(m_load_custom_textures, &QCheckBox::toggled, this, &AdvancedWidget::SaveSettings);
connect(m_dump_use_ffv1, &QCheckBox::toggled, this, &AdvancedWidget::SaveSettings); connect(m_dump_use_ffv1, &QCheckBox::toggled, this, &AdvancedWidget::SaveSettings);
connect(m_enable_prog_scan, &QCheckBox::toggled, this, &AdvancedWidget::SaveSettings); connect(m_enable_prog_scan, &QCheckBox::toggled, this, &AdvancedWidget::SaveSettings);
connect(m_enable_freelook, &QCheckBox::toggled, this, &AdvancedWidget::SaveSettings);
} }
void AdvancedWidget::LoadSettings() void AdvancedWidget::LoadSettings()
@ -153,6 +166,8 @@ void AdvancedWidget::LoadSettings()
m_dump_bitrate->setEnabled(!Config::Get(Config::GFX_USE_FFV1)); m_dump_bitrate->setEnabled(!Config::Get(Config::GFX_USE_FFV1));
m_enable_prog_scan->setChecked(Config::Get(Config::SYSCONF_PROGRESSIVE_SCAN)); m_enable_prog_scan->setChecked(Config::Get(Config::SYSCONF_PROGRESSIVE_SCAN));
m_freelook_control_type->setEnabled(Config::Get(Config::GFX_FREE_LOOK));
} }
void AdvancedWidget::SaveSettings() void AdvancedWidget::SaveSettings()
@ -161,6 +176,8 @@ void AdvancedWidget::SaveSettings()
m_dump_bitrate->setEnabled(!Config::Get(Config::GFX_USE_FFV1)); m_dump_bitrate->setEnabled(!Config::Get(Config::GFX_USE_FFV1));
Config::SetBase(Config::SYSCONF_PROGRESSIVE_SCAN, m_enable_prog_scan->isChecked()); Config::SetBase(Config::SYSCONF_PROGRESSIVE_SCAN, m_enable_prog_scan->isChecked());
m_freelook_control_type->setEnabled(Config::Get(Config::GFX_FREE_LOOK));
} }
void AdvancedWidget::OnBackendChanged() void AdvancedWidget::OnBackendChanged()
@ -213,6 +230,14 @@ void AdvancedWidget::AddDescriptions()
"to pan or middle button to roll.\n\nUse the WASD keys while holding SHIFT to move the " "to pan or middle button to roll.\n\nUse the WASD keys while holding SHIFT to move the "
"camera. Press SHIFT+2 to increase speed or SHIFT+1 to decrease speed. Press SHIFT+R " "camera. Press SHIFT+2 to increase speed or SHIFT+1 to decrease speed. Press SHIFT+R "
"to reset the camera or SHIFT+F to reset the speed.\n\nIf unsure, leave this unchecked. "); "to reset the camera or SHIFT+F to reset the speed.\n\nIf unsure, leave this unchecked. ");
static const char TR_FREE_LOOK_CONTROL_TYPE_DESCRIPTION[] = QT_TR_NOOP(
"Changes the in-game camera type during freelook.\n\n Six Axis: Offers full camera control "
"on all axis, akin to moving a spacecraft in zero gravity. This is the most powerful "
"freelook option but is the most challenging to use.\n"
"First Person: cControls the free camera similarly to a first person video game. The camera "
"can rotate and travel, but roll is impossible. Easy to use, but limiting.\nOrbital: Rotates "
"the free camera around the original camera. Has no lateral movement, only rotation and you "
"may zoom up to the camera's origin point.");
static const char TR_CROPPING_DESCRIPTION[] = static const char TR_CROPPING_DESCRIPTION[] =
QT_TR_NOOP("Crops the picture from its native aspect ratio to 4:3 or " QT_TR_NOOP("Crops the picture from its native aspect ratio to 4:3 or "
"16:9.\n\nIf unsure, leave this unchecked."); "16:9.\n\nIf unsure, leave this unchecked.");
@ -254,6 +279,7 @@ void AdvancedWidget::AddDescriptions()
AddDescription(m_enable_cropping, TR_CROPPING_DESCRIPTION); AddDescription(m_enable_cropping, TR_CROPPING_DESCRIPTION);
AddDescription(m_enable_prog_scan, TR_PROGRESSIVE_SCAN_DESCRIPTION); AddDescription(m_enable_prog_scan, TR_PROGRESSIVE_SCAN_DESCRIPTION);
AddDescription(m_enable_freelook, TR_FREE_LOOK_DESCRIPTION); AddDescription(m_enable_freelook, TR_FREE_LOOK_DESCRIPTION);
AddDescription(m_freelook_control_type, TR_FREE_LOOK_CONTROL_TYPE_DESCRIPTION);
AddDescription(m_backend_multithreading, TR_BACKEND_MULTITHREADING_DESCRIPTION); AddDescription(m_backend_multithreading, TR_BACKEND_MULTITHREADING_DESCRIPTION);
#ifdef _WIN32 #ifdef _WIN32
AddDescription(m_borderless_fullscreen, TR_BORDERLESS_FULLSCREEN_DESCRIPTION); AddDescription(m_borderless_fullscreen, TR_BORDERLESS_FULLSCREEN_DESCRIPTION);

View File

@ -8,6 +8,7 @@
class GraphicsWindow; class GraphicsWindow;
class QCheckBox; class QCheckBox;
class QComboBox;
class QSpinBox; class QSpinBox;
class AdvancedWidget final : public GraphicsWidget class AdvancedWidget final : public GraphicsWidget
@ -39,6 +40,7 @@ private:
QCheckBox* m_disable_vram_copies; QCheckBox* m_disable_vram_copies;
QCheckBox* m_load_custom_textures; QCheckBox* m_load_custom_textures;
QCheckBox* m_enable_freelook; QCheckBox* m_enable_freelook;
QComboBox* m_freelook_control_type;
// Frame dumping // Frame dumping
QCheckBox* m_dump_use_ffv1; QCheckBox* m_dump_use_ffv1;

View File

@ -30,6 +30,7 @@
#include "InputCommon/ControlReference/ControlReference.h" #include "InputCommon/ControlReference/ControlReference.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h" #include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "VideoCommon/FreeLookCamera.h"
#include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/RenderBase.h" #include "VideoCommon/RenderBase.h"
#include "VideoCommon/VertexShaderManager.h" #include "VideoCommon/VertexShaderManager.h"
@ -545,25 +546,25 @@ void HotkeyScheduler::Run()
fl_speed = 1.0; fl_speed = 1.0;
if (IsHotkey(HK_FREELOOK_UP, true)) if (IsHotkey(HK_FREELOOK_UP, true))
VertexShaderManager::TranslateView(0.0, 0.0, -fl_speed); g_freelook_camera.MoveVertical(-fl_speed);
if (IsHotkey(HK_FREELOOK_DOWN, true)) if (IsHotkey(HK_FREELOOK_DOWN, true))
VertexShaderManager::TranslateView(0.0, 0.0, fl_speed); g_freelook_camera.MoveVertical(fl_speed);
if (IsHotkey(HK_FREELOOK_LEFT, true)) if (IsHotkey(HK_FREELOOK_LEFT, true))
VertexShaderManager::TranslateView(fl_speed, 0.0); g_freelook_camera.MoveHorizontal(fl_speed);
if (IsHotkey(HK_FREELOOK_RIGHT, true)) if (IsHotkey(HK_FREELOOK_RIGHT, true))
VertexShaderManager::TranslateView(-fl_speed, 0.0); g_freelook_camera.MoveHorizontal(-fl_speed);
if (IsHotkey(HK_FREELOOK_ZOOM_IN, true)) if (IsHotkey(HK_FREELOOK_ZOOM_IN, true))
VertexShaderManager::TranslateView(0.0, fl_speed); g_freelook_camera.Zoom(fl_speed);
if (IsHotkey(HK_FREELOOK_ZOOM_OUT, true)) if (IsHotkey(HK_FREELOOK_ZOOM_OUT, true))
VertexShaderManager::TranslateView(0.0, -fl_speed); g_freelook_camera.Zoom(-fl_speed);
if (IsHotkey(HK_FREELOOK_RESET, true)) if (IsHotkey(HK_FREELOOK_RESET, true))
VertexShaderManager::ResetView(); g_freelook_camera.Reset();
// Savestates // Savestates
for (u32 i = 0; i < State::NUM_STATES; i++) for (u32 i = 0; i < State::NUM_STATES; i++)

View File

@ -32,6 +32,7 @@
#include "DolphinQt/Resources.h" #include "DolphinQt/Resources.h"
#include "DolphinQt/Settings.h" #include "DolphinQt/Settings.h"
#include "VideoCommon/FreeLookCamera.h"
#include "VideoCommon/RenderBase.h" #include "VideoCommon/RenderBase.h"
#include "VideoCommon/VertexShaderManager.h" #include "VideoCommon/VertexShaderManager.h"
#include "VideoCommon/VideoConfig.h" #include "VideoCommon/VideoConfig.h"
@ -238,12 +239,12 @@ void RenderWidget::OnFreeLookMouseMove(QMouseEvent* event)
if (event->buttons() & Qt::RightButton) if (event->buttons() & Qt::RightButton)
{ {
// Camera Pitch and Yaw: // Camera Pitch and Yaw:
VertexShaderManager::RotateView(mouse_move.y() / 200.f, mouse_move.x() / 200.f, 0.f); g_freelook_camera.Rotate(Common::Vec3{mouse_move.y() / 200.f, mouse_move.x() / 200.f, 0.f});
} }
else if (event->buttons() & Qt::MidButton) else if (event->buttons() & Qt::MidButton)
{ {
// Camera Roll: // Camera Roll:
VertexShaderManager::RotateView(0.f, 0.f, mouse_move.x() / 200.f); g_freelook_camera.Rotate({0.f, 0.f, mouse_move.x() / 200.f});
} }
} }

View File

@ -33,6 +33,8 @@ add_library(videocommon
FramebufferManager.h FramebufferManager.h
FramebufferShaderGen.cpp FramebufferShaderGen.cpp
FramebufferShaderGen.h FramebufferShaderGen.h
FreeLookCamera.cpp
FreeLookCamera.h
GeometryShaderGen.cpp GeometryShaderGen.cpp
GeometryShaderGen.h GeometryShaderGen.h
GeometryShaderManager.cpp GeometryShaderManager.cpp

View File

@ -0,0 +1,272 @@
// Copyright 2020 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include "VideoCommon/FreeLookCamera.h"
#include <algorithm>
#include <math.h>
#include <fmt/format.h>
#include "Common/MathUtil.h"
#include "Common/ChunkFile.h"
#include "Core/Config/GraphicsSettings.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "VideoCommon/VideoCommon.h"
#include "VideoCommon/VideoConfig.h"
FreeLookCamera g_freelook_camera;
namespace
{
std::string to_string(FreelookControlType type)
{
switch (type)
{
case FreelookControlType::SixAxis:
return "Six Axis";
case FreelookControlType::FPS:
return "First Person";
case FreelookControlType::Orbital:
return "Orbital";
}
return "";
}
class SixAxisController : public CameraController
{
public:
SixAxisController() = default;
Common::Matrix44 GetView() override { return m_mat; }
void MoveVertical(float amt) override
{
m_mat = Common::Matrix44::Translate(Common::Vec3{0, amt, 0}) * m_mat;
}
void MoveHorizontal(float amt) override
{
m_mat = Common::Matrix44::Translate(Common::Vec3{amt, 0, 0}) * m_mat;
}
void Zoom(float amt) override
{
m_mat = Common::Matrix44::Translate(Common::Vec3{0, 0, amt}) * m_mat;
}
void Rotate(const Common::Vec3& amt) override
{
using Common::Matrix33;
m_mat = Common::Matrix44::FromMatrix33(Matrix33::RotateX(amt.x) * Matrix33::RotateY(amt.y) *
Matrix33::RotateZ(amt.z)) *
m_mat;
}
void Reset() override { m_mat = Common::Matrix44::Identity(); }
void DoState(PointerWrap& p) { p.Do(m_mat); }
private:
Common::Matrix44 m_mat = Common::Matrix44::Identity();
};
constexpr double HalfPI = MathUtil::PI / 2;
class FPSController : public CameraController
{
public:
Common::Matrix44 GetView() override
{
return m_rotate_mat * Common::Matrix44::Translate(m_position);
}
void MoveVertical(float amt) override
{
Common::Vec3 up{m_rotate_mat.data[4], m_rotate_mat.data[5], m_rotate_mat.data[6]};
m_position += up * amt;
}
void MoveHorizontal(float amt) override
{
Common::Vec3 right{m_rotate_mat.data[0], m_rotate_mat.data[1], m_rotate_mat.data[2]};
m_position += right * amt;
}
void Zoom(float amt) override
{
Common::Vec3 forward{m_rotate_mat.data[8], m_rotate_mat.data[9], m_rotate_mat.data[10]};
m_position += forward * amt;
}
void Rotate(const Common::Vec3& amt) override
{
m_rotation += amt;
using Common::Matrix33;
using Common::Matrix44;
m_rotate_mat =
Matrix44::FromMatrix33(Matrix33::RotateX(m_rotation.x) * Matrix33::RotateY(m_rotation.y));
}
void Reset() override
{
m_position = Common::Vec3{};
m_rotation = Common::Vec3{};
m_rotate_mat = Common::Matrix44::Identity();
}
void DoState(PointerWrap& p)
{
p.Do(m_rotation);
p.Do(m_rotate_mat);
p.Do(m_position);
}
private:
Common::Vec3 m_rotation = Common::Vec3{};
Common::Matrix44 m_rotate_mat = Common::Matrix44::Identity();
Common::Vec3 m_position = Common::Vec3{};
};
class OrbitalController : public CameraController
{
public:
Common::Matrix44 GetView() override
{
Common::Matrix44 result = Common::Matrix44::Identity();
result *= Common::Matrix44::Translate(Common::Vec3{0, 0, -m_distance});
result *= Common::Matrix44::FromMatrix33(Common::Matrix33::RotateX(m_rotation.x));
result *= Common::Matrix44::FromMatrix33(Common::Matrix33::RotateY(m_rotation.y));
return result;
}
void MoveVertical(float) override {}
void MoveHorizontal(float) override {}
void Zoom(float amt) override
{
m_distance += -1 * amt;
m_distance = std::clamp(m_distance, 0.0f, m_distance);
}
void Rotate(const Common::Vec3& amt) override { m_rotation += amt; }
void Reset() override
{
m_rotation = Common::Vec3{};
m_distance = 0;
}
void DoState(PointerWrap& p)
{
p.Do(m_rotation);
p.Do(m_distance);
}
private:
float m_distance = 0;
Common::Vec3 m_rotation = Common::Vec3{};
};
} // namespace
void FreeLookCamera::SetControlType(FreelookControlType type)
{
if (m_current_type && *m_current_type == type)
{
return;
}
if (type == FreelookControlType::SixAxis)
{
m_camera_controller = std::make_unique<SixAxisController>();
}
else if (type == FreelookControlType::Orbital)
{
m_camera_controller = std::make_unique<OrbitalController>();
}
else
{
m_camera_controller = std::make_unique<FPSController>();
}
m_current_type = type;
}
Common::Matrix44 FreeLookCamera::GetView()
{
return m_camera_controller->GetView();
}
void FreeLookCamera::MoveVertical(float amt)
{
m_camera_controller->MoveVertical(amt);
m_dirty = true;
}
void FreeLookCamera::MoveHorizontal(float amt)
{
m_camera_controller->MoveHorizontal(amt);
m_dirty = true;
}
void FreeLookCamera::Zoom(float amt)
{
m_camera_controller->Zoom(amt);
m_dirty = true;
}
void FreeLookCamera::Rotate(const Common::Vec3& amt)
{
m_camera_controller->Rotate(amt);
m_dirty = true;
}
void FreeLookCamera::Reset()
{
m_camera_controller->Reset();
m_dirty = true;
}
void FreeLookCamera::DoState(PointerWrap& p)
{
if (p.mode == PointerWrap::MODE_WRITE || p.mode == PointerWrap::MODE_MEASURE)
{
p.Do(m_current_type);
if (m_camera_controller)
{
m_camera_controller->DoState(p);
}
}
else
{
const auto old_type = m_current_type;
p.Do(m_current_type);
if (old_type == m_current_type)
{
m_camera_controller->DoState(p);
}
else if (p.GetMode() == PointerWrap::MODE_READ)
{
const std::string old_type_name = old_type ? to_string(*old_type) : "";
const std::string loaded_type_name = m_current_type ? to_string(*m_current_type) : "";
const std::string message =
fmt::format("State needs same free look camera type. Settings value '{}', loaded value "
"'{}'. Aborting load state",
old_type_name, loaded_type_name);
Core::DisplayMessage(message, 5000);
p.SetMode(PointerWrap::MODE_VERIFY);
}
}
}
bool FreeLookCamera::IsDirty() const
{
return m_dirty;
}

View File

@ -0,0 +1,66 @@
// Copyright 2020 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <optional>
#include "Common/Matrix.h"
#include "VideoCommon/VideoConfig.h"
class PointerWrap;
class CameraController
{
public:
CameraController() = default;
virtual ~CameraController() = default;
CameraController(const CameraController&) = delete;
CameraController& operator=(const CameraController&) = delete;
CameraController(CameraController&&) = delete;
CameraController& operator=(CameraController&&) = delete;
virtual Common::Matrix44 GetView() = 0;
virtual void MoveVertical(float amt) = 0;
virtual void MoveHorizontal(float amt) = 0;
virtual void Zoom(float amt) = 0;
virtual void Rotate(const Common::Vec3& amt) = 0;
virtual void Reset() = 0;
virtual void DoState(PointerWrap& p) = 0;
};
class FreeLookCamera
{
public:
void SetControlType(FreelookControlType type);
Common::Matrix44 GetView();
void MoveVertical(float amt);
void MoveHorizontal(float amt);
void Zoom(float amt);
void Rotate(const Common::Vec3& amt);
void Reset();
void DoState(PointerWrap& p);
bool IsDirty() const;
private:
bool m_dirty = false;
std::optional<FreelookControlType> m_current_type;
std::unique_ptr<CameraController> m_camera_controller;
};
extern FreeLookCamera g_freelook_camera;

View File

@ -12,13 +12,16 @@
#include "Common/BitSet.h" #include "Common/BitSet.h"
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/Config/Config.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Common/Matrix.h" #include "Common/Matrix.h"
#include "Core/Config/GraphicsSettings.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "VideoCommon/BPFunctions.h" #include "VideoCommon/BPFunctions.h"
#include "VideoCommon/BPMemory.h" #include "VideoCommon/BPMemory.h"
#include "VideoCommon/CPMemory.h" #include "VideoCommon/CPMemory.h"
#include "VideoCommon/FreeLookCamera.h"
#include "VideoCommon/RenderBase.h" #include "VideoCommon/RenderBase.h"
#include "VideoCommon/Statistics.h" #include "VideoCommon/Statistics.h"
#include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VertexManagerBase.h"
@ -42,7 +45,6 @@ static std::array<int, 2> nPostTransformMatricesChanged; // min,max
static std::array<int, 2> nLightsChanged; // min,max static std::array<int, 2> nLightsChanged; // min,max
static Common::Matrix44 s_viewportCorrection; static Common::Matrix44 s_viewportCorrection;
static Common::Matrix44 s_freelook_matrix;
VertexShaderConstants VertexShaderManager::constants; VertexShaderConstants VertexShaderManager::constants;
bool VertexShaderManager::dirty; bool VertexShaderManager::dirty;
@ -110,10 +112,10 @@ void VertexShaderManager::Init()
bViewportChanged = false; bViewportChanged = false;
bTexMtxInfoChanged = false; bTexMtxInfoChanged = false;
bLightingConfigChanged = false; bLightingConfigChanged = false;
g_freelook_camera.SetControlType(Config::Get(Config::GFX_FREE_LOOK_CONTROL_TYPE));
std::memset(static_cast<void*>(&xfmem), 0, sizeof(xfmem)); std::memset(static_cast<void*>(&xfmem), 0, sizeof(xfmem));
constants = {}; constants = {};
ResetView();
// TODO: should these go inside ResetView()? // TODO: should these go inside ResetView()?
s_viewportCorrection = Common::Matrix44::Identity(); s_viewportCorrection = Common::Matrix44::Identity();
@ -344,7 +346,7 @@ void VertexShaderManager::SetConstants()
} }
} }
if (bProjectionChanged) if (bProjectionChanged || g_freelook_camera.IsDirty())
{ {
bProjectionChanged = false; bProjectionChanged = false;
@ -413,7 +415,7 @@ void VertexShaderManager::SetConstants()
auto corrected_matrix = s_viewportCorrection * Common::Matrix44::FromArray(g_fProjectionMatrix); auto corrected_matrix = s_viewportCorrection * Common::Matrix44::FromArray(g_fProjectionMatrix);
if (g_ActiveConfig.bFreeLook && xfmem.projection.type == GX_PERSPECTIVE) if (g_ActiveConfig.bFreeLook && xfmem.projection.type == GX_PERSPECTIVE)
corrected_matrix *= s_freelook_matrix; corrected_matrix *= g_freelook_camera.GetView();
memcpy(constants.projection.data(), corrected_matrix.data.data(), 4 * sizeof(float4)); memcpy(constants.projection.data(), corrected_matrix.data.data(), 4 * sizeof(float4));
@ -445,6 +447,9 @@ void VertexShaderManager::SetConstants()
dirty = true; dirty = true;
} }
// Handle a potential config change
g_freelook_camera.SetControlType(Config::Get(Config::GFX_FREE_LOOK_CONTROL_TYPE));
} }
void VertexShaderManager::InvalidateXFRange(int start, int end) void VertexShaderManager::InvalidateXFRange(int start, int end)
@ -600,31 +605,6 @@ void VertexShaderManager::SetMaterialColorChanged(int index)
nMaterialsChanged[index] = true; nMaterialsChanged[index] = true;
} }
void VertexShaderManager::TranslateView(float x, float y, float z)
{
s_freelook_matrix = Common::Matrix44::Translate({x, z, y}) * s_freelook_matrix;
bProjectionChanged = true;
}
void VertexShaderManager::RotateView(float x, float y, float z)
{
using Common::Matrix33;
s_freelook_matrix = Common::Matrix44::FromMatrix33(Matrix33::RotateX(x) * Matrix33::RotateY(y) *
Matrix33::RotateZ(z)) *
s_freelook_matrix;
bProjectionChanged = true;
}
void VertexShaderManager::ResetView()
{
s_freelook_matrix = Common::Matrix44::Identity();
bProjectionChanged = true;
}
void VertexShaderManager::SetVertexFormat(u32 components) void VertexShaderManager::SetVertexFormat(u32 components)
{ {
if (components != constants.components) if (components != constants.components)
@ -673,7 +653,7 @@ void VertexShaderManager::DoState(PointerWrap& p)
{ {
p.DoArray(g_fProjectionMatrix); p.DoArray(g_fProjectionMatrix);
p.Do(s_viewportCorrection); p.Do(s_viewportCorrection);
p.Do(s_freelook_matrix); g_freelook_camera.DoState(p);
p.DoArray(nTransformMatricesChanged); p.DoArray(nTransformMatricesChanged);
p.DoArray(nNormalMatricesChanged); p.DoArray(nNormalMatricesChanged);

View File

@ -29,10 +29,6 @@ public:
static void SetProjectionChanged(); static void SetProjectionChanged();
static void SetMaterialColorChanged(int index); static void SetMaterialColorChanged(int index);
static void TranslateView(float x, float y, float z = 0.0f);
static void RotateView(float x, float y, float z);
static void ResetView();
static void SetVertexFormat(u32 components); static void SetVertexFormat(u32 components);
static void SetTexMatrixInfoChanged(int index); static void SetTexMatrixInfoChanged(int index);
static void SetLightingConfigChanged(); static void SetLightingConfigChanged();

View File

@ -63,6 +63,7 @@
<ClCompile Include="FPSCounter.cpp" /> <ClCompile Include="FPSCounter.cpp" />
<ClCompile Include="FramebufferManager.cpp" /> <ClCompile Include="FramebufferManager.cpp" />
<ClCompile Include="FramebufferShaderGen.cpp" /> <ClCompile Include="FramebufferShaderGen.cpp" />
<ClCompile Include="FreeLookCamera.cpp" />
<ClCompile Include="HiresTextures.cpp" /> <ClCompile Include="HiresTextures.cpp" />
<ClCompile Include="HiresTextures_DDSLoader.cpp" /> <ClCompile Include="HiresTextures_DDSLoader.cpp" />
<ClCompile Include="ImageWrite.cpp" /> <ClCompile Include="ImageWrite.cpp" />
@ -141,6 +142,7 @@
<ClInclude Include="FPSCounter.h" /> <ClInclude Include="FPSCounter.h" />
<ClInclude Include="FramebufferManager.h" /> <ClInclude Include="FramebufferManager.h" />
<ClInclude Include="FramebufferShaderGen.h" /> <ClInclude Include="FramebufferShaderGen.h" />
<ClInclude Include="FreeLookCamera.h" />
<ClInclude Include="GXPipelineTypes.h" /> <ClInclude Include="GXPipelineTypes.h" />
<ClInclude Include="NetPlayChatUI.h" /> <ClInclude Include="NetPlayChatUI.h" />
<ClInclude Include="NetPlayGolfUI.h" /> <ClInclude Include="NetPlayGolfUI.h" />

View File

@ -51,6 +51,13 @@ enum class ShaderCompilationMode : int
AsynchronousSkipRendering AsynchronousSkipRendering
}; };
enum class FreelookControlType : int
{
SixAxis,
FPS,
Orbital
};
// NEVER inherit from this class. // NEVER inherit from this class.
struct VideoConfig final struct VideoConfig final
{ {
@ -107,6 +114,7 @@ struct VideoConfig final
std::string sDumpPath; std::string sDumpPath;
bool bInternalResolutionFrameDumps; bool bInternalResolutionFrameDumps;
bool bFreeLook; bool bFreeLook;
FreelookControlType iFreelookControlType;
bool bBorderlessFullscreen; bool bBorderlessFullscreen;
bool bEnableGPUTextureDecoding; bool bEnableGPUTextureDecoding;
int iBitrateKbps; int iBitrateKbps;