MouseInputHandler
This commit is contained in:
@@ -20,6 +20,7 @@ public:
|
|||||||
void Process();
|
void Process();
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void AddHandler();
|
void AddHandler();
|
||||||
|
void Publish(const Events::InputCommand& e);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
@@ -27,7 +28,7 @@ protected:
|
|||||||
std::map<std::string, std::set<InputHandler*>> m_CommandHandlers;
|
std::map<std::string, std::set<InputHandler*>> m_CommandHandlers;
|
||||||
|
|
||||||
// Represents every unique command (has of PlayerID & Command) and all values reported for that command this frame
|
// Represents every unique command (has of PlayerID & Command) and all values reported for that command this frame
|
||||||
//std::map<std::pair<unsigned int, std::string>, std::vector<float>> m_CommandQueue;
|
std::map<std::pair<unsigned int, std::string>, std::vector<float>> m_CommandQueue;
|
||||||
|
|
||||||
std::map<std::string, float> m_CurrentCommandValues;
|
std::map<std::string, float> m_CurrentCommandValues;
|
||||||
std::map<std::string, float> m_LastCommandValues;
|
std::map<std::string, float> m_LastCommandValues;
|
||||||
|
|||||||
@@ -13,12 +13,15 @@ public:
|
|||||||
MouseInputHandler(EventBroker* eventBroker, InputProxy* inputProxy);
|
MouseInputHandler(EventBroker* eventBroker, InputProxy* inputProxy);
|
||||||
|
|
||||||
bool BindOrigin(std::string origin, std::string command, float value) override;
|
bool BindOrigin(std::string origin, std::string command, float value) override;
|
||||||
|
virtual float GetCommandValue(std::string command) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, int> m_OriginCodes;
|
std::unordered_map<std::string, int> m_OriginCodes;
|
||||||
std::unordered_map<std::string, char> m_OriginAxes;
|
std::unordered_map<std::string, char> m_OriginAxes;
|
||||||
std::unordered_map<int, std::tuple<std::string, float>> m_Bindings; // GLFW_MOUSE_BUTTON... -> command string & value
|
std::unordered_map<int, std::tuple<std::string, float>> m_Bindings; // GLFW_MOUSE_BUTTON... -> command string & value
|
||||||
std::unordered_map<char, std::tuple<std::string, float>> m_Axes; // Axis -> command string & value
|
std::unordered_map<char, std::tuple<std::string, float>> m_Axes; // Axis -> command string & value
|
||||||
|
std::unordered_map<std::string, float> m_CommandValues;
|
||||||
|
std::unordered_map<std::string, float> m_ContinuousCommandValues;
|
||||||
|
|
||||||
EventRelay<InputHandler, Events::MousePress> m_EMousePress;
|
EventRelay<InputHandler, Events::MousePress> m_EMousePress;
|
||||||
bool OnMousePress(const Events::MousePress& e);
|
bool OnMousePress(const Events::MousePress& e);
|
||||||
@@ -28,6 +31,8 @@ private:
|
|||||||
bool OnMouseMove(const Events::MouseMove& e);
|
bool OnMouseMove(const Events::MouseMove& e);
|
||||||
|
|
||||||
bool hasOrigin(std::string origin);
|
bool hasOrigin(std::string origin);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#include "../Input/FirstPersonInputController.h"
|
||||||
|
|
||||||
|
template <typename EventContext>
|
||||||
|
class DebugCameraInputController : public FirstPersonInputController<EventContext>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DebugCameraInputController(EventBroker* eventBroker, unsigned int playerID)
|
||||||
|
: FirstPersonInputController(eventBroker, playerID)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
const glm::vec3 Position() const { return m_Position; }
|
||||||
|
void SetBaseSpeed(float speed) { m_BaseSpeed = speed; }
|
||||||
|
|
||||||
|
virtual bool OnCommand(const Events::InputCommand& e) override
|
||||||
|
{
|
||||||
|
if (e.Command == "PrimaryFire") {
|
||||||
|
if (e.Value > 0) {
|
||||||
|
LockMouse();
|
||||||
|
} else {
|
||||||
|
UnlockMouse();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Command == "Right") {
|
||||||
|
float value = std::max(-1.f, std::min(e.Value, 1.f));
|
||||||
|
m_Velocity.x = value;
|
||||||
|
}
|
||||||
|
if (e.Command == "Forward") {
|
||||||
|
float value = std::max(-1.f, std::min(e.Value, 1.f));
|
||||||
|
m_Velocity.z = -value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FirstPersonInputController::OnCommand(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(double dt)
|
||||||
|
{
|
||||||
|
if (glm::length2(m_Velocity) > 0) {
|
||||||
|
m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_BaseSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
glm::vec3 m_Position = glm::vec3(0, 0, 0);
|
||||||
|
glm::vec3 m_Velocity = glm::vec3(0, 0, 0);
|
||||||
|
float m_BaseSpeed = 0.1f;
|
||||||
|
};
|
||||||
@@ -66,6 +66,27 @@ void InputProxy::Process()
|
|||||||
m_LastCommandValues[command] = currentValue;
|
m_LastCommandValues[command] = currentValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
//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);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputProxy::OnBindOrigin(const Events::BindOrigin& e)
|
bool InputProxy::OnBindOrigin(const Events::BindOrigin& e)
|
||||||
|
|||||||
@@ -50,6 +50,16 @@ bool MouseInputHandler::BindOrigin(std::string origin, std::string command, floa
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float MouseInputHandler::GetCommandValue(std::string command)
|
||||||
|
{
|
||||||
|
auto it = m_CommandValues.find(command);
|
||||||
|
if (it != m_CommandValues.end()) {
|
||||||
|
return m_CommandValues[command];
|
||||||
|
} else {
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool MouseInputHandler::OnMousePress(const Events::MousePress& e)
|
bool MouseInputHandler::OnMousePress(const Events::MousePress& e)
|
||||||
{
|
{
|
||||||
auto it = m_Bindings.find(e.Button);
|
auto it = m_Bindings.find(e.Button);
|
||||||
@@ -57,10 +67,10 @@ bool MouseInputHandler::OnMousePress(const Events::MousePress& e)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Events::InputCommand ic;
|
std::string command;
|
||||||
ic.PlayerID = 0;
|
float value;
|
||||||
std::tie(ic.Command, ic.Value) = it->second;
|
std::tie(command, value) = it->second;
|
||||||
m_InputProxy->Publish(ic);
|
m_CommandValues[command] += value;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -72,11 +82,10 @@ bool MouseInputHandler::OnMouseRelease(const Events::MouseRelease& e)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Events::InputCommand ic;
|
std::string command;
|
||||||
ic.PlayerID = 0;
|
float value;
|
||||||
std::tie(ic.Command, std::ignore) = it->second;
|
std::tie(command, value) = it->second;
|
||||||
ic.Value = 0;
|
m_CommandValues[command] -= value;
|
||||||
m_InputProxy->Publish(ic);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -87,7 +96,7 @@ bool MouseInputHandler::OnMouseMove(const Events::MouseMove& e)
|
|||||||
auto it = m_Axes.find('X');
|
auto it = m_Axes.find('X');
|
||||||
if (it != m_Axes.end()) {
|
if (it != m_Axes.end()) {
|
||||||
Events::InputCommand ic;
|
Events::InputCommand ic;
|
||||||
ic.PlayerID = 0;
|
ic.PlayerID = -1;
|
||||||
std::tie(ic.Command, ic.Value) = it->second;
|
std::tie(ic.Command, ic.Value) = it->second;
|
||||||
ic.Value *= e.DeltaX;
|
ic.Value *= e.DeltaX;
|
||||||
m_InputProxy->Publish(ic);
|
m_InputProxy->Publish(ic);
|
||||||
@@ -98,7 +107,7 @@ bool MouseInputHandler::OnMouseMove(const Events::MouseMove& e)
|
|||||||
auto it = m_Axes.find('Y');
|
auto it = m_Axes.find('Y');
|
||||||
if (it != m_Axes.end()) {
|
if (it != m_Axes.end()) {
|
||||||
Events::InputCommand ic;
|
Events::InputCommand ic;
|
||||||
ic.PlayerID = 0;
|
ic.PlayerID = -1;
|
||||||
std::tie(ic.Command, ic.Value) = it->second;
|
std::tie(ic.Command, ic.Value) = it->second;
|
||||||
ic.Value *= e.DeltaY;
|
ic.Value *= e.DeltaY;
|
||||||
m_InputProxy->Publish(ic);
|
m_InputProxy->Publish(ic);
|
||||||
@@ -117,5 +126,4 @@ bool MouseInputHandler::hasOrigin(std::string origin)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "Rendering/Renderer.h"
|
#include "Rendering/Renderer.h"
|
||||||
|
#include "Rendering/DebugCameraInputController.h"
|
||||||
|
|
||||||
void Renderer::Initialize()
|
void Renderer::Initialize()
|
||||||
{
|
{
|
||||||
@@ -83,6 +84,8 @@ void Renderer::InitializeShaders()
|
|||||||
|
|
||||||
void Renderer::InputUpdate(double dt)
|
void Renderer::InputUpdate(double dt)
|
||||||
{
|
{
|
||||||
|
static DebugCameraInputController<Renderer> firstPersonInputController(m_EventBroker, -1);
|
||||||
|
|
||||||
glm::vec3 m_Position = m_Camera->Position();
|
glm::vec3 m_Position = m_Camera->Position();
|
||||||
if (glfwGetKey(m_Window, GLFW_KEY_O) == GLFW_PRESS)
|
if (glfwGetKey(m_Window, GLFW_KEY_O) == GLFW_PRESS)
|
||||||
{
|
{
|
||||||
@@ -112,37 +115,15 @@ void Renderer::InputUpdate(double dt)
|
|||||||
m_CameraMoveSpeed = 0.5f;
|
m_CameraMoveSpeed = 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
firstPersonInputController.Update(dt);
|
||||||
static double mousePosX, mousePosY;
|
m_Camera->SetOrientation(firstPersonInputController.Orientation());
|
||||||
glfwGetCursorPos(m_Window, &mousePosX, &mousePosY);
|
m_Camera->SetPosition(firstPersonInputController.Position());
|
||||||
|
|
||||||
if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) {
|
|
||||||
|
|
||||||
|
|
||||||
double deltaX, deltaY;
|
|
||||||
deltaX = mousePosX - (float)Resolution().Width / 2;
|
|
||||||
deltaY = mousePosY - (float)Resolution().Height / 2;
|
|
||||||
|
|
||||||
float rotationY = -deltaY / 300.f;
|
|
||||||
float rotationX = -deltaX / 300.f;
|
|
||||||
glm::quat orientation = m_Camera->Orientation();
|
|
||||||
|
|
||||||
|
|
||||||
orientation = orientation * glm::angleAxis<float>(rotationY, glm::vec3(1, 0, 0));
|
|
||||||
orientation = glm::angleAxis<float>(rotationX, glm::vec3(0, 1, 0)) * orientation;
|
|
||||||
|
|
||||||
m_Camera->SetOrientation(orientation);
|
|
||||||
|
|
||||||
glfwSetCursorPos(m_Window, Resolution().Width / 2, Resolution().Height / 2);
|
|
||||||
}
|
|
||||||
m_Camera->SetPosition(m_Position);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Update(double dt)
|
void Renderer::Update(double dt)
|
||||||
{
|
{
|
||||||
m_EventBroker->Process<Renderer>();
|
m_EventBroker->Process<Renderer>();
|
||||||
InputUpdate(dt);
|
InputUpdate(dt);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Draw(RenderQueueCollection& rq)
|
void Renderer::Draw(RenderQueueCollection& rq)
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ void Game::Tick()
|
|||||||
m_LastTime = currentTime;
|
m_LastTime = currentTime;
|
||||||
|
|
||||||
// Handle input in a weird looking but responsive way
|
// Handle input in a weird looking but responsive way
|
||||||
|
m_EventBroker->Process<InputManager>();
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
m_InputManager->Update(dt);
|
m_InputManager->Update(dt);
|
||||||
m_EventBroker->Swap();
|
m_EventBroker->Swap();
|
||||||
|
|||||||
Reference in New Issue
Block a user