Basic transformation widgets

This commit is contained in:
2015-12-15 18:01:20 +01:00
parent 51dd627ae3
commit 322aedaf72
6 changed files with 285 additions and 40 deletions
+1 -1
Submodule assets updated: 95823e122a...c5f674349a
+36 -1
View File
@@ -2,34 +2,69 @@
#include <glm/gtx/common.hpp>
#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<glm::vec2> 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<EditorSystem, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e);
EventRelay<EditorSystem, Events::MouseRelease> m_EMouseRelease;
bool OnMouseRelease(const Events::MouseRelease& e);
EventRelay<EditorSystem, Events::MousePress> m_EMousePress;
bool OnMousePress(const Events::MousePress& e);
EventRelay<EditorSystem, Events::MouseMove> m_EMouseMove;
bool OnMouseMove(const Events::MouseMove& e);
EventRelay<EditorSystem, Events::Picking> 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);
};
+3
View File
@@ -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()) {
+243 -34
View File
@@ -2,8 +2,9 @@
#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui/imgui_internal.h>
EditorSystem::EditorSystem(EventBroker* eventBroker)
EditorSystem::EditorSystem(EventBroker* eventBroker, IRenderer* renderer)
: ImpureSystem(eventBroker)
, m_Renderer(renderer)
{
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
m_Enabled = config->Get<bool>("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();
+1 -3
View File
@@ -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");
+1 -1
View File
@@ -52,7 +52,7 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline = new SystemPipeline(m_EventBroker);
m_SystemPipeline->AddSystem<RaptorCopterSystem>();
m_SystemPipeline->AddSystem<PlayerSystem>();
m_SystemPipeline->AddSystem<EditorSystem>();
m_SystemPipeline->AddSystem<EditorSystem>(m_Renderer);
m_LastTime = glfwGetTime();