diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index e8b832b5..d8584494 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -3,6 +3,7 @@ #include "../GLM.h" #include "../Core/InputController.h" +#include "../Core/ELockMouse.h" template class FirstPersonInputController : public InputController @@ -11,9 +12,26 @@ public: FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID) : InputController(eventBroker) , m_PlayerID(playerID) - { } + { + EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); + EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); + } const glm::quat Orientation() const { return m_Orientation; } + + void LockMouse() + { + Events::LockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = true; + } + + void UnlockMouse() + { + Events::UnlockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = false; + } virtual bool OnCommand(const Events::InputCommand& e) override { @@ -21,20 +39,32 @@ public: return false; } - if (e.Command == "Pitch") { - float val = glm::radians(e.Value); - m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1, 0, 0)); + if (m_MouseLocked) { + if (e.Command == "Pitch") { + float val = glm::radians(e.Value); + m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1, 0, 0)); + return true; + } + + if (e.Command == "Yaw") { + float val = glm::radians(e.Value); + m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1, 0)) * m_Orientation; + return true; + } } - if (e.Command == "Yaw") { - float val = glm::radians(e.Value); - m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1, 0)) * m_Orientation; - } + return false; } -private: +protected: const unsigned int m_PlayerID; glm::quat m_Orientation; + bool m_MouseLocked = false; + + EventRelay m_ELockMouse; + bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; } + EventRelay m_EUnlockMouse; + bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; } }; #endif \ No newline at end of file diff --git a/include/Engine/Input/InputHandler.h b/include/Engine/Input/InputHandler.h index c8ecb3af..a9b3c038 100644 --- a/include/Engine/Input/InputHandler.h +++ b/include/Engine/Input/InputHandler.h @@ -13,8 +13,9 @@ public: , m_InputProxy(inputProxy) { } - virtual void Update(double dt) { } virtual bool BindOrigin(std::string origin, std::string command, float value) = 0; + virtual void Update(double dt) { } + virtual float GetCommandValue(std::string command) = 0; protected: EventBroker* m_EventBroker; diff --git a/include/Engine/Input/InputProxy.h b/include/Engine/Input/InputProxy.h index d3ee57d9..43c4940c 100644 --- a/include/Engine/Input/InputProxy.h +++ b/include/Engine/Input/InputProxy.h @@ -20,13 +20,17 @@ public: void Process(); template void AddHandler(); - void Publish(const Events::InputCommand& e); protected: EventBroker* m_EventBroker; std::vector m_Handlers; + std::map> m_CommandHandlers; + // Represents every unique command (has of PlayerID & Command) and all values reported for that command this frame - std::map, std::vector> m_CommandQueue; + //std::map, std::vector> m_CommandQueue; + + std::map m_CurrentCommandValues; + std::map m_LastCommandValues; EventRelay m_EBindOrigin; bool OnBindOrigin(const Events::BindOrigin& e); diff --git a/include/Engine/Input/KeyboardInputHandler.h b/include/Engine/Input/KeyboardInputHandler.h index 53b08f7a..49597fce 100644 --- a/include/Engine/Input/KeyboardInputHandler.h +++ b/include/Engine/Input/KeyboardInputHandler.h @@ -12,10 +12,12 @@ public: KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy); bool BindOrigin(std::string origin, std::string command, float value) override; + virtual float GetCommandValue(std::string command) override; private: std::unordered_map m_OriginKeyCodes; std::unordered_map> m_KeyBindings; // GLFW_KEY... -> command string & value + std::unordered_map m_CommandValues; EventRelay m_EKeyDown; bool OnKeyDown(const Events::KeyDown& e); diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini index b6bbd20f..3be67287 100644 --- a/resources/DefaultInput.ini +++ b/resources/DefaultInput.ini @@ -3,10 +3,13 @@ Sensitivity=0.5 InvertPitch=false [Bindings] -W=Forward -A=Left -S=Back -D=Right +MouseLeft=PrimaryFire +MouseX=Yaw +MouseY=Pitch +W=+Forward +S=-Forward +D=+Right +A=-Right R=Reload Space=Jump LeftControl=Crouch diff --git a/src/Engine/Input/InputProxy.cpp b/src/Engine/Input/InputProxy.cpp index 430cb250..3fe29b7d 100644 --- a/src/Engine/Input/InputProxy.cpp +++ b/src/Engine/Input/InputProxy.cpp @@ -22,7 +22,16 @@ void InputProxy::LoadBindings(std::string file) e.Origin = origin.first; e.Command = origin.second; e.Value = 1.f; - OnBindOrigin(e); + if (!e.Command.empty()) { + char prefix = e.Command.at(0); + if (prefix == '+' || prefix == '-') { + e.Command = e.Command.substr(1); + if (prefix == '-') { + e.Value *= -1.f; + } + } + OnBindOrigin(e); + } } } @@ -37,26 +46,26 @@ void InputProxy::Update(double dt) void InputProxy::Process() { - // Accumulate the input values of all unique commands published by input handlers - for (auto& pair : m_CommandQueue) { - Events::InputCommand e; - e.PlayerID = pair.first.first; - e.Command = pair.first.second; - e.Value = 0; - for (auto& value : pair.second) { - e.Value += value; + for (auto& pair : m_CommandHandlers) { + const std::string& command = pair.first; + auto handlers = pair.second; + m_CurrentCommandValues[command] = 0.f; + for (auto& handler : handlers) { + m_CurrentCommandValues[command] += handler->GetCommandValue(command); } - //e.Value = std::max(-1.f, std::min(e.Value, 1.f)); - m_EventBroker->Publish(e); - LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); - } - m_CommandQueue.clear(); -} -void InputProxy::Publish(const Events::InputCommand& e) -{ - auto key = std::make_pair(e.PlayerID, e.Command); - m_CommandQueue[key].push_back(e.Value); + auto last = m_LastCommandValues.find(command); + float currentValue = m_CurrentCommandValues[command]; + if (last == m_LastCommandValues.end() || last->second != currentValue) { + Events::InputCommand e; + e.PlayerID = -1; + e.Command = command; + e.Value = currentValue; + m_EventBroker->Publish(e); + LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); + m_LastCommandValues[command] = currentValue; + } + } } bool InputProxy::OnBindOrigin(const Events::BindOrigin& e) @@ -65,6 +74,8 @@ bool InputProxy::OnBindOrigin(const Events::BindOrigin& e) for (auto& handler : m_Handlers) { bool result = handler->BindOrigin(e.Origin, e.Command, e.Value); if (result) { + m_CommandHandlers[e.Command].insert(handler); + m_LastCommandValues[e.Command] = 0.f; if (originBound) { LOG_WARNING("Multiple handlers responded to binding input origin \"%s\"!", e.Origin.c_str()); } diff --git a/src/Engine/Input/KeyboardInputHandler.cpp b/src/Engine/Input/KeyboardInputHandler.cpp index 1686d8cd..0a0994aa 100644 --- a/src/Engine/Input/KeyboardInputHandler.cpp +++ b/src/Engine/Input/KeyboardInputHandler.cpp @@ -146,10 +146,10 @@ bool KeyboardInputHandler::OnKeyDown(const Events::KeyDown& e) return false; } - Events::InputCommand ic; - ic.PlayerID = 0; - std::tie(ic.Command, ic.Value) = it->second; - m_InputProxy->Publish(ic); + std::string command; + float value; + std::tie(command, value) = it->second; + m_CommandValues[command] += value; return true; } @@ -161,12 +161,21 @@ bool KeyboardInputHandler::OnKeyUp(const Events::KeyUp& e) return false; } - Events::InputCommand ic; - ic.PlayerID = 0; - std::tie(ic.Command, std::ignore) = it->second; - ic.Value = 0; - m_InputProxy->Publish(ic); + std::string command; + float value; + std::tie(command, value) = it->second; + m_CommandValues[command] -= value; return true; } +float KeyboardInputHandler::GetCommandValue(std::string command) +{ + auto it = m_CommandValues.find(command); + if (it != m_CommandValues.end()) { + return m_CommandValues[command]; + } else { + return 0.f; + } +} +