From ca2aab449e340af9968dd97c1f39a6706876e511 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 22 Jan 2016 16:12:51 +0100 Subject: [PATCH] Basic movement and camera management between players and editor --- assets | 2 +- include/Engine/Core/EntityWrapper.h | 1 + include/Engine/Core/Transform.h | 5 + .../Editor/EditorCameraInputController.h | 98 ++++++++++++++ include/Engine/Editor/EditorSystem.h | 19 ++- include/Engine/Input/EInputCommand.h | 2 +- .../Engine/Input/FirstPersonInputController.h | 33 ++++- .../Rendering/DebugCameraInputController.h | 84 ------------ include/Engine/Rendering/RenderSystem.h | 1 - include/Game/Systems/PlayerMovementSystem.h | 18 ++- include/Game/Systems/PlayerSpawnSystem.h | 1 + resources/DefaultConfig.ini | 4 +- resources/Schema/Components/Player.xml | 6 +- resources/Schema/Components/Player.xsd | 6 +- resources/Schema/Entities/CollidableCube.xml | 15 +++ resources/Schema/Entities/MovementTest.xml | 125 +++++++++++++----- resources/Schema/Entities/Player.xml | 61 +++++++-- resources/Schema/Types.xsd | 3 + src/Engine/Core/EntityWrapper.cpp | 16 +++ src/Engine/Core/Transform.cpp | 20 +++ src/Engine/Editor/EditorSystem.cpp | 86 +++++++++--- src/Engine/Rendering/RenderSystem.cpp | 9 +- src/Game/Systems/PlayerMovementSystem.cpp | 52 +++++++- src/Game/Systems/PlayerSpawnSystem.cpp | 8 ++ 24 files changed, 499 insertions(+), 176 deletions(-) create mode 100644 include/Engine/Editor/EditorCameraInputController.h delete mode 100644 include/Engine/Rendering/DebugCameraInputController.h create mode 100644 resources/Schema/Entities/CollidableCube.xml diff --git a/assets b/assets index 6ffb46e1..2a800ea9 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6ffb46e155c8f013241cd1507098c94900ec2448 +Subproject commit 2a800ea92b323646432c65217d55aab6750d5a72 diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index 3ba4e087..d0e5e31f 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -25,6 +25,7 @@ struct EntityWrapper bool HasComponent(const std::string& componentName); EntityWrapper Parent(); + EntityWrapper FirstChildByName(const std::string& name); bool Valid(); ComponentWrapper operator[](const char* componentName); diff --git a/include/Engine/Core/Transform.h b/include/Engine/Core/Transform.h index 474a7bdb..3b0811c9 100644 --- a/include/Engine/Core/Transform.h +++ b/include/Engine/Core/Transform.h @@ -3,13 +3,18 @@ #include "../GLM.h" #include "World.h" +#include "EntityWrapper.h" namespace Transform { +glm::vec3 AbsolutePosition(EntityWrapper entity); glm::vec3 AbsolutePosition(World* world, EntityID entity); +glm::quat AbsoluteOrientation(EntityWrapper entity); glm::quat AbsoluteOrientation(World* world, EntityID entity); +glm::vec3 AbsoluteScale(EntityWrapper entity); glm::vec3 AbsoluteScale(World* world, EntityID entity); +glm::mat4 ModelMatrix(EntityWrapper entity); glm::mat4 ModelMatrix(EntityID entity, World* world); } diff --git a/include/Engine/Editor/EditorCameraInputController.h b/include/Engine/Editor/EditorCameraInputController.h new file mode 100644 index 00000000..c12113c7 --- /dev/null +++ b/include/Engine/Editor/EditorCameraInputController.h @@ -0,0 +1,98 @@ +#ifndef EditorCameraInputController_h__ +#define EditorCameraInputController_h__ + +#include +#include "../Input/FirstPersonInputController.h" +#include "../Core/EMousePress.h" +#include "../Core/EMouseRelease.h" +#include "../Core/EMouseScroll.h" +#include "../Core/ConfigFile.h" + +template +class EditorCameraInputController : public FirstPersonInputController +{ +public: + EditorCameraInputController(EventBroker* eventBroker, unsigned int playerID) + : FirstPersonInputController(eventBroker, playerID) + { + EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorCameraInputController::OnMousePress); + EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &EditorCameraInputController::OnMouseRelease); + EVENT_SUBSCRIBE_MEMBER(m_EMouseScroll, &EditorCameraInputController::OnMouseScroll); + + m_Config = ResourceManager::Load("Config.ini"); + m_SpeedMultiplier = m_Config->Get("Editor.CameraSpeed", 3.f); + } + + virtual const glm::vec3 Movement() const override + { + return m_Movement * m_SpeedMultiplier; + } + + virtual bool OnCommand(const Events::InputCommand& e) override + { + ImGuiIO& io = ImGui::GetIO(); + if (glm::abs(e.Value) > 0 && (io.WantCaptureKeyboard || io.WantCaptureMouse)) { + return false; + } + + if (e.Command == "Jump") { + if (e.Value > 0) { + m_Movement.y = glm::max(e.Value, 1.f); + } else { + m_Movement.y = 0.f; + } + } + + if (e.Command == "Crouch") { + if (e.Value > 0) { + m_Movement.y = glm::min(-e.Value, -1.f); + } else { + m_Movement.y = 0.f; + } + } + + if (e.Command == "Sprint") { + if (e.Value > 0) { + m_SpeedMultiplier *= 2.f; + } else { + m_SpeedMultiplier /= 2.f; + } + } + + return FirstPersonInputController::OnCommand(e); + } + +protected: + ConfigFile* m_Config; + float m_SpeedMultiplier = 1.f; + + EventRelay m_EMousePress; + bool OnMousePress(const Events::MousePress& e) + { + if (e.Button == GLFW_MOUSE_BUTTON_2) { + ImGuiIO& io = ImGui::GetIO(); + if (!io.WantCaptureMouse) { + LockMouse(); + } + } + return true; + } + EventRelay m_EMouseRelease; + bool OnMouseRelease(const Events::MouseRelease& e) + { + if (e.Button == GLFW_MOUSE_BUTTON_2) { + UnlockMouse(); + } + return true; + } + EventRelay m_EMouseScroll; + bool OnMouseScroll(const Events::MouseScroll& e) + { + m_SpeedMultiplier += e.DeltaY * (0.1f * m_SpeedMultiplier); + m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier); + m_Config->SaveToDisk(); + return true; + } +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index b354ddf3..2db24ba3 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -1,7 +1,6 @@ #include "../Core/System.h" #include "../Rendering/IRenderer.h" #include "../Rendering/Camera.h" -#include "../Rendering/DebugCameraInputController.h" #include "../Rendering/ESetCamera.h" #include "../Core/World.h" #include "../Core/SystemPipeline.h" @@ -10,8 +9,10 @@ #include "../Core/EntityFileParser.h" #include "../Core/EntityFileWriter.h" #include "../Core/EMousePress.h" +#include "../Input/EInputCommand.h" #include "EditorGUI.h" #include "EditorStats.h" +#include "EditorCameraInputController.h" class EditorSystem : public ImpureSystem { @@ -21,18 +22,24 @@ public: void Update(double dt); + void Enable(); + void Disable(); + private: IRenderer* m_Renderer; RenderFrame* m_RenderFrame; World* m_EditorWorld; SystemPipeline* m_EditorWorldSystemPipeline; - Camera* m_EditorCamera; - EntityWrapper m_Camera = EntityWrapper::Invalid; - DebugCameraInputController* m_DebugCameraInputController; + //Camera* m_EditorCamera; + EntityWrapper m_EditorCamera = EntityWrapper::Invalid; + EntityWrapper m_ActualCamera = EntityWrapper::Invalid; + EditorCameraInputController* m_EditorCameraInputController; EditorGUI* m_EditorGUI; EditorStats* m_EditorStats; // State + double m_LastTime = 0.f; + bool m_Enabled = true; EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate; EntityWrapper m_Widget = EntityWrapper::Invalid; EntityWrapper m_CurrentSelection = EntityWrapper::Invalid; @@ -56,4 +63,8 @@ private: bool OnMousePress(const Events::MousePress& e); EventRelay m_EWidgetDelta; bool OnWidgetDelta(const Events::WidgetDelta& e); + EventRelay m_EInputCommand; + bool OnInputCommand(const Events::InputCommand& e); + EventRelay m_ESetCamera; + bool OnSetCamera(const Events::SetCamera& e); }; \ No newline at end of file diff --git a/include/Engine/Input/EInputCommand.h b/include/Engine/Input/EInputCommand.h index 9ec897d3..1e150786 100644 --- a/include/Engine/Input/EInputCommand.h +++ b/include/Engine/Input/EInputCommand.h @@ -9,7 +9,7 @@ namespace Events struct InputCommand : Event { /** Numerical ID of the player. */ - unsigned int PlayerID; + int PlayerID; /** The command that was sent. */ std::string Command; /** The value of the command. */ diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index d8584494..91445534 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -9,7 +9,7 @@ template class FirstPersonInputController : public InputController { public: - FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID) + FirstPersonInputController(EventBroker* eventBroker, int playerID) : InputController(eventBroker) , m_PlayerID(playerID) { @@ -17,7 +17,8 @@ public: EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); } - const glm::quat Orientation() const { return m_Orientation; } + virtual const glm::vec3 Movement() const { return m_Movement; } + virtual const glm::vec3 Orientation() const { return m_Orientation; } void LockMouse() { @@ -42,24 +43,44 @@ public: 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)); + m_Orientation.x += -val; + m_Orientation.x = glm::clamp(m_Orientation.x, -glm::half_pi(), glm::half_pi()); + //m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1.f, 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; + m_Orientation.y += -val; + //m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1.f, 0)) * m_Orientation; return true; } } + if (e.Command == "Forward" || e.Command == "Right") { + if (e.Command == "Forward") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.z = -val; + return true; + } + if (e.Command == "Right") { + float val = glm::clamp(e.Value, -1.f, 1.f); + m_Movement.x = val; + return true; + } + if (glm::length2(m_Movement) > 0) { + m_Movement = glm::normalize(m_Movement); + } + } + return false; } protected: - const unsigned int m_PlayerID; - glm::quat m_Orientation; + const int m_PlayerID; bool m_MouseLocked = false; + glm::vec3 m_Orientation; + glm::vec3 m_Movement; EventRelay m_ELockMouse; bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; } diff --git a/include/Engine/Rendering/DebugCameraInputController.h b/include/Engine/Rendering/DebugCameraInputController.h deleted file mode 100644 index 5ce85b3f..00000000 --- a/include/Engine/Rendering/DebugCameraInputController.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef DebugCameraInputController_h__ -#define DebugCameraInputController_h__ - -#include -#include "../Input/FirstPersonInputController.h" -#include "../Core/EMousePress.h" -#include "../Core/EMouseRelease.h" - -template -class DebugCameraInputController : public FirstPersonInputController -{ -public: - DebugCameraInputController(EventBroker* eventBroker, unsigned int playerID) - : FirstPersonInputController(eventBroker, playerID) - { - EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &DebugCameraInputController::OnMousePress); - EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &DebugCameraInputController::OnMouseRelease); - } - - void SetPosition(const glm::vec3 position) { m_Position = position; } - void SetOrientation(const glm::quat orientation) { m_Orientation = orientation; } - - const glm::vec3 Position() const { return m_Position; } - void SetBaseSpeed(float speed) { m_BaseSpeed = speed; } - - virtual bool OnCommand(const Events::InputCommand& e) override - { - ImGuiIO& io = ImGui::GetIO(); - - if (!io.WantCaptureKeyboard) { - 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; - } - if (e.Command == "Sprint") { - if (e.Value > 0.f) { - m_Speed = m_BaseSpeed * 2.f * (e.Value); - } else { - m_Speed = m_BaseSpeed; - } - } - } - - return FirstPersonInputController::OnCommand(e); - } - - void Update(double dt) - { - if (glm::length2(m_Velocity) > 0) { - m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_Speed * (float)dt); - } - } - -protected: - glm::vec3 m_Position = glm::vec3(0, 0, 0); - glm::vec3 m_Velocity = glm::vec3(0, 0, 0); - float m_BaseSpeed = 2.0f; - float m_Speed = m_BaseSpeed; - EventRelay m_EMousePress; - bool OnMousePress(const Events::MousePress& e) - { - if (e.Button == GLFW_MOUSE_BUTTON_2) { - ImGuiIO& io = ImGui::GetIO(); - if (!io.WantCaptureMouse) { - LockMouse(); - } - } - return true; - } - EventRelay m_EMouseRelease; - bool OnMouseRelease(const Events::MouseRelease& e) - { - if (e.Button == GLFW_MOUSE_BUTTON_2) { - UnlockMouse(); - } - return true; - } -}; - -#endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index 003e308e..04c394a9 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -15,7 +15,6 @@ #include "Renderer.h" #include "PointLightJob.h" #include "../Core/Transform.h" -#include "DebugCameraInputController.h" class RenderSystem : public ImpureSystem { diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index 1be61bdd..f5b6539b 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -1,14 +1,22 @@ #include "Common.h" #include "GLM.h" #include "Core/System.h" +#include "Events/EPlayerSpawned.h" +#include "Input/FirstPersonInputController.h" -class PlayerMovementSystem : public PureSystem +class PlayerMovementSystem : public ImpureSystem, PureSystem { public: - PlayerMovementSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) - , PureSystem("Player") - { } + PlayerMovementSystem(World* world, EventBroker* eventBroker); + ~PlayerMovementSystem(); + virtual void Update(double dt) override; virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt); + +private: + // State + std::unordered_map*> m_PlayerInputControllers; + + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned& e); }; \ No newline at end of file diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index 69014f65..9e9ce0be 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -3,6 +3,7 @@ #include "Systems/SpawnerSystem.h" #include "Events/ESpawnerSpawn.h" #include "Events/EPlayerSpawned.h" +#include "Rendering/ESetCamera.h" class PlayerSpawnSystem : public ImpureSystem { diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index fb490ec8..7e7dc08c 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -1,11 +1,13 @@ [Debug] LogLevel=1 LoadMap= -EditorEnabled=false ; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation. ; if false -> Use pool allocation. DisableMemoryPool=false +[Editor] +CameraSpeed=3 + [Video] Fullscreen=false VSYNC=false diff --git a/resources/Schema/Components/Player.xml b/resources/Schema/Components/Player.xml index caefd6e6..a9ecc6be 100644 --- a/resources/Schema/Components/Player.xml +++ b/resources/Schema/Components/Player.xml @@ -1,8 +1,4 @@ - - false - false - false - false + 0.2 \ No newline at end of file diff --git a/resources/Schema/Components/Player.xsd b/resources/Schema/Components/Player.xsd index 1a315a35..89c4a398 100644 --- a/resources/Schema/Components/Player.xsd +++ b/resources/Schema/Components/Player.xsd @@ -9,11 +9,7 @@ - - - - - + diff --git a/resources/Schema/Entities/CollidableCube.xml b/resources/Schema/Entities/CollidableCube.xml new file mode 100644 index 00000000..ebba54be --- /dev/null +++ b/resources/Schema/Entities/CollidableCube.xml @@ -0,0 +1,15 @@ + + + + + + + + Models/Core/UnitCube.obj + + + + + + + diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 93b4d374..9ea1ae68 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -6,14 +6,7 @@ - - - - - - - - + @@ -22,46 +15,116 @@ - - + + - + - - - - - - - - Models/Assault.obj - - - + + + Schema/Entities/Player.xml + + + + + + - + + + + + + + + + Models/Assault.obj + + + + + + + + + + + + + Models/Assault.obj + + + + + + + + + + + + + + + Models/DirectionalLightWidget.obj + + + + - + + + + Models/Test/ObstacleCourse.obj + + + + + + - - - Models/Core/UnitCube.obj - - - - + + + + + + + + + + + + Models/Core/UnitCube.obj + + + + + + + + + + + + + + Models/Core/UnitCube.obj + + + + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 6c3b39c3..087b1f7e 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -2,17 +2,60 @@ - - + + + + - - Models/Core/UnitSphere.obj - - - - + + + 3 + + + + + - + + + + + + Models/Camera.obj + false + + + + + + + + + + + + + Models/Camera.obj + + + + + + + + + + + + Models/Assault.obj + + + + + + + + diff --git a/resources/Schema/Types.xsd b/resources/Schema/Types.xsd index fb584c64..8d9bf289 100644 --- a/resources/Schema/Types.xsd +++ b/resources/Schema/Types.xsd @@ -16,6 +16,9 @@ + + + diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 98b9c7d4..6177d91d 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -17,6 +17,22 @@ EntityWrapper EntityWrapper::Parent() } } +EntityWrapper EntityWrapper::FirstChildByName(const std::string& name) +{ + auto itPair = this->World->GetChildren(this->ID); + if (itPair.first == itPair.second) { + return EntityWrapper::Invalid; + } + + for (auto it = itPair.first; it != itPair.second; ++it) { + if (this->World->GetName(it->second) == name) { + return EntityWrapper(this->World, it->second); + } + } + + return EntityWrapper::Invalid; +} + bool EntityWrapper::Valid() { if (this->World == nullptr) { diff --git a/src/Engine/Core/Transform.cpp b/src/Engine/Core/Transform.cpp index cbc405a3..c9869014 100644 --- a/src/Engine/Core/Transform.cpp +++ b/src/Engine/Core/Transform.cpp @@ -1,5 +1,10 @@ #include "Core/Transform.h" +glm::vec3 Transform::AbsolutePosition(EntityWrapper entity) +{ + return AbsolutePosition(entity.World, entity.ID); +} + glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity) { glm::vec3 position; @@ -14,6 +19,11 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity) return position; } +glm::quat Transform::AbsoluteOrientation(EntityWrapper entity) +{ + return AbsoluteOrientation(entity.World, entity.ID); +} + glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity) { glm::quat orientation; @@ -27,6 +37,11 @@ glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity) return orientation; } +glm::vec3 Transform::AbsoluteScale(EntityWrapper entity) +{ + return AbsoluteScale(entity.World, entity.ID); +} + glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity) { glm::vec3 scale(1.f); @@ -40,6 +55,11 @@ glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity) return scale; } +glm::mat4 Transform::ModelMatrix(EntityWrapper entity) +{ + return ModelMatrix(entity.ID, entity.World); +} + glm::mat4 Transform::ModelMatrix(EntityID entity, World* world) { glm::vec3 position = Transform::AbsolutePosition(world, entity); diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 35b8a361..a357a542 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -14,10 +14,11 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re m_EditorWorldSystemPipeline->AddSystem(0, m_Renderer); m_EditorWorldSystemPipeline->AddSystem(1, m_Renderer, m_RenderFrame); - m_Camera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml"); - m_EditorWorld->AttachComponent(m_Camera.ID, "Transform"); - m_EditorWorld->AttachComponent(m_Camera.ID, "Camera"); - m_DebugCameraInputController = new DebugCameraInputController(m_EventBroker, -1); + m_EditorCamera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml"); + m_ActualCamera = m_EditorCamera; + m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform"); + m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); + m_EditorCameraInputController = new EditorCameraInputController(m_EventBroker, -1); m_EditorGUI = new EditorGUI(m_World, m_EventBroker); m_EditorGUI->SetEntitySelectedCallback(std::bind(&EditorSystem::OnEntitySelected, this, std::placeholders::_1)); @@ -33,38 +34,66 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress); EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &EditorSystem::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorSystem::OnSetCamera); m_EditorStats = new EditorStats(); - Events::SetCamera e; - e.CameraEntity = m_Camera; - m_EventBroker->Publish(e); + if (m_Enabled) { + Enable(); + } } EditorSystem::~EditorSystem() { delete m_EditorStats; delete m_EditorGUI; - delete m_DebugCameraInputController; + delete m_EditorCameraInputController; delete m_EditorWorldSystemPipeline; delete m_EditorWorld; } void EditorSystem::Update(double dt) { - m_EventBroker->Process(); - m_EditorGUI->Draw(); - m_EditorStats->Draw(dt); + double now = glfwGetTime(); + double actualDelta = now - m_LastTime; + m_LastTime = now; - if (m_CurrentSelection.Valid() && m_Widget.Valid()) { - (glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID); + if (m_Enabled) { + m_EventBroker->Process(); + m_EditorGUI->Draw(); + m_EditorStats->Draw(actualDelta); + + if (m_CurrentSelection.Valid() && m_Widget.Valid()) { + (glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID); + } + + m_EditorWorldSystemPipeline->Update(actualDelta); + + ComponentWrapper& cameraTransform = m_EditorCamera["Transform"]; + glm::vec3& ori = cameraTransform["Orientation"]; + ori.x = m_EditorCameraInputController->Orientation().x; + ori.y = m_EditorCameraInputController->Orientation().y; + glm::vec3& pos = cameraTransform["Position"]; + pos += m_EditorCameraInputController->Movement() * glm::inverse(glm::quat(ori)) * (float)actualDelta; } +} - m_EditorWorldSystemPipeline->Update(dt); +void EditorSystem::Enable() +{ + Events::SetCamera e; + e.CameraEntity = m_EditorCamera; + m_EventBroker->Publish(e); + (glm::vec3&)m_EditorCamera["Transform"]["Position"] = Transform::AbsolutePosition(m_ActualCamera); + m_Enabled = true; +} - m_DebugCameraInputController->Update(dt); - m_Camera["Transform"]["Position"] = m_DebugCameraInputController->Position(); - m_Camera["Transform"]["Orientation"] = glm::eulerAngles(m_DebugCameraInputController->Orientation()); +void EditorSystem::Disable() +{ + Events::SetCamera e; + e.CameraEntity = m_ActualCamera; + m_EventBroker->Publish(e); + m_Enabled = false; } void EditorSystem::OnEntitySelected(EntityWrapper entity) @@ -148,6 +177,29 @@ bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e) return true; } +bool EditorSystem::OnInputCommand(const Events::InputCommand& e) +{ + if (e.Command == "ToggleEditor" && e.Value > 0) { + if (m_Enabled) { + Disable(); + } else { + Enable(); + } + } + return true; +} + +bool EditorSystem::OnSetCamera(const Events::SetCamera& e) +{ + if (m_Enabled && e.CameraEntity != m_EditorCamera) { + m_ActualCamera = e.CameraEntity; + Events::SetCamera e2; + e2.CameraEntity = m_EditorCamera; + m_EventBroker->Publish(e2); + } + return true; +} + EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem::path filePath) { if (parent.World == nullptr) { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 80b6696c..6eedc34c 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -119,11 +119,12 @@ void RenderSystem::Update(double dt) { m_EventBroker->Process(); - if (m_CurrentCamera) { - ComponentWrapper cameraTransform = m_CurrentCamera["Transform"]; - m_Camera->SetPosition(cameraTransform["Position"]); - m_Camera->SetOrientation(glm::quat((const glm::vec3&)cameraTransform["Orientation"])); + // Update the current camera used for rendering + if (m_CurrentCamera.Valid()) { + m_Camera->SetPosition(Transform::AbsolutePosition(m_CurrentCamera)); + m_Camera->SetOrientation(Transform::AbsoluteOrientation(m_CurrentCamera)); } + //Only supports opaque geometry atm RenderScene scene; diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index e14cd146..351acad5 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -1,5 +1,45 @@ #include "Systems/PlayerMovementSystem.h" +PlayerMovementSystem::PlayerMovementSystem(World* world, EventBroker* eventBroker) + : System(world, eventBroker) + , PureSystem("Player") +{ + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned); +} + +PlayerMovementSystem::~PlayerMovementSystem() +{ + for (auto& kv : m_PlayerInputControllers) { + delete kv.second; + } +} + +void PlayerMovementSystem::Update(double dt) +{ + for (auto& kv : m_PlayerInputControllers) { + EntityWrapper player = kv.first; + auto& controller = kv.second; + + if (!player.Valid()) { + continue; + } + + EntityWrapper cameraEntity = player.FirstChildByName("Camera"); + if (cameraEntity.Valid()) { + glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"]; + cameraOrientation.x = controller->Orientation().x; + } + + ComponentWrapper& cTransform = player["Transform"]; + glm::vec3& ori = cTransform["Orientation"]; + ori.y = controller->Orientation().y; + + glm::vec3& pos = cTransform["Position"]; + pos += controller->Movement() * glm::inverse(glm::quat(ori)) * (float)player["Player"]["MovementSpeed"] * (float)dt; + + } +} + void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) { ComponentWrapper& cTransform = entity["Transform"]; @@ -10,9 +50,17 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp glm::vec3& velocity = cPhysics["Velocity"]; if (cPhysics["Gravity"]) { - velocity.y -= 9.82 * dt; + velocity.y -= 9.82f * (float)dt; } glm::vec3& position = cTransform["Position"]; position += velocity * (float)dt; -} \ No newline at end of file +} + +bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e) +{ + // When a player spawns, create an input controller for them + m_PlayerInputControllers[e.Player] = new FirstPersonInputController(m_EventBroker, e.PlayerID); + + return true; +} diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 11be0486..0763fa9c 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -38,6 +38,14 @@ void PlayerSpawnSystem::Update(double dt) e.Player = player; e.Spawner = spawner; m_EventBroker->Publish(e); + + // Set the camera to the correct entity + EntityWrapper cameraEntity = player.FirstChildByName("Camera"); + if (cameraEntity.Valid()) { + Events::SetCamera e; + e.CameraEntity = cameraEntity; + m_EventBroker->Publish(e); + } } } m_SpawnRequests.clear();