Merge pull request #8767 from iwubcode/freelook-camera-type
Expand freelook camera with control options
This commit is contained in:
commit
cea779cc84
|
@ -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"}, ""};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
|
@ -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});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue