feat: add firstpersoncontroller
This commit is contained in:
@@ -30,8 +30,8 @@ public:
|
|||||||
|
|
||||||
int MouseX() const { return m_mouseX; }
|
int MouseX() const { return m_mouseX; }
|
||||||
int MouseY() const { return m_mouseY; }
|
int MouseY() const { return m_mouseY; }
|
||||||
int MouseDeltaX() const { return m_mouseDX; }
|
int MouseDeltaX() const { return m_mouseRelDX; }
|
||||||
int MouseDeltaY() const { return m_mouseDY; }
|
int MouseDeltaY() const { return m_mouseRelDY; }
|
||||||
|
|
||||||
int WheelX() const { return m_wheelX; }
|
int WheelX() const { return m_wheelX; }
|
||||||
int WheelY() const { return m_wheelY; }
|
int WheelY() const { return m_wheelY; }
|
||||||
@@ -81,6 +81,9 @@ public:
|
|||||||
|
|
||||||
void SetAxisDeadzone(int deadzone) { m_axisDeadzone = deadzone; } // 0..32767
|
void SetAxisDeadzone(int deadzone) { m_axisDeadzone = deadzone; } // 0..32767
|
||||||
|
|
||||||
|
void SetMouseCaptured(bool captured);
|
||||||
|
[[nodiscard]] bool IsMouseCaptured() const { return m_MouseCaptured; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Key states
|
// Key states
|
||||||
std::unordered_set<SDL_Scancode> m_keysDown;
|
std::unordered_set<SDL_Scancode> m_keysDown;
|
||||||
@@ -92,10 +95,9 @@ private:
|
|||||||
std::unordered_set<Uint8> m_mousePressed;
|
std::unordered_set<Uint8> m_mousePressed;
|
||||||
std::unordered_set<Uint8> m_mouseReleased;
|
std::unordered_set<Uint8> m_mouseReleased;
|
||||||
|
|
||||||
// Mouse position + delta
|
// Mouse position + relative delta (accumulated from SDL xrel/yrel)
|
||||||
int m_mouseX = 0, m_mouseY = 0;
|
int m_mouseX = 0, m_mouseY = 0;
|
||||||
int m_prevMouseX = 0, m_prevMouseY = 0;
|
int m_mouseRelDX = 0, m_mouseRelDY = 0;
|
||||||
int m_mouseDX = 0, m_mouseDY = 0;
|
|
||||||
|
|
||||||
int m_wheelX = 0, m_wheelY = 0;
|
int m_wheelX = 0, m_wheelY = 0;
|
||||||
|
|
||||||
@@ -125,6 +127,8 @@ private:
|
|||||||
|
|
||||||
int m_axisDeadzone = 8000; // typical deadzone
|
int m_axisDeadzone = 8000; // typical deadzone
|
||||||
|
|
||||||
|
bool m_MouseCaptured = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool QueryBinding(const Binding& b, ButtonState state) const;
|
bool QueryBinding(const Binding& b, ButtonState state) const;
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -131,6 +131,12 @@ void App::run()
|
|||||||
|
|
||||||
imguiPass.handleEvent(event);
|
imguiPass.handleEvent(event);
|
||||||
|
|
||||||
|
const bool mouseEvent =
|
||||||
|
event.type == SDL_MOUSEBUTTONDOWN ||
|
||||||
|
event.type == SDL_MOUSEBUTTONUP ||
|
||||||
|
event.type == SDL_MOUSEMOTION ||
|
||||||
|
event.type == SDL_MOUSEWHEEL;
|
||||||
|
|
||||||
if (event.type == SDL_QUIT)
|
if (event.type == SDL_QUIT)
|
||||||
{
|
{
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
@@ -149,19 +155,13 @@ void App::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool mouseEvent =
|
|
||||||
event.type == SDL_MOUSEBUTTONDOWN ||
|
|
||||||
event.type == SDL_MOUSEBUTTONUP ||
|
|
||||||
event.type == SDL_MOUSEMOTION ||
|
|
||||||
event.type == SDL_MOUSEWHEEL;
|
|
||||||
|
|
||||||
const bool keyboardEvent =
|
const bool keyboardEvent =
|
||||||
event.type == SDL_KEYDOWN ||
|
event.type == SDL_KEYDOWN ||
|
||||||
event.type == SDL_KEYUP ||
|
event.type == SDL_KEYUP ||
|
||||||
event.type == SDL_TEXTINPUT;
|
event.type == SDL_TEXTINPUT;
|
||||||
|
|
||||||
const bool capturedByImgui =
|
const bool capturedByImgui =
|
||||||
(mouseEvent && imguiPass.wantsMouse()) ||
|
(mouseEvent && !InputManager::GetInstance().IsMouseCaptured() && imguiPass.wantsMouse()) ||
|
||||||
(keyboardEvent && imguiPass.wantsKeyboard());
|
(keyboardEvent && imguiPass.wantsKeyboard());
|
||||||
|
|
||||||
if (!capturedByImgui)
|
if (!capturedByImgui)
|
||||||
@@ -176,7 +176,7 @@ void App::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isRunning) break;
|
if (!isRunning) break;
|
||||||
|
|
||||||
// Consume SDL events before updating the base camera so held and
|
// Consume SDL events before updating the base camera so held and
|
||||||
// newly pressed inputs are applied in the same frame.
|
// newly pressed inputs are applied in the same frame.
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ void Camera::SetRotation(const glm::vec2& yawPitchRadians) {
|
|||||||
SetRotation(yawPitchRadians.x, yawPitchRadians.y);
|
SetRotation(yawPitchRadians.x, yawPitchRadians.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::SetTarget(const glm::vec3& target) {
|
void Camera::SetTarget(const glm::vec3&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::ClearTarget() {
|
void Camera::ClearTarget() {
|
||||||
|
|||||||
@@ -124,6 +124,11 @@ void ImguiPass::beginFrame() {
|
|||||||
|
|
||||||
ImGui_ImplVulkan_NewFrame();
|
ImGui_ImplVulkan_NewFrame();
|
||||||
ImGui_ImplSDL2_NewFrame();
|
ImGui_ImplSDL2_NewFrame();
|
||||||
|
|
||||||
|
if (SDL_GetRelativeMouseMode() == SDL_TRUE) {
|
||||||
|
ImGui::GetIO().MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
frameBegun = true;
|
frameBegun = true;
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ void InputManager::BeginFrame() {
|
|||||||
|
|
||||||
m_textInput.clear();
|
m_textInput.clear();
|
||||||
|
|
||||||
// Update mouse delta based on last known position
|
// Relative mouse accumulators are filled during SDL event processing
|
||||||
m_mouseDX = m_mouseX - m_prevMouseX;
|
// and consumed by game code each frame. Reset them here (before events
|
||||||
m_mouseDY = m_mouseY - m_prevMouseY;
|
// are processed) so this frame accumulates fresh deltas.
|
||||||
m_prevMouseX = m_mouseX;
|
m_mouseRelDX = 0;
|
||||||
m_prevMouseY = m_mouseY;
|
m_mouseRelDY = 0;
|
||||||
|
|
||||||
// Clear controller "edge" sets + snapshot axes
|
// Clear controller "edge" sets + snapshot axes
|
||||||
for (auto& [id, pad]: m_pads) {
|
for (auto& [id, pad]: m_pads) {
|
||||||
@@ -60,6 +60,12 @@ void InputManager::BeginFrame() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputManager::SetMouseCaptured(bool captured) {
|
||||||
|
if (captured == m_MouseCaptured) return;
|
||||||
|
m_MouseCaptured = captured;
|
||||||
|
SDL_SetRelativeMouseMode(captured ? SDL_TRUE : SDL_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
void InputManager::AddController(int deviceIndex) {
|
void InputManager::AddController(int deviceIndex) {
|
||||||
if (!SDL_IsGameController(deviceIndex)) return;
|
if (!SDL_IsGameController(deviceIndex)) return;
|
||||||
|
|
||||||
@@ -134,6 +140,8 @@ bool InputManager::ProcessEvent(const SDL_Event& e) {
|
|||||||
case SDL_MOUSEMOTION: {
|
case SDL_MOUSEMOTION: {
|
||||||
m_mouseX = e.motion.x;
|
m_mouseX = e.motion.x;
|
||||||
m_mouseY = e.motion.y;
|
m_mouseY = e.motion.y;
|
||||||
|
m_mouseRelDX += e.motion.xrel;
|
||||||
|
m_mouseRelDY += e.motion.yrel;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ set(GAME_SRC
|
|||||||
src/Lightkeeper.cpp
|
src/Lightkeeper.cpp
|
||||||
|
|
||||||
src/components/GameComponentRegistry.cpp
|
src/components/GameComponentRegistry.cpp
|
||||||
|
src/components/FirstPersonController.cpp
|
||||||
src/components/PrintComponent.cpp
|
src/components/PrintComponent.cpp
|
||||||
src/components/TriggerLoggerComponent.cpp
|
src/components/TriggerLoggerComponent.cpp
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "destrum/Graphics/Resources/Cubemap.h"
|
#include "destrum/Graphics/Resources/Cubemap.h"
|
||||||
#include "destrum/ObjectModel/GameObject.h"
|
#include "destrum/ObjectModel/GameObject.h"
|
||||||
|
|
||||||
|
class FirstPersonController;
|
||||||
class LightKeeper final : public App {
|
class LightKeeper final : public App {
|
||||||
public:
|
public:
|
||||||
LightKeeper();
|
LightKeeper();
|
||||||
@@ -39,6 +40,8 @@ private:
|
|||||||
std::unique_ptr<CubeMap> skyboxCubemap;
|
std::unique_ptr<CubeMap> skyboxCubemap;
|
||||||
|
|
||||||
GameObject* capybara = nullptr;
|
GameObject* capybara = nullptr;
|
||||||
|
GameObject* m_Player = nullptr;
|
||||||
|
FirstPersonController* m_FPSController = nullptr;
|
||||||
|
|
||||||
char scenePath[512]{"scenes/debug_scene.json"};
|
char scenePath[512]{"scenes/debug_scene.json"};
|
||||||
char newSceneName[128]{"EmptyScene"};
|
char newSceneName[128]{"EmptyScene"};
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef LIGHTKEEPER_FIRSTPERSONCONTROLLER_H
|
||||||
|
#define LIGHTKEEPER_FIRSTPERSONCONTROLLER_H
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <destrum/Input/InputManager.h>
|
||||||
|
#include <destrum/ObjectModel/Component.h>
|
||||||
|
|
||||||
|
class Rigidbody;
|
||||||
|
class CapsuleCollider;
|
||||||
|
|
||||||
|
class FirstPersonController final : public Component {
|
||||||
|
public:
|
||||||
|
explicit FirstPersonController(GameObject& parent);
|
||||||
|
|
||||||
|
std::string GetTypeName() const override { return "FirstPersonController"; }
|
||||||
|
|
||||||
|
void Start() override;
|
||||||
|
void Update(float dt) override;
|
||||||
|
void FixedUpdate(float fixedDt) override;
|
||||||
|
void ImGuiInspector() override;
|
||||||
|
nlohmann::json Serialize() const override;
|
||||||
|
void Deserialize(const nlohmann::json& data) override;
|
||||||
|
|
||||||
|
[[nodiscard]] float GetYaw() const { return m_Yaw; }
|
||||||
|
[[nodiscard]] float GetPitch() const { return m_Pitch; }
|
||||||
|
[[nodiscard]] float GetEyeHeight() const { return m_EyeHeight; }
|
||||||
|
|
||||||
|
void SetMovementSpeed(float speed) { m_MovementSpeed = speed; }
|
||||||
|
[[nodiscard]] float GetMovementSpeed() const { return m_MovementSpeed; }
|
||||||
|
|
||||||
|
void SetMouseSensitivity(float sens) { m_MouseSensitivity = sens; }
|
||||||
|
[[nodiscard]] float GetMouseSensitivity() const { return m_MouseSensitivity; }
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsMouseCaptured() const { return InputManager::GetInstance().IsMouseCaptured(); }
|
||||||
|
void SetMouseCaptured(bool captured);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Rigidbody* m_Rigidbody{nullptr};
|
||||||
|
CapsuleCollider* m_Capsule{nullptr};
|
||||||
|
|
||||||
|
float m_Yaw{0.0f};
|
||||||
|
float m_Pitch{0.0f};
|
||||||
|
float m_MovementSpeed{5.0f};
|
||||||
|
float m_MouseSensitivity{0.002f};
|
||||||
|
float m_EyeHeight{1.6f};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
#ifndef LIGHTKEEPER_GAMECOMPONENTLIST_H
|
#ifndef LIGHTKEEPER_GAMECOMPONENTLIST_H
|
||||||
#define LIGHTKEEPER_GAMECOMPONENTLIST_H
|
#define LIGHTKEEPER_GAMECOMPONENTLIST_H
|
||||||
|
|
||||||
|
#include <components/FirstPersonController.h>
|
||||||
#include <components/PrintComponent.h>
|
#include <components/PrintComponent.h>
|
||||||
#include <components/TriggerLoggerComponent.h>
|
#include <components/TriggerLoggerComponent.h>
|
||||||
|
|
||||||
#define LIGHTKEEPER_GAME_COMPONENTS(X) \
|
#define LIGHTKEEPER_GAME_COMPONENTS(X) \
|
||||||
|
X(FirstPersonController) \
|
||||||
X(PrintComponent) \
|
X(PrintComponent) \
|
||||||
X(TriggerLoggerComponent)
|
X(TriggerLoggerComponent)
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "destrum/ObjectModel/GameObject.h"
|
#include "destrum/ObjectModel/GameObject.h"
|
||||||
#include "destrum/Util/ModelDoc.h"
|
#include "destrum/Util/ModelDoc.h"
|
||||||
#include "destrum/Components/Animator.h"
|
#include "destrum/Components/Animator.h"
|
||||||
|
#include <components/FirstPersonController.h>
|
||||||
#include <components/TriggerLoggerComponent.h>
|
#include <components/TriggerLoggerComponent.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -446,6 +447,13 @@ void LightKeeper::customInit()
|
|||||||
triggerObj->AddComponent<TriggerLoggerComponent>();
|
triggerObj->AddComponent<TriggerLoggerComponent>();
|
||||||
triggerObj->GetTransform().SetWorldPosition({0.0f, 0.0f, 0.0f});
|
triggerObj->GetTransform().SetWorldPosition({0.0f, 0.0f, 0.0f});
|
||||||
|
|
||||||
|
auto playerObj = scene.CreateGameObject("Player");
|
||||||
|
playerObj->GetTransform().SetWorldPosition(glm::vec3(0.0f, 2.0f, -5.0f));
|
||||||
|
auto* fps = playerObj->AddComponent<FirstPersonController>();
|
||||||
|
m_Player = playerObj;
|
||||||
|
m_FPSController = fps;
|
||||||
|
scene.GetPhysics().RegisterGameObject(*playerObj);
|
||||||
|
|
||||||
const auto texPath = AssetFS::GetInstance().GetFullPath("engine://textures/kobe.png");
|
const auto texPath = AssetFS::GetInstance().GetFullPath("engine://textures/kobe.png");
|
||||||
texID = resources.loadImageFromFile(gfxDevice, texPath);
|
texID = resources.loadImageFromFile(gfxDevice, texPath);
|
||||||
|
|
||||||
@@ -455,7 +463,19 @@ void LightKeeper::customUpdate(float dt)
|
|||||||
{
|
{
|
||||||
// LightKeeper owns a camera that hides App::camera; update this instance
|
// LightKeeper owns a camera that hides App::camera; update this instance
|
||||||
// after SDL events have been consumed.
|
// after SDL events have been consumed.
|
||||||
|
if (m_FPSController != nullptr && m_FPSController->IsMouseCaptured())
|
||||||
|
{
|
||||||
|
auto& playerTransform = m_Player->GetTransform();
|
||||||
|
const glm::vec3 playerPos = playerTransform.GetWorldPosition();
|
||||||
|
camera.SetRotation(m_FPSController->GetYaw(), m_FPSController->GetPitch());
|
||||||
|
camera.m_position = playerPos + glm::vec3(0.0f, m_FPSController->GetEyeHeight(), 0.0f);
|
||||||
|
camera.CalculateViewMatrix();
|
||||||
|
camera.CalculateProjectionMatrix();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
camera.Update(dt);
|
camera.Update(dt);
|
||||||
|
}
|
||||||
SceneManager::GetInstance().Update(dt);
|
SceneManager::GetInstance().Update(dt);
|
||||||
SceneManager::GetInstance().LateUpdate(dt);
|
SceneManager::GetInstance().LateUpdate(dt);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
#include <components/FirstPersonController.h>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
#include <glm/gtx/norm.hpp>
|
||||||
|
|
||||||
|
#include <destrum/Components/Physics/CapsuleCollider.h>
|
||||||
|
#include <destrum/Components/Physics/Rigidbody.h>
|
||||||
|
#include <destrum/Input/InputManager.h>
|
||||||
|
#include <destrum/ObjectModel/GameObject.h>
|
||||||
|
#include <destrum/Physics/PhysicsWorld.h>
|
||||||
|
#include <destrum/Scene/Scene.h>
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
FirstPersonController::FirstPersonController(GameObject& parent)
|
||||||
|
: Component(parent, "FirstPersonController")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirstPersonController::SetMouseCaptured(bool captured)
|
||||||
|
{
|
||||||
|
InputManager::GetInstance().SetMouseCaptured(captured);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirstPersonController::Start()
|
||||||
|
{
|
||||||
|
auto* obj = GetGameObject();
|
||||||
|
m_Capsule = obj->AddComponent<CapsuleCollider>(0.5f, 2.0f);
|
||||||
|
m_Rigidbody = obj->AddComponent<Rigidbody>();
|
||||||
|
m_Rigidbody->SetMass(80.0f);
|
||||||
|
m_Rigidbody->SetAllowSleep(false);
|
||||||
|
m_Rigidbody->SetUseGravity(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirstPersonController::Update(float)
|
||||||
|
{
|
||||||
|
const auto& input = InputManager::GetInstance();
|
||||||
|
|
||||||
|
if (input.WasKeyPressed(SDL_SCANCODE_F5))
|
||||||
|
{
|
||||||
|
SetMouseCaptured(!IsMouseCaptured());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsMouseCaptured())
|
||||||
|
{
|
||||||
|
if (input.WasMousePressed(SDL_BUTTON_LEFT) && !ImGui::GetIO().WantCaptureMouse)
|
||||||
|
{
|
||||||
|
SetMouseCaptured(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.WasKeyPressed(SDL_SCANCODE_ESCAPE))
|
||||||
|
{
|
||||||
|
SetMouseCaptured(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.WasKeyPressed(SDL_SCANCODE_SPACE) && m_Rigidbody->HasPhysicsBody())
|
||||||
|
{
|
||||||
|
m_Rigidbody->AddImpulse(glm::vec3(0.0f, 400.0f, 0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Yaw += static_cast<float>(input.MouseDeltaX()) * m_MouseSensitivity;
|
||||||
|
m_Pitch -= static_cast<float>(input.MouseDeltaY()) * m_MouseSensitivity;
|
||||||
|
m_Pitch = glm::clamp(m_Pitch, glm::radians(-89.0f), glm::radians(89.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirstPersonController::FixedUpdate(float)
|
||||||
|
{
|
||||||
|
if (!IsMouseCaptured() || m_Rigidbody == nullptr || !m_Rigidbody->HasPhysicsBody())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto& input = InputManager::GetInstance();
|
||||||
|
|
||||||
|
const float cosY = glm::cos(m_Yaw);
|
||||||
|
const float sinY = glm::sin(m_Yaw);
|
||||||
|
const glm::vec3 forward{cosY, 0.0f, sinY};
|
||||||
|
const glm::vec3 right{-sinY, 0.0f, cosY};
|
||||||
|
|
||||||
|
glm::vec3 moveDir(0.0f);
|
||||||
|
if (input.IsKeyDown(SDL_SCANCODE_W)) moveDir += forward;
|
||||||
|
if (input.IsKeyDown(SDL_SCANCODE_S)) moveDir -= forward;
|
||||||
|
if (input.IsKeyDown(SDL_SCANCODE_D)) moveDir += right;
|
||||||
|
if (input.IsKeyDown(SDL_SCANCODE_A)) moveDir -= right;
|
||||||
|
|
||||||
|
glm::vec3 velocity(0.0f);
|
||||||
|
if (glm::length2(moveDir) > 0.0f)
|
||||||
|
{
|
||||||
|
moveDir = glm::normalize(moveDir);
|
||||||
|
velocity = moveDir * m_MovementSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
velocity.y = m_Rigidbody->GetLinearVelocity().y;
|
||||||
|
m_Rigidbody->SetLinearVelocity(velocity);
|
||||||
|
|
||||||
|
auto* world = m_Rigidbody->GetPhysicsWorld();
|
||||||
|
if (world != nullptr)
|
||||||
|
{
|
||||||
|
PhysicsTransform xform = world->GetBodyTransform(m_Rigidbody->GetBody());
|
||||||
|
xform.rotation = glm::quat(glm::vec3(0.0f, m_Yaw, 0.0f));
|
||||||
|
world->SetBodyTransform(m_Rigidbody->GetBody(), xform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirstPersonController::ImGuiInspector()
|
||||||
|
{
|
||||||
|
Component::ImGuiInspector();
|
||||||
|
ImGui::DragFloat("Movement Speed", &m_MovementSpeed, 0.1f, 0.0f, 100.0f);
|
||||||
|
ImGui::DragFloat("Mouse Sensitivity", &m_MouseSensitivity, 0.0001f, 0.0f, 0.1f);
|
||||||
|
ImGui::DragFloat("Eye Height", &m_EyeHeight, 0.01f, 0.0f, 5.0f);
|
||||||
|
ImGui::Text("Yaw: %.1f deg", glm::degrees(m_Yaw));
|
||||||
|
ImGui::Text("Pitch: %.1f deg", glm::degrees(m_Pitch));
|
||||||
|
bool captured = IsMouseCaptured();
|
||||||
|
ImGui::Checkbox("Mouse Captured", &captured);
|
||||||
|
if (captured != IsMouseCaptured()) {
|
||||||
|
SetMouseCaptured(captured);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json FirstPersonController::Serialize() const
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
{"movementSpeed", m_MovementSpeed},
|
||||||
|
{"mouseSensitivity", m_MouseSensitivity},
|
||||||
|
{"eyeHeight", m_EyeHeight},
|
||||||
|
{"yaw", m_Yaw},
|
||||||
|
{"pitch", m_Pitch},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirstPersonController::Deserialize(const nlohmann::json& data)
|
||||||
|
{
|
||||||
|
if (data.contains("movementSpeed")) m_MovementSpeed = data.at("movementSpeed").get<float>();
|
||||||
|
if (data.contains("mouseSensitivity")) m_MouseSensitivity = data.at("mouseSensitivity").get<float>();
|
||||||
|
if (data.contains("eyeHeight")) m_EyeHeight = data.at("eyeHeight").get<float>();
|
||||||
|
if (data.contains("yaw")) m_Yaw = data.at("yaw").get<float>();
|
||||||
|
if (data.contains("pitch")) m_Pitch = data.at("pitch").get<float>();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user