MAJOR BREAKING CHANGE: EntityID 0 is now a valid entity. Use EntityID_Invalid as sentry for checks!
Also contains inseparable editor changes.
This commit is contained in:
+1
-1
Submodule deps updated: 1ae6ba5b12...bf83f099ba
@@ -2,5 +2,6 @@
|
|||||||
#define Entity_h__
|
#define Entity_h__
|
||||||
|
|
||||||
typedef unsigned int EntityID;
|
typedef unsigned int EntityID;
|
||||||
|
const static unsigned int EntityID_Invalid = -1;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
#include <glm/gtx/common.hpp>
|
#include <glm/gtx/common.hpp>
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
|
#include <nativefiledialog/nfd.h>
|
||||||
#include "../Core/System.h"
|
#include "../Core/System.h"
|
||||||
#include "../Core/EMousePress.h"
|
#include "../Core/EMousePress.h"
|
||||||
#include "../Core/EMouseRelease.h"
|
#include "../Core/EMouseRelease.h"
|
||||||
@@ -11,6 +12,9 @@
|
|||||||
#include "../Rendering/EPicking.h"
|
#include "../Rendering/EPicking.h"
|
||||||
#include "../Core/EFileDropped.h"
|
#include "../Core/EFileDropped.h"
|
||||||
#include "../Rendering/RenderQueueFactory.h"
|
#include "../Rendering/RenderQueueFactory.h"
|
||||||
|
#include "../Core/EntityFilePreprocessor.h"
|
||||||
|
#include "../Core/EntityFileParser.h"
|
||||||
|
#include "../Core/EntityFileWriter.h"
|
||||||
|
|
||||||
class EditorSystem : public ImpureSystem
|
class EditorSystem : public ImpureSystem
|
||||||
{
|
{
|
||||||
@@ -25,6 +29,8 @@ private:
|
|||||||
|
|
||||||
bool m_Enabled;
|
bool m_Enabled;
|
||||||
bool m_Visible;
|
bool m_Visible;
|
||||||
|
boost::filesystem::path m_DefaultEntityDir;
|
||||||
|
boost::filesystem::path m_CurrentFile;
|
||||||
std::vector<glm::vec2> m_PickingQueue;
|
std::vector<glm::vec2> m_PickingQueue;
|
||||||
|
|
||||||
enum class WidgetMode
|
enum class WidgetMode
|
||||||
@@ -41,22 +47,26 @@ private:
|
|||||||
Global
|
Global
|
||||||
} m_WidgetSpace = WidgetSpace::Global;
|
} m_WidgetSpace = WidgetSpace::Global;
|
||||||
|
|
||||||
EntityID m_Widget = 0;
|
EntityID m_Widget = EntityID_Invalid;
|
||||||
EntityID m_WidgetX = 0;
|
EntityID m_WidgetX = EntityID_Invalid;
|
||||||
EntityID m_WidgetPlaneX = 0;
|
EntityID m_WidgetPlaneX = EntityID_Invalid;
|
||||||
EntityID m_WidgetY = 0;
|
EntityID m_WidgetY = EntityID_Invalid;
|
||||||
EntityID m_WidgetPlaneY = 0;
|
EntityID m_WidgetPlaneY = EntityID_Invalid;
|
||||||
EntityID m_WidgetZ = 0;
|
EntityID m_WidgetZ = EntityID_Invalid;
|
||||||
EntityID m_WidgetPlaneZ = 0;
|
EntityID m_WidgetPlaneZ = EntityID_Invalid;
|
||||||
EntityID m_WidgetOrigin = 0;
|
EntityID m_WidgetOrigin = EntityID_Invalid;
|
||||||
glm::vec3 m_WidgetCurrentAxis;
|
glm::vec3 m_WidgetCurrentAxis;
|
||||||
float m_WidgetPickingDepth = 0.f;
|
float m_WidgetPickingDepth = 0.f;
|
||||||
|
|
||||||
EntityID m_Selection = 0;
|
EntityID m_Selection = EntityID_Invalid;
|
||||||
EntityID m_LastSelection = 0;
|
EntityID m_LastSelection = EntityID_Invalid;
|
||||||
|
EntityID m_UIDraggingEntity = EntityID_Invalid;
|
||||||
glm::vec3 m_Position;
|
glm::vec3 m_Position;
|
||||||
std::string m_LastDroppedFile;
|
std::string m_LastDroppedFile;
|
||||||
|
|
||||||
|
static boost::filesystem::path openDialog(boost::filesystem::path defaultPath);
|
||||||
|
static boost::filesystem::path saveDialog(boost::filesystem::path defaultPath);
|
||||||
|
|
||||||
EventRelay<EditorSystem, Events::InputCommand> m_EInputCommand;
|
EventRelay<EditorSystem, Events::InputCommand> m_EInputCommand;
|
||||||
bool OnInputCommand(const Events::InputCommand& e);
|
bool OnInputCommand(const Events::InputCommand& e);
|
||||||
EventRelay<EditorSystem, Events::MouseRelease> m_EMouseRelease;
|
EventRelay<EditorSystem, Events::MouseRelease> m_EMouseRelease;
|
||||||
@@ -70,10 +80,15 @@ private:
|
|||||||
EventRelay<EditorSystem, Events::FileDropped> m_EFileDropped;
|
EventRelay<EditorSystem, Events::FileDropped> m_EFileDropped;
|
||||||
bool OnFileDropped(const Events::FileDropped& e);
|
bool OnFileDropped(const Events::FileDropped& e);
|
||||||
|
|
||||||
|
void createWidget();
|
||||||
void updateWidget();
|
void updateWidget();
|
||||||
void setWidgetMode(WidgetMode newMode);
|
void setWidgetMode(WidgetMode newMode);
|
||||||
void setWidgetSpace(WidgetSpace space);
|
void setWidgetSpace(WidgetSpace space);
|
||||||
void drawUI(World* world, double dt);
|
void drawUI(World* world, double dt);
|
||||||
bool createDeleteButton(std::string componentType);
|
bool createDeleteButton(std::string componentType);
|
||||||
|
bool createEntityNode(World* world, EntityID entity);
|
||||||
void changeParent(EntityID entity, EntityID newParent);
|
void changeParent(EntityID entity, EntityID newParent);
|
||||||
|
void fileImport(World* world);
|
||||||
|
void fileSave(World* world);
|
||||||
|
void fileSaveAs(World* world);
|
||||||
};
|
};
|
||||||
@@ -51,7 +51,7 @@ public:
|
|||||||
if (it != PickingColorsToEntity->end()) {
|
if (it != PickingColorsToEntity->end()) {
|
||||||
pickData.Entity = it->second;
|
pickData.Entity = it->second;
|
||||||
} else {
|
} else {
|
||||||
pickData.Entity = 0;
|
pickData.Entity = EntityID_Invalid;
|
||||||
}
|
}
|
||||||
pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix);
|
pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix);
|
||||||
|
|
||||||
|
|||||||
@@ -90,12 +90,27 @@ set(SOURCE_FILES
|
|||||||
${SOURCE_FILES_Rendering}
|
${SOURCE_FILES_Rendering}
|
||||||
${SOURCE_FILES_Rendering_Util}
|
${SOURCE_FILES_Rendering_Util}
|
||||||
${SOURCE_FILES_Collision}
|
${SOURCE_FILES_Collision}
|
||||||
|
${SOURCE_FILES_Editor}
|
||||||
${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui.cpp
|
${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui.cpp
|
||||||
${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui_draw.cpp
|
${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui_draw.cpp
|
||||||
${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui_demo.cpp
|
${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui_demo.cpp
|
||||||
${SOURCE_FILES_Editor}
|
${CMAKE_SOURCE_DIR}/deps/include/nativefiledialog/nfd_common.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# nativefiledialog
|
||||||
|
if(WIN32)
|
||||||
|
set(SOURCE_FILES ${SOURCE_FILES}
|
||||||
|
${CMAKE_SOURCE_DIR}/deps/include/nativefiledialog/nfd_win.cpp
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
if(UNIX)
|
||||||
|
set(SOURCE_FILES ${SOURCE_FILES}
|
||||||
|
${CMAKE_SOURCE_DIR}/deps/include/nativefiledialog/nfd_gtk.c
|
||||||
|
# TODO: Link with GTK+ here!
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
set(LIBRARIES
|
set(LIBRARIES
|
||||||
${OPENGL_LIBRARIES}
|
${OPENGL_LIBRARIES}
|
||||||
${GLEW_LIBRARIES}
|
${GLEW_LIBRARIES}
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ World::~World()
|
|||||||
EntityID World::CreateEntity(EntityID parent /*= 0*/)
|
EntityID World::CreateEntity(EntityID parent /*= 0*/)
|
||||||
{
|
{
|
||||||
EntityID newEntity = generateEntityID();
|
EntityID newEntity = generateEntityID();
|
||||||
if (newEntity != parent) {
|
if (newEntity == parent) {
|
||||||
m_EntityParents[newEntity] = parent;
|
LOG_WARNING("Invalid parent #%i of Entity#%i", newEntity, parent);
|
||||||
m_EntityChildren.insert(std::make_pair(parent, newEntity));
|
parent = EntityID_Invalid;
|
||||||
} else {
|
|
||||||
LOG_WARNING("Attempted to create an entity with itself as parent! Entity#%i with parent #%i", newEntity, parent);
|
|
||||||
}
|
}
|
||||||
|
m_EntityParents[newEntity] = parent;
|
||||||
|
m_EntityChildren.insert(std::make_pair(parent, newEntity));
|
||||||
return newEntity;
|
return newEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ EditorSystem::EditorSystem(EventBroker* eventBroker, IRenderer* renderer)
|
|||||||
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
m_Enabled = config->Get<bool>("Debug.EditorEnabled", false);
|
m_Enabled = config->Get<bool>("Debug.EditorEnabled", false);
|
||||||
m_Visible = m_Enabled;
|
m_Visible = m_Enabled;
|
||||||
|
m_DefaultEntityDir = boost::filesystem::path("Schema") / boost::filesystem::path("Entities");
|
||||||
|
|
||||||
if (!m_Enabled) {
|
if (!m_Enabled) {
|
||||||
return;
|
return;
|
||||||
@@ -44,6 +45,35 @@ void EditorSystem::Update(World* world, double dt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boost::filesystem::path EditorSystem::openDialog(boost::filesystem::path defaultPath)
|
||||||
|
{
|
||||||
|
namespace bfs = boost::filesystem;
|
||||||
|
auto absolutePath = bfs::absolute(defaultPath);
|
||||||
|
nfdchar_t* outPath = nullptr;
|
||||||
|
nfdresult_t result = NFD_OpenDialog(NULL, absolutePath.string().c_str(), &outPath);
|
||||||
|
if (result == NFD_ERROR) {
|
||||||
|
LOG_ERROR("NFD Error: %s", NFD_GetError());
|
||||||
|
return bfs::path();
|
||||||
|
}
|
||||||
|
|
||||||
|
return bfs::absolute(outPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::filesystem::path EditorSystem::saveDialog(boost::filesystem::path defaultPath)
|
||||||
|
{
|
||||||
|
namespace bfs = boost::filesystem;
|
||||||
|
auto absolutePath = bfs::absolute(defaultPath);
|
||||||
|
nfdchar_t* outPath = nullptr;
|
||||||
|
nfdresult_t result = NFD_SaveDialog(NULL, absolutePath.string().c_str(), &outPath);
|
||||||
|
if (result == NFD_ERROR) {
|
||||||
|
LOG_ERROR("NFD Error: %s", NFD_GetError());
|
||||||
|
return bfs::path();
|
||||||
|
}
|
||||||
|
|
||||||
|
return bfs::absolute(outPath);
|
||||||
|
}
|
||||||
|
|
||||||
bool EditorSystem::OnInputCommand(const Events::InputCommand& e)
|
bool EditorSystem::OnInputCommand(const Events::InputCommand& e)
|
||||||
{
|
{
|
||||||
if (e.Command == "ToggleEditor" && e.Value > 0) {
|
if (e.Command == "ToggleEditor" && e.Value > 0) {
|
||||||
@@ -81,17 +111,24 @@ bool EditorSystem::OnMousePress(const Events::MousePress& e)
|
|||||||
|
|
||||||
bool EditorSystem::OnMouseMove(const Events::MouseMove& e)
|
bool EditorSystem::OnMouseMove(const Events::MouseMove& e)
|
||||||
{
|
{
|
||||||
if (m_Widget == 0) {
|
if (m_Widget == EntityID_Invalid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (m_Selection == EntityID_Invalid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (m_Selection == m_Widget) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// TODO: No widgets for root entity until widgets reside in thier own world,
|
||||||
|
// or the widgets will move relative to the root entity being moved, which is WEEEIRD.
|
||||||
if (m_Selection == 0) {
|
if (m_Selection == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
|
auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
|
||||||
glm::vec3 widgetOrientation = widgetTransform["Orientation"];
|
glm::vec3 widgetOrientation = widgetTransform["Orientation"];
|
||||||
|
glm::quat totalOrientation = m_Renderer->Camera()->Orientation() * glm::inverse(glm::quat(widgetOrientation));
|
||||||
glm::quat totalOrientation = m_Renderer->Camera()->Orientation() * glm::inverse(glm::quat(widgetOrientation));
|
|
||||||
|
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
@@ -122,9 +159,9 @@ bool EditorSystem::OnMouseMove(const Events::MouseMove& e)
|
|||||||
if (m_WidgetSpace == WidgetSpace::Global) {
|
if (m_WidgetSpace == WidgetSpace::Global) {
|
||||||
EntityID parent = m_World->GetParent(m_Selection);
|
EntityID parent = m_World->GetParent(m_Selection);
|
||||||
glm::quat inverseParentOrientation;
|
glm::quat inverseParentOrientation;
|
||||||
if (parent != 0) {
|
//if (parent != 0) {
|
||||||
inverseParentOrientation = glm::inverse(RenderQueueFactory::AbsoluteOrientation(m_World, parent));
|
inverseParentOrientation = glm::inverse(RenderQueueFactory::AbsoluteOrientation(m_World, parent));
|
||||||
}
|
//}
|
||||||
(glm::vec3&)m_World->GetComponent(m_Selection, "Transform")["Position"] += inverseParentOrientation * movement;
|
(glm::vec3&)m_World->GetComponent(m_Selection, "Transform")["Position"] += inverseParentOrientation * movement;
|
||||||
} else if (m_WidgetSpace == WidgetSpace::Local) {
|
} else if (m_WidgetSpace == WidgetSpace::Local) {
|
||||||
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
|
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
|
||||||
@@ -138,12 +175,12 @@ bool EditorSystem::OnMouseMove(const Events::MouseMove& e)
|
|||||||
if (m_WidgetSpace == WidgetSpace::Global) {
|
if (m_WidgetSpace == WidgetSpace::Global) {
|
||||||
EntityID parent = m_World->GetParent(m_Selection);
|
EntityID parent = m_World->GetParent(m_Selection);
|
||||||
glm::quat parentOrientation;
|
glm::quat parentOrientation;
|
||||||
if (parent != 0) {
|
//if (parent != 0) {
|
||||||
parentOrientation = RenderQueueFactory::AbsoluteOrientation(m_World, parent);
|
// parentOrientation = RenderQueueFactory::AbsoluteOrientation(m_World, parent);
|
||||||
}
|
//}
|
||||||
glm::vec3& selectionOrientation = m_World->GetComponent(m_Selection, "Transform")["Orientation"];
|
glm::vec3& selectionOrientation = m_World->GetComponent(m_Selection, "Transform")["Orientation"];
|
||||||
//glm::quat currentOrientation = RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection);
|
glm::quat currentOrientation = RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection);
|
||||||
glm::quat currentOrientation = parentOrientation * glm::quat(selectionOrientation);
|
//glm::quat currentOrientation = parentOrientation * glm::quat(selectionOrientation);
|
||||||
glm::quat deltaOrientation(finalMovement);
|
glm::quat deltaOrientation(finalMovement);
|
||||||
selectionOrientation = glm::eulerAngles(glm::inverse(parentOrientation) * (deltaOrientation * currentOrientation));
|
selectionOrientation = glm::eulerAngles(glm::inverse(parentOrientation) * (deltaOrientation * currentOrientation));
|
||||||
} else if (m_WidgetSpace == WidgetSpace::Local) {
|
} else if (m_WidgetSpace == WidgetSpace::Local) {
|
||||||
@@ -204,9 +241,10 @@ bool EditorSystem::OnPicking(const Events::Picking& e)
|
|||||||
auto result = e.Pick(pos);
|
auto result = e.Pick(pos);
|
||||||
EntityID entity = result.Entity;
|
EntityID entity = result.Entity;
|
||||||
if (glm::length2(m_WidgetCurrentAxis) > 0.f) {
|
if (glm::length2(m_WidgetCurrentAxis) > 0.f) {
|
||||||
|
// ???
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("Selected %i", entity);
|
LOG_INFO("Selected %i", entity);
|
||||||
if (entity != 0) {
|
if (entity != EntityID_Invalid) {
|
||||||
EntityID parent = m_World->GetParent(entity);
|
EntityID parent = m_World->GetParent(entity);
|
||||||
if (parent == m_Widget) {
|
if (parent == m_Widget) {
|
||||||
m_WidgetCurrentAxis = glm::vec3(
|
m_WidgetCurrentAxis = glm::vec3(
|
||||||
@@ -221,11 +259,12 @@ bool EditorSystem::OnPicking(const Events::Picking& e)
|
|||||||
//widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"];
|
//widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"];
|
||||||
} else {
|
} else {
|
||||||
ImGui::SetActiveID(0, nullptr);
|
ImGui::SetActiveID(0, nullptr);
|
||||||
m_Selection = entity;
|
if (m_WidgetMode == WidgetMode::None) {
|
||||||
|
m_WidgetMode = WidgetMode::Translate;
|
||||||
|
}
|
||||||
setWidgetMode(m_WidgetMode);
|
setWidgetMode(m_WidgetMode);
|
||||||
|
m_Selection = entity;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
m_Selection = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,9 +279,10 @@ bool EditorSystem::OnFileDropped(const Events::FileDropped& e)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorSystem::updateWidget()
|
|
||||||
|
void EditorSystem::createWidget()
|
||||||
{
|
{
|
||||||
if (m_Widget == 0) {
|
if (m_Widget == EntityID_Invalid) {
|
||||||
m_Widget = m_World->CreateEntity();
|
m_Widget = m_World->CreateEntity();
|
||||||
m_World->AttachComponent(m_Widget, "Transform");
|
m_World->AttachComponent(m_Widget, "Transform");
|
||||||
m_WidgetX = m_World->CreateEntity(m_Widget);
|
m_WidgetX = m_World->CreateEntity(m_Widget);
|
||||||
@@ -269,10 +309,20 @@ void EditorSystem::updateWidget()
|
|||||||
m_WidgetOrigin = m_World->CreateEntity(m_Widget);
|
m_WidgetOrigin = m_World->CreateEntity(m_Widget);
|
||||||
m_World->AttachComponent(m_WidgetOrigin, "Transform");
|
m_World->AttachComponent(m_WidgetOrigin, "Transform");
|
||||||
m_World->AttachComponent(m_WidgetOrigin, "Model");
|
m_World->AttachComponent(m_WidgetOrigin, "Model");
|
||||||
setWidgetMode(WidgetMode::Translate);
|
setWidgetMode(WidgetMode::None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorSystem::updateWidget()
|
||||||
|
{
|
||||||
|
if (m_Widget == EntityID_Invalid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_Selection == m_Widget) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Selection != 0) {
|
if (m_Selection != EntityID_Invalid) {
|
||||||
auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
|
auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
|
||||||
glm::vec3 selectionPosition = RenderQueueFactory::AbsolutePosition(m_World, m_Selection);
|
glm::vec3 selectionPosition = RenderQueueFactory::AbsolutePosition(m_World, m_Selection);
|
||||||
widgetTransform["Position"] = selectionPosition;
|
widgetTransform["Position"] = selectionPosition;
|
||||||
@@ -284,7 +334,7 @@ void EditorSystem::updateWidget()
|
|||||||
|
|
||||||
void EditorSystem::setWidgetMode(WidgetMode newMode)
|
void EditorSystem::setWidgetMode(WidgetMode newMode)
|
||||||
{
|
{
|
||||||
if (m_Widget == 0) {
|
if (m_Widget == EntityID_Invalid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +359,7 @@ void EditorSystem::setWidgetMode(WidgetMode newMode)
|
|||||||
m_World->GetComponent(m_WidgetPlaneY, "Model")["Visible"] = true;
|
m_World->GetComponent(m_WidgetPlaneY, "Model")["Visible"] = true;
|
||||||
m_World->GetComponent(m_WidgetPlaneZ, "Model")["Visible"] = true;
|
m_World->GetComponent(m_WidgetPlaneZ, "Model")["Visible"] = true;
|
||||||
}
|
}
|
||||||
if (m_Selection != 0) {
|
if (m_Selection != EntityID_Invalid) {
|
||||||
if (m_WidgetSpace == WidgetSpace::Local) {
|
if (m_WidgetSpace == WidgetSpace::Local) {
|
||||||
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
|
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
|
||||||
widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection));
|
widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection));
|
||||||
@@ -321,7 +371,7 @@ void EditorSystem::setWidgetMode(WidgetMode newMode)
|
|||||||
m_World->GetComponent(m_WidgetZ, "Model")["Resource"] = "Models/ScaleWidgetZ.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")["Visible"] = true;
|
||||||
m_World->GetComponent(m_WidgetOrigin, "Model")["Resource"] = "Models/ScaleWidgetOrigin.obj";
|
m_World->GetComponent(m_WidgetOrigin, "Model")["Resource"] = "Models/ScaleWidgetOrigin.obj";
|
||||||
if (m_Selection != 0) {
|
if (m_Selection != EntityID_Invalid) {
|
||||||
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
|
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
|
||||||
widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection));
|
widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection));
|
||||||
}
|
}
|
||||||
@@ -329,7 +379,7 @@ void EditorSystem::setWidgetMode(WidgetMode newMode)
|
|||||||
m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/RotationWidgetX.obj";
|
m_World->GetComponent(m_WidgetX, "Model")["Resource"] = "Models/RotationWidgetX.obj";
|
||||||
m_World->GetComponent(m_WidgetY, "Model")["Resource"] = "Models/RotationWidgetY.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_WidgetZ, "Model")["Resource"] = "Models/RotationWidgetZ.obj";
|
||||||
if (m_Selection != 0) {
|
if (m_Selection != EntityID_Invalid) {
|
||||||
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
|
auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
|
||||||
if (m_WidgetSpace == WidgetSpace::Local) {
|
if (m_WidgetSpace == WidgetSpace::Local) {
|
||||||
widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection));
|
widgetTransform["Orientation"] = glm::eulerAngles(RenderQueueFactory::AbsoluteOrientation(m_World, m_Selection));
|
||||||
@@ -339,7 +389,6 @@ void EditorSystem::setWidgetMode(WidgetMode newMode)
|
|||||||
m_WidgetMode = newMode;
|
m_WidgetMode = newMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void EditorSystem::setWidgetSpace(WidgetSpace space)
|
void EditorSystem::setWidgetSpace(WidgetSpace space)
|
||||||
{
|
{
|
||||||
m_WidgetSpace = space;
|
m_WidgetSpace = space;
|
||||||
@@ -348,16 +397,23 @@ void EditorSystem::setWidgetSpace(WidgetSpace space)
|
|||||||
|
|
||||||
void EditorSystem::drawUI(World* world, double dt)
|
void EditorSystem::drawUI(World* world, double dt)
|
||||||
{
|
{
|
||||||
|
namespace bfs = boost::filesystem;
|
||||||
|
|
||||||
ImGui::ShowTestWindow();
|
ImGui::ShowTestWindow();
|
||||||
//ImGui::ShowStyleEditor();
|
//ImGui::ShowStyleEditor();
|
||||||
|
|
||||||
if (ImGui::BeginMainMenuBar()) {
|
if (ImGui::BeginMainMenuBar()) {
|
||||||
if (ImGui::BeginMenu("File")) {
|
if (ImGui::BeginMenu("File")) {
|
||||||
|
//if (ImGui::MenuItem("New")) { }
|
||||||
if (ImGui::MenuItem("New")) { }
|
if (ImGui::MenuItem("Import", "Ctrl+O")) {
|
||||||
if (ImGui::MenuItem("Open", "Ctrl+O")) { }
|
fileImport(world);
|
||||||
if (ImGui::MenuItem("Save", "Ctrl+S")) { }
|
}
|
||||||
if (ImGui::MenuItem("Save As...", "Ctrl+Shift+S")) { }
|
if (ImGui::MenuItem("Save", "Ctrl+S")) {
|
||||||
|
fileSave(world);
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem("Save As...", "Ctrl+Shift+S")) {
|
||||||
|
fileSaveAs(world);
|
||||||
|
}
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::MenuItem("Close Editor", "F1")) { }
|
if (ImGui::MenuItem("Close Editor", "F1")) { }
|
||||||
|
|
||||||
@@ -392,7 +448,7 @@ void EditorSystem::drawUI(World* world, double dt)
|
|||||||
|
|
||||||
std::string title = std::string("Components #") + std::to_string(m_Selection) + std::string("###Components");
|
std::string title = std::string("Components #") + std::to_string(m_Selection) + std::string("###Components");
|
||||||
if (ImGui::Begin(title.c_str())) {
|
if (ImGui::Begin(title.c_str())) {
|
||||||
if (m_Selection != 0) {
|
if (m_Selection != EntityID_Invalid) {
|
||||||
auto& pools = world->GetComponentPools();
|
auto& pools = world->GetComponentPools();
|
||||||
|
|
||||||
std::vector<const char*> componentTypes;
|
std::vector<const char*> componentTypes;
|
||||||
@@ -492,74 +548,81 @@ void EditorSystem::drawUI(World* world, double dt)
|
|||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
if (ImGui::Begin("Entitites")) {
|
if (ImGui::Begin("Entities")) {
|
||||||
static EntityID draggingEntity = 0;
|
|
||||||
auto entityChildren = world->GetEntityChildren();
|
auto entityChildren = world->GetEntityChildren();
|
||||||
std::function<void(EntityID)> recurse = [&](EntityID parent) {
|
std::function<void(EntityID)> recurse = [&](EntityID parent) {
|
||||||
auto range = entityChildren.equal_range(parent);
|
auto range = entityChildren.equal_range(parent);
|
||||||
for (auto it = range.first; it != range.second; it++) {
|
for (auto it = range.first; it != range.second; it++) {
|
||||||
|
if (createEntityNode(world, it->second)) {
|
||||||
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 (draggingEntity != 0 && ImGui::IsItemHoveredRect() && ImGui::IsMouseReleased(0)) {
|
|
||||||
LOG_DEBUG("Changed parent of %i to %i", draggingEntity, it->second);
|
|
||||||
changeParent(draggingEntity, it->second);
|
|
||||||
draggingEntity = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
recurse(it->second);
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
recurse(0);
|
recurse(EntityID_Invalid);
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EditorSystem::createEntityNode(World* world, EntityID entity)
|
||||||
|
{
|
||||||
|
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 == entity) {
|
||||||
|
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(entity)).c_str());
|
||||||
|
bool hovered = false;
|
||||||
|
bool held = false;
|
||||||
|
if (ImGui::ButtonBehavior(bb, id, &hovered, &held)) {
|
||||||
|
m_Selection = entity;
|
||||||
|
}
|
||||||
|
if (held) {
|
||||||
|
ImVec2 entityDragDelta = ImGui::GetMouseDragDelta(0);
|
||||||
|
if (std::abs(entityDragDelta.x) > 0 && std::abs(entityDragDelta.y) > 0) {
|
||||||
|
if (m_UIDraggingEntity == EntityID_Invalid) {
|
||||||
|
m_UIDraggingEntity = entity;
|
||||||
|
LOG_DEBUG("Started drag of entity %i", m_UIDraggingEntity);
|
||||||
|
}
|
||||||
|
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", m_UIDraggingEntity);
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetNextTreeNodeOpened(true, ImGuiSetCond_Once);
|
||||||
|
if (ImGui::TreeNode((std::string("#") + std::to_string(entity)).c_str())) {
|
||||||
|
if (m_UIDraggingEntity != EntityID_Invalid && ImGui::IsItemHoveredRect() && ImGui::IsMouseReleased(0)) {
|
||||||
|
LOG_DEBUG("Changed parent of %i to %i", m_UIDraggingEntity, entity);
|
||||||
|
changeParent(m_UIDraggingEntity, entity);
|
||||||
|
m_UIDraggingEntity = EntityID_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginPopupContextItem("item context menu")) {
|
||||||
|
if (ImGui::Button("Add")) {
|
||||||
|
EntityID entity = world->CreateEntity(entity);
|
||||||
|
world->AttachComponent(entity, "Transform");
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Delete")) {
|
||||||
|
world->DeleteEntity(entity);
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
if (m_Selection == entity) {
|
||||||
|
m_Selection = EntityID_Invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool EditorSystem::createDeleteButton(std::string componentType)
|
bool EditorSystem::createDeleteButton(std::string componentType)
|
||||||
{
|
{
|
||||||
float width = ImGui::GetContentRegionAvailWidth();
|
float width = ImGui::GetContentRegionAvailWidth();
|
||||||
@@ -594,3 +657,32 @@ void EditorSystem::changeParent(EntityID entity, EntityID newParent)
|
|||||||
|
|
||||||
m_World->SetParent(entity, newParent);
|
m_World->SetParent(entity, newParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorSystem::fileImport(World* world)
|
||||||
|
{
|
||||||
|
m_CurrentFile = openDialog(m_DefaultEntityDir);
|
||||||
|
auto file = ResourceManager::Load<EntityFile>(m_CurrentFile.string());
|
||||||
|
//EntityFilePreprocessor fpp(file);
|
||||||
|
//fpp.RegisterComponents(world);
|
||||||
|
EntityFileParser fp(file);
|
||||||
|
fp.MergeEntities(world);
|
||||||
|
createWidget();
|
||||||
|
updateWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorSystem::fileSave(World* world)
|
||||||
|
{
|
||||||
|
if (boost::filesystem::exists(m_CurrentFile)) {
|
||||||
|
EntityFileWriter writer(m_CurrentFile.string());
|
||||||
|
writer.WriteWorld(world);
|
||||||
|
} else {
|
||||||
|
fileSaveAs(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorSystem::fileSaveAs(World* world)
|
||||||
|
{
|
||||||
|
auto filePath = saveDialog(m_DefaultEntityDir);
|
||||||
|
EntityFileWriter writer(filePath.string());
|
||||||
|
writer.WriteWorld(world);
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,16 +27,16 @@ glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity)
|
|||||||
{
|
{
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
|
|
||||||
do {
|
while (entity != EntityID_Invalid) {
|
||||||
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
||||||
EntityID parent = world->GetParent(entity);
|
EntityID parent = world->GetParent(entity);
|
||||||
if (parent != 0) {
|
//if (parent != EntityID_Invalid) {
|
||||||
position += AbsoluteOrientation(world, parent) * (glm::vec3)transform["Position"];
|
position += AbsoluteOrientation(world, parent) * (glm::vec3)transform["Position"];
|
||||||
} else {
|
//} else {
|
||||||
position += (glm::vec3)transform["Position"];
|
// position += (glm::vec3)transform["Position"];
|
||||||
}
|
//}
|
||||||
entity = parent;
|
entity = parent;
|
||||||
} while (entity != 0);
|
}
|
||||||
|
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@@ -45,11 +45,11 @@ glm::quat RenderQueueFactory::AbsoluteOrientation(World* world, EntityID entity)
|
|||||||
{
|
{
|
||||||
glm::quat orientation;
|
glm::quat orientation;
|
||||||
|
|
||||||
do {
|
while (entity != EntityID_Invalid) {
|
||||||
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
||||||
orientation = glm::quat((glm::vec3)transform["Orientation"]) * orientation;
|
orientation = glm::quat((glm::vec3)transform["Orientation"]) * orientation;
|
||||||
entity = world->GetParent(entity);
|
entity = world->GetParent(entity);
|
||||||
} while (entity != 0);
|
}
|
||||||
|
|
||||||
return orientation;
|
return orientation;
|
||||||
}
|
}
|
||||||
@@ -58,11 +58,11 @@ glm::vec3 RenderQueueFactory::AbsoluteScale(World* world, EntityID entity)
|
|||||||
{
|
{
|
||||||
glm::vec3 scale(1.f);
|
glm::vec3 scale(1.f);
|
||||||
|
|
||||||
do {
|
while (entity != EntityID_Invalid) {
|
||||||
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
ComponentWrapper transform = world->GetComponent(entity, "Transform");
|
||||||
scale *= (glm::vec3)transform["Scale"];
|
scale *= (glm::vec3)transform["Scale"];
|
||||||
entity = world->GetParent(entity);
|
entity = world->GetParent(entity);
|
||||||
} while (entity != 0);
|
}
|
||||||
|
|
||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-5
@@ -52,11 +52,8 @@ Game::Game(int argc, char* argv[])
|
|||||||
auto file = ResourceManager::Load<EntityFile>(mapToLoad);
|
auto file = ResourceManager::Load<EntityFile>(mapToLoad);
|
||||||
EntityFilePreprocessor fpp(file);
|
EntityFilePreprocessor fpp(file);
|
||||||
fpp.RegisterComponents(m_World);
|
fpp.RegisterComponents(m_World);
|
||||||
EntityFileParser fp(file);
|
//EntityFileParser fp(file);
|
||||||
fp.MergeEntities(m_World);
|
//fp.MergeEntities(m_World);
|
||||||
|
|
||||||
EntityFileWriter writer("Testasdasdasd.xml");
|
|
||||||
writer.WriteWorld(m_World);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create system pipeline
|
// Create system pipeline
|
||||||
|
|||||||
Reference in New Issue
Block a user