From 522679b14cffcd0ef3a1ce43a51570e22f8d6932 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 20:13:45 +0100 Subject: [PATCH 01/12] Added BlendEquation and BlendFunc to RenderState, and cleaned it up A LOT --- include/Engine/Rendering/RenderState.h | 18 ++- src/Engine/Rendering/DrawScenePassState.cpp | 2 +- src/Engine/Rendering/PickingPassState.cpp | 2 +- src/Engine/Rendering/RenderState.cpp | 145 +++++++++----------- 4 files changed, 80 insertions(+), 87 deletions(-) diff --git a/include/Engine/Rendering/RenderState.h b/include/Engine/Rendering/RenderState.h index e7ba2f80..c6eb8775 100644 --- a/include/Engine/Rendering/RenderState.h +++ b/include/Engine/Rendering/RenderState.h @@ -1,6 +1,7 @@ #ifndef RenderState_h__ #define RenderState_h__ +#include #include "../Common.h" #include "../OpenGL.h" #include "../GLM.h" @@ -8,16 +9,19 @@ class RenderState { public: - RenderState(); + RenderState() = default; ~RenderState(); - bool Enable(GLenum GLEnable); - bool CullFace(GLenum GlFaceToCull); + + bool Enable(GLenum cap); + bool Disable(GLenum cap); + bool CullFace(GLenum mode); bool ClearColor(glm::vec4 color); bool Clear(GLbitfield mask); - bool BindBuffer(GLint buffer); + bool BindFramebuffer(GLint framebuffer); + bool BlendEquation(GLenum mode); + bool BlendFunc(GLenum sfactor, GLenum dfactor); + private: - std::vector m_Enables; - float m_preClearColor[4]; - int m_preBuffer; + std::vector> m_ResetFunctions; }; #endif \ No newline at end of file diff --git a/src/Engine/Rendering/DrawScenePassState.cpp b/src/Engine/Rendering/DrawScenePassState.cpp index 59654775..9e7497a3 100644 --- a/src/Engine/Rendering/DrawScenePassState.cpp +++ b/src/Engine/Rendering/DrawScenePassState.cpp @@ -4,7 +4,7 @@ DrawScenePassState::DrawScenePassState() { GLERROR("---"); - BindBuffer(0); + BindFramebuffer(0); GLERROR("---"); Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); diff --git a/src/Engine/Rendering/PickingPassState.cpp b/src/Engine/Rendering/PickingPassState.cpp index a52fa546..1e28ea66 100644 --- a/src/Engine/Rendering/PickingPassState.cpp +++ b/src/Engine/Rendering/PickingPassState.cpp @@ -4,7 +4,7 @@ PickingPassState::PickingPassState(GLuint frameBuffer) { GLERROR("---2"); - BindBuffer(frameBuffer); + BindFramebuffer(frameBuffer); GLERROR("---3"); Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp index 34c88ece..631e7ff5 100644 --- a/src/Engine/Rendering/RenderState.cpp +++ b/src/Engine/Rendering/RenderState.cpp @@ -1,110 +1,99 @@ #include "Rendering/RenderState.h" -RenderState::RenderState() +bool RenderState::Enable(GLenum cap) { - -} - -bool RenderState::Enable(GLenum GLEnable) -{ - if(glIsEnabled(GLEnable)) - { + if (glIsEnabled(cap)) { return false; } - m_Enables.push_back(GLEnable); - glEnable(GLEnable); - if (GLERROR("RenderState::Enable")) - { - return false; - } - return true; + m_ResetFunctions.push_back(std::bind(glDisable, cap)); + glEnable(cap); + return !GLERROR("RenderState::Enable"); } -bool RenderState::CullFace(GLenum GLCullFace) +bool RenderState::Disable(GLenum cap) { - if(!glIsEnabled(GL_CULL_FACE)) - { + if (!glIsEnabled(cap)) { + return false; + } + m_ResetFunctions.push_back(std::bind(glEnable, cap)); + glDisable(cap); + return !GLERROR("RenderState::Disable"); +} + +bool RenderState::CullFace(GLenum mode) +{ + if (!glIsEnabled(GL_CULL_FACE)) { LOG_ERROR("Setting GL_CULL_FACE without enabling it."); return false; } - GLint a; - glGetIntegerv(GL_CULL_FACE_MODE, &a); - if(a != GL_BACK) - { - //LOG_INFO("Setting Cullface to back, unessesary since this is already default."); - glCullFace(GLCullFace); - } - if (GLERROR("RenderState::CullFace")) - { - return false; - } - return true; + GLint original; + glGetIntegerv(GL_CULL_FACE_MODE, &original); + m_ResetFunctions.push_back(std::bind(glCullFace, original)); + glCullFace(mode); + return !GLERROR("RenderState::CullFace"); } bool RenderState::ClearColor(glm::vec4 color) { - glGetFloatv(GL_COLOR_CLEAR_VALUE, &m_preClearColor[0]); + GLfloat original[4]; + glGetFloatv(GL_COLOR_CLEAR_VALUE, &original[0]); + m_ResetFunctions.push_back(std::bind(glClearColor, original[0], original[1], original[2], original[3])); glClearColor(color.r, color.g, color.b, color.a); - if (GLERROR("RenderState::ClearColor")) { - return false; - } - return true; + return !GLERROR("RenderState::ClearColor"); } bool RenderState::Clear(GLbitfield mask) { glClear(mask); - if (GLERROR("RenderState::Clear")) { - return false; - } - return true; + return !GLERROR("RenderState::Clear"); } -bool RenderState::BindBuffer(GLint buffer) +bool RenderState::BindFramebuffer(GLint framebuffer) { - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_preBuffer); - if (buffer == m_preBuffer) - { - return true; - } - glBindFramebuffer(GL_FRAMEBUFFER, buffer); - if (GLERROR("RenderState::BindBuffer")) - { - printf("BufferID: %i\npreBufferID: %i\n", buffer, m_preBuffer); - return false; - } - return true; + GLint originalRead; + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &originalRead); + GLint originalDraw; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &originalDraw); + m_ResetFunctions.push_back([originalRead, originalDraw]() { + glBindFramebuffer(GL_READ_FRAMEBUFFER, originalRead); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, originalDraw); + }); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + return !GLERROR("RenderState::BindBuffer"); +} + + +bool RenderState::BlendEquation(GLenum mode) +{ + GLint originalRGB; + glGetIntegerv(GL_BLEND_EQUATION_RGB, &originalRGB); + GLint originalAlpha; + glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &originalAlpha); + m_ResetFunctions.push_back(std::bind(glBlendEquationSeparate, originalRGB, originalAlpha)); + glBlendEquation(mode); + return !GLERROR("RenderState::BlendEquation"); +} + +bool RenderState::BlendFunc(GLenum sfactor, GLenum dfactor) +{ + GLint originalSrcRGB; + glGetIntegerv(GL_BLEND_SRC_RGB, &originalSrcRGB); + GLint originalSrcAlpha; + glGetIntegerv(GL_BLEND_SRC_ALPHA, &originalSrcAlpha); + GLint originalDestRGB; + glGetIntegerv(GL_BLEND_DST_RGB, &originalDestRGB); + GLint originalDestAlpha; + glGetIntegerv(GL_BLEND_DST_ALPHA, &originalDestAlpha); + m_ResetFunctions.push_back(std::bind(glBlendFuncSeparate, originalSrcRGB, originalSrcAlpha, originalDestRGB, originalDestAlpha)); + glBlendFunc(sfactor, dfactor); + return !GLERROR("RenderState::BlendFunc"); } RenderState::~RenderState() { - GLERROR("RenderState::~RenderState Pre"); - GLint n_buffer = -1; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &n_buffer); - - //Set cullface to default - if (glIsEnabled(GL_CULL_FACE)) { - glCullFace(GL_BACK); + for (auto& f : m_ResetFunctions) { + f(); } - GLERROR("RenderState::~RenderState glCullFace"); - - //Set color to default - glClearColor(m_preClearColor[0], m_preClearColor[1], m_preClearColor[2], m_preClearColor[3]); - GLERROR("RenderState::~RenderState glClearColor"); - - //Disable Enables - for (auto i : m_Enables) - { - glDisable(i); - } - GLERROR("RenderState::~RenderState glDisable"); - - if(m_preBuffer != 0) - { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - m_Enables.clear(); - GLERROR("RenderState::~RenderState glBindFramebuffer"); } From 422e6f5264f028645cc638ecaccda192d5f18eb5 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 20:25:16 +0100 Subject: [PATCH 02/12] Created a RenderState for ImGuiRenderPass --- include/Engine/Rendering/ImGuiRenderPass.h | 17 ++++++++++ src/Engine/Rendering/ImGuiRenderPass.cpp | 39 ++-------------------- 2 files changed, 19 insertions(+), 37 deletions(-) diff --git a/include/Engine/Rendering/ImGuiRenderPass.h b/include/Engine/Rendering/ImGuiRenderPass.h index 1ca443e9..e9d359ba 100644 --- a/include/Engine/Rendering/ImGuiRenderPass.h +++ b/include/Engine/Rendering/ImGuiRenderPass.h @@ -1,6 +1,7 @@ #include #include "../OpenGL.h" #include "IRenderer.h" +#include "RenderState.h" #include "../Core/EventBroker.h" #include "../Core/EMousePress.h" #include "../Core/EMouseRelease.h" @@ -10,6 +11,22 @@ #include "../Core/EKeyUp.h" #include "../Core/EKeyboardChar.h" +class ImGuiRenderState : public RenderState +{ +public: + ImGuiRenderState() + : RenderState() + { + BindFramebuffer(0); + Enable(GL_BLEND); + BlendEquation(GL_FUNC_ADD); + BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + Disable(GL_CULL_FACE); + Disable(GL_DEPTH_TEST); + Enable(GL_SCISSOR_TEST); + } +}; + class ImGuiRenderPass { public: diff --git a/src/Engine/Rendering/ImGuiRenderPass.cpp b/src/Engine/Rendering/ImGuiRenderPass.cpp index f2147ea8..96f987d9 100644 --- a/src/Engine/Rendering/ImGuiRenderPass.cpp +++ b/src/Engine/Rendering/ImGuiRenderPass.cpp @@ -69,29 +69,8 @@ void ImGuiRenderPass::Draw() ImDrawData* draw_data = ImGui::GetDrawData(); - // Backup GL state - GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); - GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); - GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - GLint last_blend_src; glGetIntegerv(GL_BLEND_SRC, &last_blend_src); - GLint last_blend_dst; glGetIntegerv(GL_BLEND_DST, &last_blend_dst); - GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); - GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - GLboolean last_enable_blend = glIsEnabled(GL_BLEND); - GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); - GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); - GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); + // Set up render state + ImGuiRenderState state; glActiveTexture(GL_TEXTURE0); // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) @@ -134,20 +113,6 @@ void ImGuiRenderPass::Draw() } } - // Restore modified GL state - glUseProgram(last_program); - glBindTexture(GL_TEXTURE_2D, last_texture); - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); - glBindVertexArray(last_vertex_array); - glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); - glBlendFunc(last_blend_src, last_blend_dst); - if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); - if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); - if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); - if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); - // Start next frame newFrame(); } From c296c4eb3b47bc12492e2e70cae7283859ce9b82 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 21:30:43 +0100 Subject: [PATCH 03/12] Fixed picking pass... again... --- src/Engine/Rendering/PickingPass.cpp | 30 +++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index d45c0322..148b272c 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -48,26 +48,31 @@ void PickingPass::Draw(RenderQueueCollection& rq) m_PickingColorsToEntity.clear(); PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle()); - int r = 1; + int r = 0; int g = 0; //TODO: Render: Add code for more jobs than modeljobs. GLuint ShaderHandle = m_PickingProgram->GetHandle(); m_PickingProgram->Bind(); + std::map entityColors; + for (auto &job : rq.Forward) { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { - //--------------- - //TODO: Renderer: IMPORTANT: Fixa detta så det inte loopar igenom listan varje frame. - //--------------- int pickColor[2] = { r, g }; - for (auto i : m_PickingColorsToEntity) { - if (modelJob->Entity == i.second) { - pickColor[0] = i.first.x; - pickColor[1] = i.first.y; - r -= 1; + auto color = entityColors.find(modelJob->Entity); + if (color != entityColors.end()) { + pickColor[0] = color->second[0]; + pickColor[1] = color->second[1]; + } else { + entityColors[modelJob->Entity] = glm::vec2(pickColor[0], pickColor[1]); + if (r + 10 > 255) { + r = 0; + g += 1; + } else { + r += 1; } } m_PickingColorsToEntity[glm::vec2(pickColor[0], pickColor[1])] = modelJob->Entity; @@ -82,11 +87,6 @@ void PickingPass::Draw(RenderQueueCollection& rq) glBindVertexArray(modelJob->Model->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, nullptr, modelJob->StartIndex); - r += 1; - if (r > 255) { - r = 0; - g += 1; - } } } m_PickingBuffer.Unbind(); @@ -105,6 +105,8 @@ void PickingPass::Draw(RenderQueueCollection& rq) &m_PickingColorsToEntity); m_EventBroker->Publish(pickEvent); + + delete state; } void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const From 51dd627ae379d21ea211a84ceff98c8a4512e4d5 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 22:32:20 +0100 Subject: [PATCH 04/12] Added Fonts to deploy.bat --- tools/deploy.bat | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/deploy.bat b/tools/deploy.bat index 22d513e6..f629058c 100755 --- a/tools/deploy.bat +++ b/tools/deploy.bat @@ -11,6 +11,8 @@ RMDIR "%DeployLocation%\Textures" MKLINK "%DeployLocation%\Textures\" "assets\Textures\" /J RMDIR "%DeployLocation%\Audio" MKLINK "%DeployLocation%\Audio\" "assets\Audio\" /J +RMDIR "%DeployLocation%\Fonts" +MKLINK "%DeployLocation%\Fonts\" "assets\Fonts\" /J ECHO Deploying resources to %DeployLocation% :: Schemas From 322aedaf72832ba24a65c96d5a8f31ceed6de41a Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 15 Dec 2015 18:01:20 +0100 Subject: [PATCH 05/12] Basic transformation widgets --- assets | 2 +- include/Engine/Editor/EditorSystem.h | 37 +++- include/Engine/Rendering/EPicking.h | 3 + src/Engine/Editor/EditorSystem.cpp | 277 +++++++++++++++++++++++---- src/Engine/Rendering/Renderer.cpp | 4 +- src/Game/Game.cpp | 2 +- 6 files changed, 285 insertions(+), 40 deletions(-) diff --git a/assets b/assets index 95823e12..c5f67434 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 95823e122ab11135170d1d70ab2535ae1d332fdd +Subproject commit c5f674349a915ab1a2b4da632d87a9832d1f6fab diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index 92e237d1..be4cd608 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -2,34 +2,69 @@ #include #include "../Core/System.h" #include "../Core/EMousePress.h" +#include "../Core/EMouseRelease.h" +#include "../Core/EMouseMove.h" #include "../Core/ConfigFile.h" #include "../Input/EInputCommand.h" +#include "../Rendering/IRenderer.h" #include "../Rendering/EPicking.h" #include "../Rendering/RenderQueueFactory.h" class EditorSystem : public ImpureSystem { public: - EditorSystem(EventBroker* eventBroker); + EditorSystem(EventBroker* eventBroker, IRenderer* renderer); virtual void Update(World* world, double dt) override; private: + IRenderer* m_Renderer; + World* m_World = nullptr; + bool m_Enabled; bool m_Visible; std::vector m_PickingQueue; + + enum class WidgetMode + { + None, + Translate, + Rotate, + Scale + } m_WidgetMode = WidgetMode::None; + + enum class WidgetSpace + { + Local, + Global + } m_WidgetSpace = WidgetSpace::Global; + EntityID m_Widget = 0; + EntityID m_WidgetX = 0; + EntityID m_WidgetY = 0; + EntityID m_WidgetZ = 0; + EntityID m_WidgetOrigin = 0; + glm::vec3 m_WidgetCurrentAxis; + float m_WidgetPickingDepth = 0.f; + EntityID m_Selection = 0; EntityID m_LastSelection = 0; glm::vec3 m_Position; EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); + EventRelay m_EMouseRelease; + bool OnMouseRelease(const Events::MouseRelease& e); EventRelay m_EMousePress; bool OnMousePress(const Events::MousePress& e); + EventRelay m_EMouseMove; + bool OnMouseMove(const Events::MouseMove& e); EventRelay m_EPicking; bool OnPicking(const Events::Picking& e); + void updateWidget(); + void setWidgetMode(WidgetMode newMode); + void setWidgetSpace(WidgetSpace space); void drawUI(World* world, double dt); bool createDeleteButton(std::string componentType); }; \ No newline at end of file diff --git a/include/Engine/Rendering/EPicking.h b/include/Engine/Rendering/EPicking.h index 044a944b..85c4b629 100644 --- a/include/Engine/Rendering/EPicking.h +++ b/include/Engine/Rendering/EPicking.h @@ -34,6 +34,8 @@ public: EntityID Entity; //World position of the "pick" glm::vec3 Position; + // Depth + float Depth; }; PickData Pick(glm::vec2 screenCoord) const @@ -43,6 +45,7 @@ public: // Invert screen y coordinate screenCoord.y = Resolution.Height - screenCoord.y; ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer); + pickData.Depth = data.Depth; auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1])); if (it != PickingColorsToEntity->end()) { diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index a56ba79c..fbad2281 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -2,8 +2,9 @@ #define IMGUI_DEFINE_MATH_OPERATORS #include -EditorSystem::EditorSystem(EventBroker* eventBroker) +EditorSystem::EditorSystem(EventBroker* eventBroker, IRenderer* renderer) : ImpureSystem(eventBroker) + , m_Renderer(renderer) { auto config = ResourceManager::Load("Config.ini"); m_Enabled = config->Get("Debug.EditorEnabled", false); @@ -15,51 +16,52 @@ EditorSystem::EditorSystem(EventBroker* eventBroker) EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &EditorSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress); + EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &EditorSystem::OnMouseRelease); + EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &EditorSystem::OnMouseMove); EVENT_SUBSCRIBE_MEMBER(m_EPicking, &EditorSystem::OnPicking); } void EditorSystem::Update(World* world, double dt) { + m_World = world; + if (!m_Enabled) { return; } - if (m_Widget == 0) { - m_Widget = world->CreateEntity(); - world->AttachComponent(m_Widget, "Transform"); - auto& model = world->AttachComponent(m_Widget, "Model"); - model["Resource"] = "Models/TranslationWidget.obj"; - } - - if (m_Selection != m_LastSelection) { - - } - - auto& widgetModel = world->GetComponent(m_Widget, "Model"); - widgetModel["Visible"] = m_Visible; - if (m_Selection != 0) { - if (world->HasComponent(m_Selection, "Transform")) { - glm::vec3 pos = RenderQueueFactory::AbsolutePosition(world, m_Selection); - auto widgetTransform = world->GetComponent(m_Widget, "Transform"); - widgetTransform["Position"] = pos; - } else { - m_Selection = 0; - } - } - if (!m_Visible) { return; } + updateWidget(); + drawUI(world, dt); } - bool EditorSystem::OnInputCommand(const Events::InputCommand& e) { if (e.Command == "ToggleEditor" && e.Value > 0) { m_Visible = !m_Visible; } + + if (e.Command == "EditorToolMove" && e.Value > 0) { + setWidgetMode(WidgetMode::Translate); + } + if (e.Command == "EditorToolRotate" && e.Value > 0) { + setWidgetMode(WidgetMode::Rotate); + } + if (e.Command == "EditorToolScale" && e.Value > 0) { + setWidgetMode(WidgetMode::Scale); + } + + if (e.Command == "EditorToggleTransformSpace" && e.Value > 0) { + if (m_WidgetSpace == WidgetSpace::Global) { + setWidgetSpace(WidgetSpace::Local); + } else if (m_WidgetSpace == WidgetSpace::Local) { + setWidgetSpace(WidgetSpace::Global); + } + } + return true; } @@ -71,17 +73,216 @@ bool EditorSystem::OnMousePress(const Events::MousePress& e) return true; } +bool EditorSystem::OnMouseMove(const Events::MouseMove& e) +{ + if (m_Widget == 0) { + return false; + } + + auto widgetTransform = m_World->GetComponent(m_Widget, "Transform"); + glm::vec3 widgetOrientation = widgetTransform["Orientation"]; + + glm::quat totalOrientation = m_Renderer->Camera()->Orientation() * glm::inverse(glm::quat(widgetOrientation)); + + int width; + int height; + glfwGetFramebufferSize(m_Renderer->Window(), &width, &height); + Rectangle res(width, height); + + glm::vec2 delta2(res.Width / 2.f + e.DeltaX, res.Height / 2.f + -e.DeltaY); + glm::vec3 deltaWorld = ScreenCoords::ToWorldPos( + delta2, + m_WidgetPickingDepth, + res, + m_Renderer->Camera()->ProjectionMatrix(), + glm::toMat4(glm::inverse(totalOrientation)) + ); + glm::vec3 origin = ScreenCoords::ToWorldPos( + glm::vec2(res.Width / 2.f, res.Height / 2.f), + m_WidgetPickingDepth, + res, + m_Renderer->Camera()->ProjectionMatrix(), + glm::toMat4(glm::inverse(totalOrientation)) + ); + deltaWorld = deltaWorld - origin; + glm::vec3 movement = deltaWorld * m_WidgetCurrentAxis; + + if (glm::length2(m_WidgetCurrentAxis) > 0.f) { + auto widgetTransform = m_World->GetComponent(m_Widget, "Transform"); + if (m_WidgetMode == WidgetMode::Translate) { + if (m_WidgetSpace == WidgetSpace::Global) { + (glm::vec3&)m_World->GetComponent(m_Selection, "Transform")["Position"] += movement; + } else if (m_WidgetSpace == WidgetSpace::Local) { + auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); + (glm::vec3&)selectionTransform["Position"] += glm::quat((glm::vec3&)selectionTransform["Orientation"]) * movement; + } + } else if (m_WidgetMode == WidgetMode::Rotate) { + glm::vec3 finalMovement; + finalMovement.x = -deltaWorld.y * m_WidgetCurrentAxis.x; + finalMovement.y = deltaWorld.x * m_WidgetCurrentAxis.y; + finalMovement.z = deltaWorld.y * m_WidgetCurrentAxis.z; + glm::vec3& selectionOrientation = m_World->GetComponent(m_Selection, "Transform")["Orientation"]; + if (m_WidgetSpace == WidgetSpace::Global) { + glm::quat currentOrientation = glm::quat(selectionOrientation); + glm::quat deltaOrientation(finalMovement); + selectionOrientation = glm::eulerAngles(deltaOrientation * currentOrientation); // (currentOrientation * deltaOrientation) * glm::vec3(0, 0, -1); + } else if (m_WidgetSpace == WidgetSpace::Local) { + glm::quat currentOrientation(selectionOrientation); + glm::quat deltaOrientation(finalMovement); + selectionOrientation = glm::eulerAngles(currentOrientation * deltaOrientation); // (currentOrientation * deltaOrientation) * glm::vec3(0, 0, -1); + widgetTransform["Orientation"] = selectionOrientation; + } + } else if (m_WidgetMode == WidgetMode::Scale) { + glm::vec3& scaleX = m_World->GetComponent(m_WidgetX, "Transform")["Scale"]; + glm::vec3& scaleY = m_World->GetComponent(m_WidgetY, "Transform")["Scale"]; + glm::vec3& scaleZ = m_World->GetComponent(m_WidgetZ, "Transform")["Scale"]; + if (m_WidgetCurrentAxis.x > 0) { + scaleX.x += movement.x; + } + if (m_WidgetCurrentAxis.y > 0) { + scaleY.y += movement.y; + } + if (m_WidgetCurrentAxis.z > 0) { + scaleZ.z += movement.z; + } + if (m_WidgetCurrentAxis.x > 0 && m_WidgetCurrentAxis.y > 0 && m_WidgetCurrentAxis.z > 0) { + float max = glm::max(scaleX.x, glm::max(scaleY.y, scaleZ.z)); + (glm::vec3&)m_World->GetComponent(m_WidgetOrigin, "Transform")["Scale"] = glm::vec3(max); + } + (glm::vec3&)m_World->GetComponent(m_Selection, "Transform")["Scale"] += movement; + } + } + + return true; +} + +bool EditorSystem::OnMouseRelease(const Events::MouseRelease& e) +{ + if (glm::length2(m_WidgetCurrentAxis) > 0.f) { + m_WidgetCurrentAxis = glm::vec3(0.f); + //setWidgetMode(m_WidgetMode); + } + + return true; +} + bool EditorSystem::OnPicking(const Events::Picking& e) { for (auto& pos : m_PickingQueue) { auto result = e.Pick(pos); - LOG_INFO("Selected %i", result.Entity); - m_Selection = result.Entity; + EntityID entity = result.Entity; + if (glm::length2(m_WidgetCurrentAxis) > 0.f) { + } else { + LOG_INFO("Selected %i", entity); + if (entity != 0) { + EntityID parent = m_World->GetParent(entity); + if (parent == m_Widget) { + m_WidgetCurrentAxis = glm::vec3( + (entity == m_WidgetX) || (entity == m_WidgetOrigin), + (entity == m_WidgetY) || (entity == m_WidgetOrigin), + (entity == m_WidgetZ) || (entity == m_WidgetOrigin) + ); + m_WidgetPickingDepth = result.Depth; + + //auto widgetTransform = m_World->GetComponent(m_Widget, "Transform"); + //auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); + //widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"]; + } else { + m_Selection = entity; + } + } else { + m_Selection = 0; + } + } } m_PickingQueue.clear(); return true; }; + +void EditorSystem::updateWidget() +{ + if (m_Widget == 0) { + m_Widget = m_World->CreateEntity(); + m_World->AttachComponent(m_Widget, "Transform"); + m_WidgetX = m_World->CreateEntity(m_Widget); + m_World->AttachComponent(m_WidgetX, "Transform"); + m_World->AttachComponent(m_WidgetX, "Model"); + m_WidgetY = m_World->CreateEntity(m_Widget); + m_World->AttachComponent(m_WidgetY, "Transform"); + m_World->AttachComponent(m_WidgetY, "Model"); + m_WidgetZ = m_World->CreateEntity(m_Widget); + m_World->AttachComponent(m_WidgetZ, "Transform"); + m_World->AttachComponent(m_WidgetZ, "Model"); + m_WidgetOrigin = m_World->CreateEntity(m_Widget); + m_World->AttachComponent(m_WidgetOrigin, "Transform"); + m_World->AttachComponent(m_WidgetOrigin, "Model"); + setWidgetMode(WidgetMode::Translate); + } + + if (m_Selection != 0) { + auto widgetTransform = m_World->GetComponent(m_Widget, "Transform"); + auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); + widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"]; + } +} + +void EditorSystem::setWidgetMode(WidgetMode newMode) +{ + if (m_Widget == 0) { + return; + } + + auto widgetTransform = m_World->GetComponent(m_Widget, "Transform"); + widgetTransform["Orientation"] = glm::vec3(0.f); + m_World->GetComponent(m_WidgetX, "Transform")["Scale"] = glm::vec3(1.f); + m_World->GetComponent(m_WidgetY, "Transform")["Scale"] = glm::vec3(1.f); + m_World->GetComponent(m_WidgetZ, "Transform")["Scale"] = glm::vec3(1.f); + m_World->GetComponent(m_WidgetOrigin, "Transform")["Scale"] = glm::vec3(1.f); + + if (newMode == WidgetMode::Translate) { + m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/TranslationWidgetX.obj"; + m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/TranslationWidgetY.obj"; + m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/TranslationWidgetZ.obj"; + m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = false; + if (m_Selection != 0) { + if (m_WidgetSpace == WidgetSpace::Local) { + auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); + widgetTransform["Orientation"] = (glm::vec3)selectionTransform["Orientation"]; + } + } + } else if (newMode == WidgetMode::Scale) { + m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/ScaleWidgetX.obj"; + m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/ScaleWidgetY.obj"; + m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/ScaleWidgetZ.obj"; + m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = true; + m_World->GetComponent(m_WidgetOrigin, "Model")["Resource"] = "Models/ScaleWidgetOrigin.obj"; + if (m_Selection != 0) { + auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); + widgetTransform["Orientation"] = (glm::vec3)selectionTransform["Orientation"]; + } + } else if (newMode == WidgetMode::Rotate) { + m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/RotationWidgetX.obj"; + m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/RotationWidgetY.obj"; + m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/RotationWidgetZ.obj"; + m_World->GetComponent(m_WidgetOrigin, "Model")["Visible"] = false; + if (m_Selection != 0) { + auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); + if (m_WidgetSpace == WidgetSpace::Local) { + widgetTransform["Orientation"] = (glm::vec3)selectionTransform["Orientation"]; + } + } + } + m_WidgetMode = newMode; +} + + +void EditorSystem::setWidgetSpace(WidgetSpace space) +{ + m_WidgetSpace = space; + setWidgetMode(m_WidgetMode); +} + void EditorSystem::drawUI(World* world, double dt) { ImGui::ShowTestWindow(); @@ -102,24 +303,32 @@ void EditorSystem::drawUI(World* world, double dt) ImGui::SameLine(); if (ImGui::Button("Move")) { - auto& model = world->GetComponent(m_Widget, "Model"); - model["Resource"] = "Models/TranslationWidget.obj"; + setWidgetMode(WidgetMode::Translate); } ImGui::SameLine(); if (ImGui::Button("Rotate")) { - auto& model = world->GetComponent(m_Widget, "Model"); - model["Resource"] = "Models/RotationWidget.obj"; + setWidgetMode(WidgetMode::Rotate); } ImGui::SameLine(); if (ImGui::Button("Scale")) { - auto& model = world->GetComponent(m_Widget, "Model"); - model["Resource"] = "Models/ScaleWidget.obj"; + setWidgetMode(WidgetMode::Scale); + } + ImGui::SameLine(); + if (m_WidgetSpace == WidgetSpace::Global) { + if (ImGui::Button("(Global)")) { + setWidgetSpace(WidgetSpace::Local); + } + } else if (m_WidgetSpace == WidgetSpace::Local) { + if (ImGui::Button("(Local)")) { + setWidgetSpace(WidgetSpace::Global); + } } ImGui::EndMainMenuBar(); } - if (ImGui::Begin("Components")) { + std::string title = std::string("Components #") + std::to_string(m_Selection) + std::string("###Components"); + if (ImGui::Begin(title.c_str())) { if (m_Selection != 0) { auto& pools = world->GetComponentPools(); diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 68402469..06810412 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -135,12 +135,10 @@ void Renderer::Update(double dt) void Renderer::Draw(RenderQueueCollection& rq) { m_PickingPass->Draw(rq); - //DrawScreenQuad(m_PickingPass->PickingTexture()); + DrawScreenQuad(m_PickingPass->PickingTexture()); //CullLights(); glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); m_DrawScenePass->Draw(rq); GLERROR("Renderer::Draw m_DrawScenePass->Draw"); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 061ac835..7f7559e0 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -52,7 +52,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline = new SystemPipeline(m_EventBroker); m_SystemPipeline->AddSystem(); m_SystemPipeline->AddSystem(); - m_SystemPipeline->AddSystem(); + m_SystemPipeline->AddSystem(m_Renderer); m_LastTime = glfwGetTime(); From bd6adcc15773b4ce9d6144954379a45a5563ecb0 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Wed, 16 Dec 2015 12:05:31 +0100 Subject: [PATCH 06/12] Added SetParent to World --- include/Engine/Core/World.h | 3 +++ src/Engine/Core/World.cpp | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/Engine/Core/World.h b/include/Engine/Core/World.h index da31d369..92378816 100644 --- a/include/Engine/Core/World.h +++ b/include/Engine/Core/World.h @@ -31,6 +31,8 @@ public: const ComponentPool* GetComponents(std::string componentType); // Get entity parent EntityID GetParent(EntityID entity); + // Change the parent of an entity + void SetParent(EntityID entity, EntityID parent); // Get all component pools const std::unordered_map& GetComponentPools() const { return m_ComponentPools; } // Get the entity children map @@ -40,6 +42,7 @@ private: EntityID m_CurrentEntityID = 1; std::unordered_map m_EntityParents; + // TODO: This should be a more effective structure std::unordered_multimap m_EntityChildren; std::unordered_map m_ComponentPools; diff --git a/src/Engine/Core/World.cpp b/src/Engine/Core/World.cpp index 7ee5e6a7..5443d388 100644 --- a/src/Engine/Core/World.cpp +++ b/src/Engine/Core/World.cpp @@ -99,6 +99,22 @@ EntityID World::GetParent(EntityID entity) return m_EntityParents.at(entity); } + +void World::SetParent(EntityID entity, EntityID parent) +{ + EntityID lastParent = m_EntityParents.at(entity); + auto parentChildren = m_EntityChildren.equal_range(lastParent); + for (auto it = parentChildren.first; it != parentChildren.second; it++) { + if (it->second == entity) { + m_EntityChildren.erase(it); + break; + } + } + + m_EntityParents[entity] = parent; + m_EntityChildren.insert(std::make_pair(parent, entity)); +} + EntityID World::generateEntityID() { // TODO: Make EntityID generation smarter From 661532e355e7144f044460fd365c31d8077231fe Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Wed, 16 Dec 2015 12:05:55 +0100 Subject: [PATCH 07/12] Slightly more usable entity tree --- include/Engine/Editor/EditorSystem.h | 1 + src/Engine/Editor/EditorSystem.cpp | 76 ++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index be4cd608..021a14ca 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -67,4 +67,5 @@ private: void setWidgetSpace(WidgetSpace space); void drawUI(World* world, double dt); bool createDeleteButton(std::string componentType); + void changeParent(EntityID entity, EntityID newParent); }; \ No newline at end of file diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index fbad2281..e224ca6b 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -414,23 +414,62 @@ void EditorSystem::drawUI(World* world, double dt) ImGui::End(); if (ImGui::Begin("Entitites")) { + static EntityID draggingEntity = 0; auto entityChildren = world->GetEntityChildren(); std::function recurse = [&](EntityID parent) { auto range = entityChildren.equal_range(parent); for (auto it = range.first; it != range.second; it++) { + + ImVec2 pos = ImGui::GetCursorScreenPos(); + float width = ImGui::GetContentRegionAvailWidth(); + ImRect bb(pos + ImVec2(20, 0), pos + ImVec2(width, 13)); + auto window = ImGui::GetCurrentWindow(); + if (m_Selection == it->second) { + const ImU32 col = window->Color(ImGuiCol_HeaderActive); + window->DrawList->AddRectFilled(bb.Min, bb.Max, col); + } + ImGuiID id = window->GetID((std::string("#SelectButton") + std::to_string(it->second)).c_str()); + bool hovered = false; + bool held = false; + if (ImGui::ButtonBehavior(bb, id, &hovered, &held)) { + m_Selection = it->second; + } + if (held) { + ImVec2 entityDragDelta = ImGui::GetMouseDragDelta(0); + if (std::abs(entityDragDelta.x) > 0 && std::abs(entityDragDelta.y) > 0) { + if (draggingEntity == 0) { + draggingEntity = it->second; + LOG_DEBUG("Started drag of entity %i", draggingEntity); + } + ImGui::SetNextWindowPos(ImGui::GetIO().MousePos + ImVec2(20, 0)); + ImGui::Begin("Change parent", nullptr, ImVec2(0, 0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings); + ImGui::Text("#%i", draggingEntity); + ImGui::End(); + } + } + ImGui::SetNextTreeNodeOpened(true, ImGuiSetCond_Once); if (ImGui::TreeNode((std::string("#") + std::to_string(it->second)).c_str())) { - if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0)) { - m_Selection = it->second; + if (draggingEntity != 0 && ImGui::IsItemHoveredRect() && ImGui::IsMouseReleased(0)) { + LOG_DEBUG("Changed parent of %i to %i", draggingEntity, it->second); + changeParent(draggingEntity, it->second); + draggingEntity = 0; } - ImGui::SameLine(); - if (ImGui::Button("Add")) { - EntityID entity = world->CreateEntity(it->second); - world->AttachComponent(entity, "Transform"); - } - ImGui::SameLine(); - if (ImGui::Button("Delete")) { - world->DeleteEntity(it->second); + + if (ImGui::BeginPopupContextItem("item context menu")) { + if (ImGui::Button("Add")) { + EntityID entity = world->CreateEntity(it->second); + world->AttachComponent(entity, "Transform"); + } + ImGui::SameLine(); + if (ImGui::Button("Delete")) { + world->DeleteEntity(it->second); + ImGui::CloseCurrentPopup(); + if (m_Selection == it->second) { + m_Selection = 0; + } + } + ImGui::EndPopup(); } recurse(it->second); ImGui::TreePop(); @@ -459,3 +498,20 @@ bool EditorSystem::createDeleteButton(std::string componentType) window->DrawList->AddCircleFilled(bb.GetCenter(), 7.f, col, 16); return pressed; } + +void EditorSystem::changeParent(EntityID entity, EntityID newParent) +{ + if (entity == newParent) { + return; + } + + // An entity can't be a child to one of its own children + auto children = m_World->GetEntityChildren().equal_range(entity); + for (auto it = children.first; it != children.second; it++) { + if (it->second == newParent) { + return; + } + } + + m_World->SetParent(entity, newParent); +} From dbbbb7b4e7518a4e56955986e33a3a78c65b5abb Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Wed, 16 Dec 2015 17:20:56 +0100 Subject: [PATCH 08/12] Working rotations and translations relative to global and local space for children --- deps | 2 +- resources/Schema/Components/Transform.xml | 2 +- resources/Schema/Entities/EditorTestWorld.xml | 23 +++++++++++- src/Engine/Core/EntityXMLFile.cpp | 4 +- src/Engine/Editor/EditorSystem.cpp | 37 +++++++++++++------ 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/deps b/deps index f20b9cc1..e6399158 160000 --- a/deps +++ b/deps @@ -1 +1 @@ -Subproject commit f20b9cc13bffa39c3b5144bacc5eacd34d43052c +Subproject commit e63991581a268f3eb85f86782d0bdf3687695795 diff --git a/resources/Schema/Components/Transform.xml b/resources/Schema/Components/Transform.xml index 276b89e7..00202aa4 100644 --- a/resources/Schema/Components/Transform.xml +++ b/resources/Schema/Components/Transform.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/resources/Schema/Entities/EditorTestWorld.xml b/resources/Schema/Entities/EditorTestWorld.xml index 6e1c0be5..7fa8e96a 100755 --- a/resources/Schema/Entities/EditorTestWorld.xml +++ b/resources/Schema/Entities/EditorTestWorld.xml @@ -2,7 +2,10 @@ - + + + + @@ -19,12 +22,28 @@ - + + An error + + + + + + + + + An error + + + + + + \ No newline at end of file diff --git a/src/Engine/Core/EntityXMLFile.cpp b/src/Engine/Core/EntityXMLFile.cpp index bf8daceb..c6e00a1b 100644 --- a/src/Engine/Core/EntityXMLFile.cpp +++ b/src/Engine/Core/EntityXMLFile.cpp @@ -431,12 +431,12 @@ float EntityXMLFile::getFloatAttribute(const xercesc::DOMElement* element, const { using namespace xercesc; XSValue::Status status; - XSValue* val = XSValue::getActualValue(element->getAttribute(XSTR(attribute)), xercesc::XSValue::DataType::dt_float, status); + XSValue* val = XSValue::getActualValue(element->getAttribute(XSTR(attribute)), xercesc::XSValue::DataType::dt_double, status); if (val == nullptr) { LOG_ERROR("Element \"%s\" doesn't have an \"%s\" attribute!", XSTR(element->getTagName()), attribute); return 0.f; } else { - return val->fData.fValue.f_float; + return static_cast(val->fData.fValue.f_double); } } diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index e224ca6b..d27a463b 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -111,26 +111,37 @@ bool EditorSystem::OnMouseMove(const Events::MouseMove& e) auto widgetTransform = m_World->GetComponent(m_Widget, "Transform"); if (m_WidgetMode == WidgetMode::Translate) { if (m_WidgetSpace == WidgetSpace::Global) { - (glm::vec3&)m_World->GetComponent(m_Selection, "Transform")["Position"] += movement; + EntityID parent = m_World->GetParent(m_Selection); + glm::quat inverseParentOrientation; + if (parent != 0) { + inverseParentOrientation = glm::inverse(RenderQueueFactory::AbsoluteOrientation(m_World, parent)); + } + (glm::vec3&)m_World->GetComponent(m_Selection, "Transform")["Position"] += inverseParentOrientation * movement; } else if (m_WidgetSpace == WidgetSpace::Local) { auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); - (glm::vec3&)selectionTransform["Position"] += glm::quat((glm::vec3&)selectionTransform["Orientation"]) * movement; + (glm::vec3&)selectionTransform["Position"] += glm::quat((glm::vec3)selectionTransform["Orientation"]) * movement; } } else if (m_WidgetMode == WidgetMode::Rotate) { glm::vec3 finalMovement; finalMovement.x = -deltaWorld.y * m_WidgetCurrentAxis.x; finalMovement.y = deltaWorld.x * m_WidgetCurrentAxis.y; finalMovement.z = deltaWorld.y * m_WidgetCurrentAxis.z; - glm::vec3& selectionOrientation = m_World->GetComponent(m_Selection, "Transform")["Orientation"]; if (m_WidgetSpace == WidgetSpace::Global) { - glm::quat currentOrientation = glm::quat(selectionOrientation); + EntityID parent = m_World->GetParent(m_Selection); + glm::quat parentOrientation; + if (parent != 0) { + parentOrientation = RenderQueueFactory::AbsoluteOrientation(m_World, parent); + } + glm::vec3& selectionOrientation = m_World->GetComponent(m_Selection, "Transform")["Orientation"]; + //glm::quat currentOrientation = RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection); + glm::quat currentOrientation = parentOrientation * glm::quat(selectionOrientation); glm::quat deltaOrientation(finalMovement); - selectionOrientation = glm::eulerAngles(deltaOrientation * currentOrientation); // (currentOrientation * deltaOrientation) * glm::vec3(0, 0, -1); + selectionOrientation = glm::eulerAngles(glm::inverse(parentOrientation) * (deltaOrientation * currentOrientation)); } else if (m_WidgetSpace == WidgetSpace::Local) { + glm::vec3& selectionOrientation = m_World->GetComponent(m_Selection, "Transform")["Orientation"]; glm::quat currentOrientation(selectionOrientation); glm::quat deltaOrientation(finalMovement); - selectionOrientation = glm::eulerAngles(currentOrientation * deltaOrientation); // (currentOrientation * deltaOrientation) * glm::vec3(0, 0, -1); - widgetTransform["Orientation"] = selectionOrientation; + selectionOrientation = glm::eulerAngles(currentOrientation * deltaOrientation); } } else if (m_WidgetMode == WidgetMode::Scale) { glm::vec3& scaleX = m_World->GetComponent(m_WidgetX, "Transform")["Scale"]; @@ -189,6 +200,7 @@ bool EditorSystem::OnPicking(const Events::Picking& e) //widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"]; } else { m_Selection = entity; + setWidgetMode(m_WidgetMode); } } else { m_Selection = 0; @@ -222,8 +234,11 @@ void EditorSystem::updateWidget() if (m_Selection != 0) { auto widgetTransform = m_World->GetComponent(m_Widget, "Transform"); - auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); - widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"]; + glm::vec3 selectionPosition = RenderQueueFactory::AbsolutePosition(m_World, m_Selection); + widgetTransform["Position"] = selectionPosition; + if (m_WidgetSpace == WidgetSpace::Local) { + widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection)); + } } } @@ -248,7 +263,7 @@ void EditorSystem::setWidgetMode(WidgetMode newMode) if (m_Selection != 0) { if (m_WidgetSpace == WidgetSpace::Local) { auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); - widgetTransform["Orientation"] = (glm::vec3)selectionTransform["Orientation"]; + widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection)); } } } else if (newMode == WidgetMode::Scale) { @@ -269,7 +284,7 @@ void EditorSystem::setWidgetMode(WidgetMode newMode) if (m_Selection != 0) { auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); if (m_WidgetSpace == WidgetSpace::Local) { - widgetTransform["Orientation"] = (glm::vec3)selectionTransform["Orientation"]; + widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection)); } } } From a914a7f924ffa0815e7f405dce6a5d7a8f5d790f Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Wed, 16 Dec 2015 17:22:35 +0100 Subject: [PATCH 09/12] Switched to deps/master branch --- deps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps b/deps index e6399158..1ae6ba5b 160000 --- a/deps +++ b/deps @@ -1 +1 @@ -Subproject commit e63991581a268f3eb85f86782d0bdf3687695795 +Subproject commit 1ae6ba5b1297ed71b560aee211b9f0007ba52547 From d4f5856304764696770c8598d5155c01eb072ec7 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 17 Dec 2015 10:44:34 +0100 Subject: [PATCH 10/12] Component attributes no longer get set on the wrong entity when switching selection while editing a field --- src/Engine/Editor/EditorSystem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index d27a463b..2463aec6 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -199,6 +199,7 @@ bool EditorSystem::OnPicking(const Events::Picking& e) //auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); //widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"]; } else { + ImGui::SetActiveID(0, nullptr); m_Selection = entity; setWidgetMode(m_WidgetMode); } From b87f5592916614a380efe56f11a7db9b710c3d12 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 17 Dec 2015 10:46:49 +0100 Subject: [PATCH 11/12] Updated default configs with editor stuff --- resources/DefaultConfig.ini | 1 + resources/DefaultInput.ini | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index 0d95de03..208f413c 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -1,6 +1,7 @@ [Debug] LogLevel=1 LoadMap= +EditorEnabled=false [Video] Fullscreen=false diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini index 3be67287..b0b9e3d0 100644 --- a/resources/DefaultInput.ini +++ b/resources/DefaultInput.ini @@ -14,3 +14,8 @@ R=Reload Space=Jump LeftControl=Crouch LeftShift=Sprint +F1=ToggleEditor +1=EditorToolMove +2=EditorToolRotate +3=EditorToolScale +X=EditorToggleTransformSpace \ No newline at end of file From c8460e0a6c6bad967cfe2c0cdf3ce8cc56c75385 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 17 Dec 2015 10:55:54 +0100 Subject: [PATCH 12/12] It's no use --- src/Engine/Rendering/Renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 06810412..21ff6c5a 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -135,7 +135,7 @@ void Renderer::Update(double dt) void Renderer::Draw(RenderQueueCollection& rq) { m_PickingPass->Draw(rq); - DrawScreenQuad(m_PickingPass->PickingTexture()); + //DrawScreenQuad(m_PickingPass->PickingTexture()); //CullLights(); glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f);