Merge pull request #105 from SHADE-DP/SP3-4-editor_fix
Add Editor Features - Transform Gizmo Added transform gizmo (UPDATE IMGUIZMO DEPENDENCY) Small tweaks and fixes to editor
This commit is contained in:
commit
eba318c54d
Binary file not shown.
|
@ -1,48 +0,0 @@
|
||||||
[Window][MainStatusBar]
|
|
||||||
Pos=0,1060
|
|
||||||
Size=1920,20
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][SHEditorMenuBar]
|
|
||||||
Pos=0,48
|
|
||||||
Size=1920,1012
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Hierarchy Panel]
|
|
||||||
Pos=0,142
|
|
||||||
Size=571,918
|
|
||||||
Collapsed=0
|
|
||||||
DockId=0x00000004,0
|
|
||||||
|
|
||||||
[Window][Debug##Default]
|
|
||||||
Pos=60,60
|
|
||||||
Size=400,400
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Inspector]
|
|
||||||
Pos=1649,48
|
|
||||||
Size=271,1012
|
|
||||||
Collapsed=0
|
|
||||||
DockId=0x00000006,0
|
|
||||||
|
|
||||||
[Window][Profiler]
|
|
||||||
Pos=0,48
|
|
||||||
Size=571,92
|
|
||||||
Collapsed=0
|
|
||||||
DockId=0x00000003,0
|
|
||||||
|
|
||||||
[Window][Viewport]
|
|
||||||
Pos=573,48
|
|
||||||
Size=1074,1012
|
|
||||||
Collapsed=0
|
|
||||||
DockId=0x00000002,0
|
|
||||||
|
|
||||||
[Docking][Data]
|
|
||||||
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X
|
|
||||||
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1992,1036 Split=X
|
|
||||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=571,1036 Split=Y Selected=0x1E6EB881
|
|
||||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881
|
|
||||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE
|
|
||||||
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1074,1036 CentralNode=1 Selected=0x13926F0B
|
|
||||||
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=271,1036 Selected=0xE7039252
|
|
||||||
|
|
|
@ -149,11 +149,10 @@ namespace Sandbox
|
||||||
SHSceneManager::SceneUpdate(0.016f);
|
SHSceneManager::SceneUpdate(0.016f);
|
||||||
#endif
|
#endif
|
||||||
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
||||||
editor->PollPicking();
|
//editor->PollPicking();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish all graphics jobs first
|
// Finish all graphics jobs first
|
||||||
graphicsSystem->AwaitGraphicsExecution();
|
graphicsSystem->AwaitGraphicsExecution();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,6 @@ namespace SHADE
|
||||||
|
|
||||||
target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
|
target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
|
||||||
target =SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
|
target =SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
|
||||||
std::cout << "Target vec: " << target.x<<", "<<target.y<<", "<<target.z << std::endl;
|
|
||||||
target += camera.position;
|
target += camera.position;
|
||||||
////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll));
|
////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll));
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace SHADE
|
||||||
class SHCommand : SHBaseCommand
|
class SHCommand : SHBaseCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using SHCommandPtr = std::unique_ptr<T>;
|
||||||
typedef std::function<void(T const&)> SetterFunction;
|
typedef std::function<void(T const&)> SetterFunction;
|
||||||
|
|
||||||
SHCommand(T const& oldVal, T const& value, SetterFunction setFnc)
|
SHCommand(T const& oldVal, T const& value, SetterFunction setFnc)
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace SHADE
|
||||||
SHCommandManager::CommandStack SHCommandManager::undoStack{};
|
SHCommandManager::CommandStack SHCommandManager::undoStack{};
|
||||||
SHCommandManager::CommandStack SHCommandManager::redoStack{};
|
SHCommandManager::CommandStack SHCommandManager::redoStack{};
|
||||||
|
|
||||||
void SHCommandManager::PerformCommand(CommandPtr commandPtr, bool const& overrideValue)
|
void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
|
||||||
{
|
{
|
||||||
redoStack = CommandStack();
|
redoStack = CommandStack();
|
||||||
commandPtr->Execute();
|
commandPtr->Execute();
|
||||||
|
@ -27,9 +27,9 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::RegisterCommand(CommandPtr commandPtr)
|
void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr)
|
||||||
{
|
{
|
||||||
undoStack.push(commandPtr);
|
undoStack.push(commandPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::UndoCommand()
|
void SHCommandManager::UndoCommand()
|
||||||
|
@ -59,4 +59,14 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return redoStack.size();
|
return redoStack.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHCommandManager::PopLatestCommandFromRedoStack()
|
||||||
|
{
|
||||||
|
redoStack.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCommandManager::PopLatestCommandFromUndoStack()
|
||||||
|
{
|
||||||
|
undoStack.pop();
|
||||||
|
}
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -19,16 +19,21 @@ namespace SHADE
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Type Aliases ||
|
//|| Type Aliases ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
using CommandPtr = std::shared_ptr<SHBaseCommand>;
|
using BaseCommandPtr = std::shared_ptr<SHBaseCommand>;
|
||||||
using CommandStack = std::stack<CommandPtr>;
|
template<typename T>
|
||||||
|
using SHCommandPtr = std::shared_ptr<SHCommand<T>>;
|
||||||
|
using CommandStack = std::stack<BaseCommandPtr>;
|
||||||
|
|
||||||
static void PerformCommand(CommandPtr commandPtr, bool const& overrideValue = false);
|
static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false);
|
||||||
static void RegisterCommand(CommandPtr commandPtr);
|
static void RegisterCommand(BaseCommandPtr commandPtr);
|
||||||
static void UndoCommand();
|
static void UndoCommand();
|
||||||
static void RedoCommand();
|
static void RedoCommand();
|
||||||
static std::size_t GetUndoStackSize();
|
static std::size_t GetUndoStackSize();
|
||||||
static std::size_t GetRedoStackSize();
|
static std::size_t GetRedoStackSize();
|
||||||
|
|
||||||
|
static void PopLatestCommandFromRedoStack();
|
||||||
|
static void PopLatestCommandFromUndoStack();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static CommandStack undoStack;
|
static CommandStack undoStack;
|
||||||
static CommandStack redoStack;
|
static CommandStack redoStack;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
#include "Serialization/SHSerialization.h"
|
#include "Serialization/SHSerialization.h"
|
||||||
|
#include "Tools/SHClipboardUtilities.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -52,6 +53,7 @@ namespace SHADE
|
||||||
if(const auto root = sceneGraph.GetRoot())
|
if(const auto root = sceneGraph.GetRoot())
|
||||||
{
|
{
|
||||||
auto const& children = root->GetChildren();
|
auto const& children = root->GetChildren();
|
||||||
|
|
||||||
for (const auto child : children)
|
for (const auto child : children)
|
||||||
{
|
{
|
||||||
RecursivelyDrawEntityNode(child);
|
RecursivelyDrawEntityNode(child);
|
||||||
|
@ -79,6 +81,8 @@ namespace SHADE
|
||||||
|
|
||||||
void SHHierarchyPanel::SetScrollTo(EntityID eid)
|
void SHHierarchyPanel::SetScrollTo(EntityID eid)
|
||||||
{
|
{
|
||||||
|
if(eid == MAX_EID)
|
||||||
|
return;
|
||||||
scrollTo = eid;
|
scrollTo = eid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +108,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
if (ImGui::SmallButton(ICON_MD_ADD_CIRCLE))
|
if (ImGui::SmallButton(ICON_MD_ADD_CIRCLE))
|
||||||
{
|
{
|
||||||
SHEntityManager::CreateEntity();
|
SHCommandManager::PerformCommand(std::make_shared<SHCreateEntityCommand>());
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
{
|
{
|
||||||
|
@ -144,23 +148,32 @@ namespace SHADE
|
||||||
|
|
||||||
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
|
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
|
||||||
//Draw Node
|
//Draw Node
|
||||||
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(entity), nodeFlags, "%u: %s", EntityHandleGenerator::GetIndex(eid), entity->name.c_str());
|
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(entity), nodeFlags, "%u: %s", SHEntityManager::GetEntityIndex(eid), entity->name.c_str());
|
||||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
|
||||||
//Check For Begin Drag
|
//Check For Begin Drag
|
||||||
if (SHDragDrop::BeginSource())
|
if (SHDragDrop::BeginSource())
|
||||||
{
|
{
|
||||||
ImGui::Text("Moving EID: %zu", eid);
|
std::string moveLabel = "Moving EID: ";
|
||||||
SHDragDrop::SetPayload<EntityID>(DRAG_EID, &eid);
|
if(!isSelected)
|
||||||
|
editor->selectedEntities.push_back(eid);
|
||||||
|
for(int i = 0; i < static_cast<int>(editor->selectedEntities.size()); ++i)
|
||||||
|
{
|
||||||
|
moveLabel.append(std::to_string(editor->selectedEntities[i]));
|
||||||
|
if(i + 1 < static_cast<int>(editor->selectedEntities.size()))
|
||||||
|
{
|
||||||
|
moveLabel.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::Text(moveLabel.c_str());
|
||||||
|
SHDragDrop::SetPayload<std::vector<EntityID>>(DRAG_EID, &editor->selectedEntities);
|
||||||
SHDragDrop::EndSource();
|
SHDragDrop::EndSource();
|
||||||
}
|
}
|
||||||
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
|
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
|
||||||
{
|
{
|
||||||
if (const EntityID* eidPayload = SHDragDrop::AcceptPayload<EntityID>(DRAG_EID)) //If payload is valid
|
if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(DRAG_EID)) //If payload is valid
|
||||||
{
|
{
|
||||||
EntityID const dropEID = *eidPayload;
|
ParentSelectedEntities(eid);
|
||||||
if(!sceneGraph.GetChild(dropEID, eid))
|
|
||||||
sceneGraph.SetParent(dropEID, eid); //Set dropEID parent to eid (belonging to current Node)
|
|
||||||
SHDragDrop::EndTarget();
|
SHDragDrop::EndTarget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,7 +188,15 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
if(ImGui::Selectable("Copy"))
|
if(ImGui::Selectable("Copy"))
|
||||||
{
|
{
|
||||||
SHLOG_INFO(SHSerialization::SerializeEntitiesToString(editor->selectedEntities))
|
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(editor->selectedEntities));
|
||||||
|
}
|
||||||
|
if(ImGui::Selectable("Paste"))
|
||||||
|
{
|
||||||
|
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard()));
|
||||||
|
}
|
||||||
|
if(ImGui::Selectable("Paste as Child"))
|
||||||
|
{
|
||||||
|
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), eid));
|
||||||
}
|
}
|
||||||
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
|
||||||
{
|
{
|
||||||
|
@ -184,7 +205,7 @@ namespace SHADE
|
||||||
|
|
||||||
if((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
|
if((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
|
||||||
{
|
{
|
||||||
sceneGraph.SetParent(currentNode->GetEntityID(), nullptr);
|
ParentSelectedEntities(MAX_EID);
|
||||||
}
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
@ -196,7 +217,15 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (!isSelected)
|
if (!isSelected)
|
||||||
{
|
{
|
||||||
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
if(ImGui::IsKeyDown(ImGuiKey_LeftShift))
|
||||||
|
{
|
||||||
|
if(editor->selectedEntities.size() >= 1)
|
||||||
|
{
|
||||||
|
SelectRangeOfEntities(editor->selectedEntities[0], eid);
|
||||||
|
}
|
||||||
|
else editor->selectedEntities.clear();
|
||||||
|
}
|
||||||
|
else if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
editor->selectedEntities.push_back(eid);
|
editor->selectedEntities.push_back(eid);
|
||||||
}//if not selected
|
}//if not selected
|
||||||
|
@ -243,4 +272,90 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID);
|
SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID) const noexcept
|
||||||
|
{
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
auto const editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
SHEntityParentCommand::EntityParentData entityParentData;
|
||||||
|
std::vector<EntityID> parentedEIDS;
|
||||||
|
for(auto const& eid : editor->selectedEntities)
|
||||||
|
{
|
||||||
|
if(sceneGraph.GetChild(eid, parentEID) == nullptr)
|
||||||
|
{
|
||||||
|
parentedEIDS.push_back(eid);
|
||||||
|
if(auto parent = sceneGraph.GetParent(eid))
|
||||||
|
entityParentData[eid].oldParentEID = parent->GetEntityID();
|
||||||
|
entityParentData[eid].newParentEID = parentEID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SHCommandManager::PerformCommand(std::make_shared<SHEntityParentCommand>(parentedEIDS, entityParentData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::SelectRangeOfEntities(EntityID beginEID, EntityID endEID)
|
||||||
|
{
|
||||||
|
bool startSelecting = false; bool endSelecting = false;
|
||||||
|
auto const editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
editor->selectedEntities.clear();
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
||||||
|
{
|
||||||
|
auto eid = nodePtr->GetEntityID();
|
||||||
|
if(!startSelecting)
|
||||||
|
{
|
||||||
|
if(eid == beginEID || eid == endEID)
|
||||||
|
{
|
||||||
|
startSelecting = true;
|
||||||
|
editor->selectedEntities.push_back(eid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!endSelecting)
|
||||||
|
{
|
||||||
|
editor->selectedEntities.push_back(eid);
|
||||||
|
if(eid == endEID || eid == beginEID)
|
||||||
|
{
|
||||||
|
endSelecting = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCreateEntityCommand::Execute()
|
||||||
|
{
|
||||||
|
EntityID newEID = SHEntityManager::CreateEntity(eid);
|
||||||
|
if(eid == MAX_EID)
|
||||||
|
eid = newEID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHCreateEntityCommand::Undo()
|
||||||
|
{
|
||||||
|
SHEntityManager::DestroyEntity(eid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEntityParentCommand::Execute()
|
||||||
|
{
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
for(auto const& eid : entities)
|
||||||
|
{
|
||||||
|
if(entityParentData[eid].newParentEID == MAX_EID)
|
||||||
|
sceneGraph.SetParent(eid, nullptr);
|
||||||
|
else
|
||||||
|
sceneGraph.SetParent(eid, entityParentData[eid].newParentEID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEntityParentCommand::Undo()
|
||||||
|
{
|
||||||
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
for(auto const& eid : entities)
|
||||||
|
{
|
||||||
|
if(entityParentData[eid].oldParentEID == MAX_EID)
|
||||||
|
sceneGraph.SetParent(eid, nullptr);
|
||||||
|
else
|
||||||
|
sceneGraph.SetParent(eid, entityParentData[eid].oldParentEID);
|
||||||
|
}
|
||||||
|
}
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
#include "ECS_Base/SHECSMacros.h"
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
#include "Editor/Command/SHCommand.hpp"
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SHSceneNode;
|
class SHSceneNode;
|
||||||
|
@ -28,8 +28,40 @@ namespace SHADE
|
||||||
void DrawMenuBar() const noexcept;
|
void DrawMenuBar() const noexcept;
|
||||||
ImRect RecursivelyDrawEntityNode(SHSceneNode*);
|
ImRect RecursivelyDrawEntityNode(SHSceneNode*);
|
||||||
void CreateChildEntity(EntityID parentEID) const noexcept;
|
void CreateChildEntity(EntityID parentEID) const noexcept;
|
||||||
|
void ParentSelectedEntities(EntityID parentEID) const noexcept;
|
||||||
|
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
|
||||||
std::string filter;
|
std::string filter;
|
||||||
bool isAnyNodeSelected = false;
|
bool isAnyNodeSelected = false;
|
||||||
EntityID scrollTo = MAX_EID;
|
EntityID scrollTo = MAX_EID;
|
||||||
};//class SHHierarchyPanel
|
};//class SHHierarchyPanel
|
||||||
|
|
||||||
|
//Might move to a different file
|
||||||
|
class SHCreateEntityCommand final : public SHBaseCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Execute() override;
|
||||||
|
void Undo() override;
|
||||||
|
private:
|
||||||
|
EntityID eid = MAX_EID;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SHEntityParentCommand final : public SHBaseCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
EntityID oldParentEID = MAX_EID;
|
||||||
|
EntityID newParentEID = MAX_EID;
|
||||||
|
};
|
||||||
|
using EntityParentData = std::unordered_map<EntityID, Data>;
|
||||||
|
|
||||||
|
SHEntityParentCommand(std::vector<EntityID> entityIDs, EntityParentData inEntityParentData):entities(entityIDs),entityParentData(inEntityParentData){}
|
||||||
|
|
||||||
|
void Execute() override;
|
||||||
|
void Undo() override;
|
||||||
|
private:
|
||||||
|
std::vector<EntityID> entities;
|
||||||
|
std::unordered_map<EntityID, Data> entityParentData;
|
||||||
|
};
|
||||||
|
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
|
#include "Editor/IconsFontAwesome6.h"
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include "Editor/SHEditorWidgets.hpp"
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
#include "Physics/Components/SHColliderComponent.h"
|
#include "Physics/Components/SHColliderComponent.h"
|
||||||
|
@ -216,7 +217,7 @@ namespace SHADE
|
||||||
|
|
||||||
if (collider.GetType() == SHCollider::Type::BOX)
|
if (collider.GetType() == SHCollider::Type::BOX)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_MD_VIEW_IN_AR, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
auto box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
auto box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
|
||||||
SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);});
|
SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);});
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,11 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
EntityID const& eid = editor->selectedEntities[0];
|
EntityID const& eid = editor->selectedEntities[0];
|
||||||
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
||||||
|
if(!entity)
|
||||||
|
{
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); });
|
SHEditorWidgets::CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); });
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Editor/Command/SHCommandManager.h"
|
||||||
#include "FRC/SHFramerateController.h"
|
#include "FRC/SHFramerateController.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -38,6 +39,11 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
ImGui::PlotLines("DT", frames.data(), static_cast<int>(frames.size()), 0, nullptr, 0.0f, 16.0f);
|
ImGui::PlotLines("DT", frames.data(), static_cast<int>(frames.size()), 0, nullptr, 0.0f, 16.0f);
|
||||||
}
|
}
|
||||||
|
if(ImGui::CollapsingHeader("Command Manager"))
|
||||||
|
{
|
||||||
|
ImGui::Text("Undo: %zu", SHCommandManager::GetUndoStackSize());
|
||||||
|
ImGui::Text("Redo: %zu", SHCommandManager::GetRedoStackSize());
|
||||||
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,12 @@ namespace SHADE
|
||||||
bool result = ImGui::Begin(windowName.data(), &isOpen, windowFlags);
|
bool result = ImGui::Begin(windowName.data(), &isOpen, windowFlags);
|
||||||
|
|
||||||
auto wndSize = ImGui::GetWindowSize();
|
auto wndSize = ImGui::GetWindowSize();
|
||||||
if(windowSize.x != wndSize.x || windowSize.y != wndSize.y)
|
auto contentRegionAvail = ImGui::GetContentRegionAvail();
|
||||||
|
if( beginContentRegionAvailable.x != contentRegionAvail.x || beginContentRegionAvailable.y != contentRegionAvail.y || windowSize.x != wndSize.x || windowSize.y != wndSize.y)
|
||||||
{
|
{
|
||||||
windowSize = {wndSize.x, wndSize.y};
|
windowSize = {wndSize.x, wndSize.y};
|
||||||
|
beginContentRegionAvailable = {contentRegionAvail.x, contentRegionAvail.y};
|
||||||
|
|
||||||
OnResize();
|
OnResize();
|
||||||
}
|
}
|
||||||
auto wndPos = ImGui::GetWindowPos();
|
auto wndPos = ImGui::GetWindowPos();
|
||||||
|
|
|
@ -26,6 +26,10 @@ namespace SHADE
|
||||||
bool isOpen;
|
bool isOpen;
|
||||||
bool isWindowHovered;
|
bool isWindowHovered;
|
||||||
std::string_view windowName;
|
std::string_view windowName;
|
||||||
|
SHVec2 windowSize;
|
||||||
|
SHVec2 windowPos;
|
||||||
|
SHVec2 viewportMousePos;
|
||||||
|
SHVec2 beginContentRegionAvailable;
|
||||||
protected:
|
protected:
|
||||||
virtual bool Begin();
|
virtual bool Begin();
|
||||||
virtual void OnResize();
|
virtual void OnResize();
|
||||||
|
@ -33,8 +37,6 @@ namespace SHADE
|
||||||
|
|
||||||
ImGuiWindowFlags windowFlags = 0;
|
ImGuiWindowFlags windowFlags = 0;
|
||||||
ImGuiIO& io;
|
ImGuiIO& io;
|
||||||
SHVec2 windowSize;
|
|
||||||
SHVec2 windowPos;
|
|
||||||
SHVec2 viewportMousePos;
|
|
||||||
};//class SHEditorWindow
|
};//class SHEditorWindow
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -1,17 +1,23 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
#include "SHEditorViewport.h"
|
#include "SHEditorViewport.h"
|
||||||
|
|
||||||
|
#include "ImGuizmo.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
#include "Editor/SHEditor.hpp"
|
#include "Editor/SHEditor.hpp"
|
||||||
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
|
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
||||||
|
#include <Editor/IconsFontAwesome6.h>
|
||||||
|
|
||||||
|
constexpr std::string_view windowName = "\xef\x80\x95 Viewport";
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHEditorViewport::SHEditorViewport()
|
SHEditorViewport::SHEditorViewport()
|
||||||
:SHEditorWindow("Viewport", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar)
|
:SHEditorWindow("\xee\x90\x8b Viewport", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,31 +32,30 @@ namespace SHADE
|
||||||
SHEditorWindow::Update();
|
SHEditorWindow::Update();
|
||||||
if(Begin())
|
if(Begin())
|
||||||
{
|
{
|
||||||
|
ImGuizmo::SetDrawlist();
|
||||||
DrawMenuBar();
|
DrawMenuBar();
|
||||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||||
auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
|
auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
|
||||||
auto mousePos = ImGui::GetMousePos();
|
auto mousePos = ImGui::GetMousePos();
|
||||||
auto cursorPos = ImGui::GetCursorScreenPos();
|
beginCursorPos = ImGui::GetCursorScreenPos();
|
||||||
viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y};
|
viewportMousePos = {mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y};
|
||||||
gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos);
|
gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos);
|
||||||
//if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
|
||||||
//{
|
|
||||||
// auto eid = gfxSystem->GetMousePickSystem ()->GetPickedEntity();
|
|
||||||
// if(eid != MAX_EID)
|
|
||||||
// {
|
|
||||||
// auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
// editor->selectedEntities.clear();
|
|
||||||
// editor->selectedEntities.push_back(eid);
|
|
||||||
// if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow<SHHierarchyPanel>())
|
|
||||||
// {
|
|
||||||
// hierarchyPanel->SetScrollTo(eid);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize());
|
ImGui::Image((ImTextureID)descriptorSet, {beginContentRegionAvailable.x, beginContentRegionAvailable.y});
|
||||||
|
|
||||||
|
if(ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right))
|
||||||
|
{
|
||||||
|
ImGui::SetMouseCursor(ImGuiMouseCursor_None);
|
||||||
|
ImGui::SetCursorScreenPos(ImGui::GetMousePos());
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiColors::green);
|
||||||
|
ImGui::Text(ICON_FA_EYE);
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
ImGuizmo::SetRect(beginCursorPos.x , beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
|
||||||
|
transformGizmo.Draw();
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditorViewport::Exit()
|
void SHEditorViewport::Exit()
|
||||||
|
@ -66,7 +71,11 @@ namespace SHADE
|
||||||
|
|
||||||
//auto pos = ImGui::GetCursorPos();
|
//auto pos = ImGui::GetCursorPos();
|
||||||
//windowCursorPos = {}
|
//windowCursorPos = {}
|
||||||
gfxSystem->PrepareResize(static_cast<uint32_t>(windowSize.x), static_cast<uint32_t>(windowSize.y));
|
if(beginContentRegionAvailable.x == 0 || beginContentRegionAvailable.y == 0)
|
||||||
|
{
|
||||||
|
beginContentRegionAvailable = windowSize;
|
||||||
|
}
|
||||||
|
gfxSystem->PrepareResize(static_cast<uint32_t>(beginContentRegionAvailable.x), static_cast<uint32_t>(beginContentRegionAvailable.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditorViewport::OnPosChange()
|
void SHEditorViewport::OnPosChange()
|
||||||
|
@ -74,10 +83,46 @@ namespace SHADE
|
||||||
SHEditorWindow::OnPosChange();
|
SHEditorWindow::OnPosChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditorViewport::DrawMenuBar() const noexcept
|
void SHEditorViewport::DrawMenuBar() noexcept
|
||||||
{
|
{
|
||||||
if(ImGui::BeginMenuBar())
|
if(ImGui::BeginMenuBar())
|
||||||
{
|
{
|
||||||
|
bool const isTranslate = transformGizmo.operation == SHTransformGizmo::Operation::TRANSLATE;
|
||||||
|
ImGui::BeginDisabled(isTranslate);
|
||||||
|
if(isTranslate)
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
|
||||||
|
if(ImGui::Button(ICON_MD_OPEN_WITH))
|
||||||
|
{
|
||||||
|
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
if(isTranslate)
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
|
bool const isRotate = transformGizmo.operation == SHTransformGizmo::Operation::ROTATE;
|
||||||
|
ImGui::BeginDisabled(isRotate);
|
||||||
|
if(isRotate)
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
|
||||||
|
if(ImGui::Button(ICON_MD_AUTORENEW))
|
||||||
|
{
|
||||||
|
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
if(isRotate)
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
|
bool const isScale = transformGizmo.operation == SHTransformGizmo::Operation::SCALE;
|
||||||
|
ImGui::BeginDisabled(isScale);
|
||||||
|
if(isScale)
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_CheckMark]);
|
||||||
|
if(ImGui::Button(ICON_MD_EXPAND))
|
||||||
|
{
|
||||||
|
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
if(isScale)
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
ImGui::EndMenuBar();
|
ImGui::EndMenuBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
#include "ECS_Base/SHECSMacros.h"
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
#include "Editor/Gizmos/SHTransformGizmo.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -20,10 +21,12 @@ namespace SHADE
|
||||||
void Init() override;
|
void Init() override;
|
||||||
void Update() override;
|
void Update() override;
|
||||||
void Exit() override;
|
void Exit() override;
|
||||||
|
SHTransformGizmo transformGizmo;
|
||||||
protected:
|
protected:
|
||||||
void OnResize() override;
|
void OnResize() override;
|
||||||
void OnPosChange() override;
|
void OnPosChange() override;
|
||||||
private:
|
private:
|
||||||
void DrawMenuBar() const noexcept;
|
void DrawMenuBar() noexcept;
|
||||||
|
SHVec2 beginCursorPos;
|
||||||
};//class SHEditorViewport
|
};//class SHEditorViewport
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHTransformGizmo.h"
|
||||||
|
|
||||||
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Editor/SHEditor.hpp"
|
||||||
|
#include "Editor/SHImGuiHelpers.hpp"
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <ImGuizmo.h>
|
||||||
|
|
||||||
|
#include "Camera/SHCameraSystem.h"
|
||||||
|
#include "Editor/Command/SHCommandManager.h"
|
||||||
|
#include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h"
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
void SHTransformGizmo::Draw()
|
||||||
|
{
|
||||||
|
bool justChangedTfm = false;
|
||||||
|
if (!editorCamera)
|
||||||
|
{
|
||||||
|
auto const cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
|
editorCamera = cameraSystem->GetEditorCamera();
|
||||||
|
}
|
||||||
|
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
|
||||||
|
ImGuizmo::SetOrthographic(false);
|
||||||
|
|
||||||
|
SHMatrix view = SHMatrix::Transpose(editorCamera->GetViewMatrix());
|
||||||
|
SHMatrix proj = SHMatrix::Transpose(editorCamera->GetProjMatrix());
|
||||||
|
proj(1, 1) *= -1;
|
||||||
|
static SHMatrix gridMat = SHMatrix::Translate(0, -0.5f, 0.f) * SHMatrix::Identity;
|
||||||
|
//ImGuizmo::DrawGrid(&view._11, &proj._11, &gridMat._11, 100.f);
|
||||||
|
if (selectedEntityTransformComponent == nullptr)
|
||||||
|
{
|
||||||
|
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (editor->selectedEntities.empty())
|
||||||
|
return;
|
||||||
|
EntityID eid = editor->selectedEntities.back();
|
||||||
|
selectedEntityTransformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
|
||||||
|
justChangedTfm = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (editor->selectedEntities.empty())
|
||||||
|
return;
|
||||||
|
EntityID eid = editor->selectedEntities.back();
|
||||||
|
auto tfmComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
|
||||||
|
if (selectedEntityTransformComponent != tfmComponent)
|
||||||
|
{
|
||||||
|
selectedEntityTransformComponent = tfmComponent;
|
||||||
|
justChangedTfm = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (selectedEntityTransformComponent == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SHMatrix mat = selectedEntityTransformComponent->GetTRS();
|
||||||
|
isManipulating = ImGuizmo::Manipulate(&view._11, &proj._11, static_cast<ImGuizmo::OPERATION>(operation), ImGuizmo::MODE::WORLD, &mat._11);
|
||||||
|
if (!justChangedTfm)
|
||||||
|
{
|
||||||
|
if (ImGui::IsItemClicked())
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHMatrix>>(selectedEntityTransformComponent->GetTRS(), mat, [tfm = std::move(selectedEntityTransformComponent)](SHMatrix const& mtx)
|
||||||
|
{
|
||||||
|
if (!tfm)
|
||||||
|
return;
|
||||||
|
SHVec3 translate{}, rotate{}, scale{};
|
||||||
|
mtx.Decompose(translate, rotate, scale);
|
||||||
|
tfm->SetWorldPosition(translate);
|
||||||
|
tfm->SetWorldRotation(rotate);
|
||||||
|
tfm->SetWorldScale(scale);
|
||||||
|
})));
|
||||||
|
else if (ImGui::IsItemHovered(ImGuiMouseButton_Left) && ImGui::IsMouseDown(ImGuiMouseButton_Left) && isManipulating)
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<SHMatrix>>(selectedEntityTransformComponent->GetTRS(), mat, [tfm = std::move(selectedEntityTransformComponent)](SHMatrix const& mtx)
|
||||||
|
{
|
||||||
|
if (!tfm)
|
||||||
|
return;
|
||||||
|
SHVec3 translate{}, rotate{}, scale{};
|
||||||
|
mtx.Decompose(translate, rotate, scale);
|
||||||
|
tfm->SetWorldPosition(translate);
|
||||||
|
tfm->SetWorldRotation(rotate);
|
||||||
|
tfm->SetWorldScale(scale);
|
||||||
|
})), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Camera/SHCameraComponent.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHTransformGizmo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class Mode
|
||||||
|
{
|
||||||
|
WORLD,
|
||||||
|
LOCAL
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Operation
|
||||||
|
{
|
||||||
|
TRANSLATE_X = (1u << 0),
|
||||||
|
TRANSLATE_Y = (1u << 1),
|
||||||
|
TRANSLATE_Z = (1u << 2),
|
||||||
|
ROTATE_X = (1u << 3),
|
||||||
|
ROTATE_Y = (1u << 4),
|
||||||
|
ROTATE_Z = (1u << 5),
|
||||||
|
ROTATE_SCREEN = (1u << 6),
|
||||||
|
SCALE_X = (1u << 7),
|
||||||
|
SCALE_Y = (1u << 8),
|
||||||
|
SCALE_Z = (1u << 9),
|
||||||
|
BOUNDS = (1u << 10),
|
||||||
|
SCALE_XU = (1u << 11),
|
||||||
|
SCALE_YU = (1u << 12),
|
||||||
|
SCALE_ZU = (1u << 13),
|
||||||
|
|
||||||
|
TRANSLATE = TRANSLATE_X | TRANSLATE_Y | TRANSLATE_Z,
|
||||||
|
ROTATE = ROTATE_X | ROTATE_Y | ROTATE_Z | ROTATE_SCREEN,
|
||||||
|
SCALE = SCALE_X | SCALE_Y | SCALE_Z,
|
||||||
|
SCALEU = SCALE_XU | SCALE_YU | SCALE_ZU, // universal
|
||||||
|
UNIVERSAL = TRANSLATE | ROTATE | SCALEU
|
||||||
|
};
|
||||||
|
|
||||||
|
void Draw();
|
||||||
|
bool isManipulating = false;
|
||||||
|
Mode mode = Mode::WORLD;
|
||||||
|
Operation operation = Operation::TRANSLATE;
|
||||||
|
private:
|
||||||
|
SHTransformComponent* selectedEntityTransformComponent{nullptr};
|
||||||
|
SHCameraComponent* editorCamera{nullptr};
|
||||||
|
};
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,7 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
|
|
||||||
#include "IconsMaterialDesign.h"
|
#include "IconsMaterialDesign.h"
|
||||||
|
#include "IconsFontAwesome6.h"
|
||||||
#include "DragDrop/SHDragDrop.hpp"
|
#include "DragDrop/SHDragDrop.hpp"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <rttr/registration>
|
#include <rttr/registration>
|
||||||
|
#include <ImGuizmo.h>
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| ImGui Backend Includes ||
|
//|| ImGui Backend Includes ||
|
||||||
|
@ -87,10 +89,10 @@ namespace SHADE
|
||||||
|
|
||||||
//Add editor windows
|
//Add editor windows
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
|
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
||||||
|
|
||||||
io = &ImGui::GetIO();
|
io = &ImGui::GetIO();
|
||||||
|
|
||||||
|
@ -98,7 +100,7 @@ namespace SHADE
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
||||||
io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini";
|
io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini";
|
||||||
|
io->ConfigWindowsMoveFromTitleBarOnly = true;
|
||||||
InitLayout();
|
InitLayout();
|
||||||
|
|
||||||
InitFonts();
|
InitFonts();
|
||||||
|
@ -127,9 +129,13 @@ namespace SHADE
|
||||||
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
||||||
{
|
{
|
||||||
if(window->isOpen)
|
if(window->isOpen)
|
||||||
|
{
|
||||||
window->Update();
|
window->Update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PollPicking();
|
||||||
|
|
||||||
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||||
{
|
{
|
||||||
SHCommandManager::RedoCommand();
|
SHCommandManager::RedoCommand();
|
||||||
|
@ -165,10 +171,11 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
|
ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
|
||||||
|
|
||||||
constexpr ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
|
|
||||||
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
|
||||||
ImFont* UIFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path
|
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
||||||
|
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
|
||||||
|
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_MD, 0 };
|
||||||
|
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
|
||||||
io->Fonts->Build();
|
io->Fonts->Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +345,7 @@ namespace SHADE
|
||||||
if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>())
|
if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>())
|
||||||
{
|
{
|
||||||
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
|
auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
|
||||||
if (viewportWindow->isWindowHovered && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
if (viewportWindow->isWindowHovered && !viewportWindow->transformGizmo.isManipulating && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
{
|
{
|
||||||
EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity();
|
EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity();
|
||||||
if(pickedEID == MAX_EID)
|
if(pickedEID == MAX_EID)
|
||||||
|
@ -366,6 +373,7 @@ namespace SHADE
|
||||||
ImGui_ImplVulkan_NewFrame();
|
ImGui_ImplVulkan_NewFrame();
|
||||||
ImGui_ImplSDL2_NewFrame();
|
ImGui_ImplSDL2_NewFrame();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
ImGuizmo::BeginFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "EditorWindow/SHEditorWindow.h"
|
#include "EditorWindow/SHEditorWindow.h"
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
|
#include "Gizmos/SHTransformGizmo.h"
|
||||||
|
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
|
@ -200,5 +202,7 @@ namespace SHADE
|
||||||
SDL_Window* sdlWindow {nullptr};
|
SDL_Window* sdlWindow {nullptr};
|
||||||
|
|
||||||
ImGuiIO* io{nullptr};
|
ImGuiIO* io{nullptr};
|
||||||
|
|
||||||
|
//SHTransformGizmo transformGizmo;
|
||||||
};//class SHEditor
|
};//class SHEditor
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#ifndef SH_IM_MATH
|
#ifndef SH_IM_MATH
|
||||||
#define IM_VEC2_CLASS_EXTRA \
|
#define IM_VEC2_CLASS_EXTRA \
|
||||||
ImVec2(const SHADE::SHVec2& vec) {x = vec.x; y = vec.y;} \
|
ImVec2(const SHADE::SHVec2& vec) {x = vec.x; y = vec.y;} \
|
||||||
operator SHADE::SHVec2() const {return SHADE::SHVec2(x,y);}
|
operator SHADE::SHVec2() const {return SHADE::SHVec2(x,y);}
|
||||||
#define IM_VEC3_CLASS_EXTRA \
|
#define IM_VEC3_CLASS_EXTRA \
|
||||||
ImVec3(const SHADE::SHVec3& vec) {x = vec.x; y = vec.y; z = vec.z;} \
|
ImVec3(const SHADE::SHVec3& vec) {x = vec.x; y = vec.y; z = vec.z;} \
|
||||||
|
@ -43,6 +43,10 @@ namespace SHADE
|
||||||
constexpr ImVec4 blue = {0.0f, 0.0f, 1.0f, 1.f};
|
constexpr ImVec4 blue = {0.0f, 0.0f, 1.0f, 1.f};
|
||||||
constexpr ImVec4 white = {1.0f, 1.0f, 1.0f, 1.f};
|
constexpr ImVec4 white = {1.0f, 1.0f, 1.0f, 1.f};
|
||||||
|
|
||||||
|
constexpr int colors_red = 0;
|
||||||
|
constexpr int colors_green = 1;
|
||||||
|
constexpr int colors_blue = 2;
|
||||||
|
constexpr int colors_white = 3;
|
||||||
constexpr ImU32 colors[] = {
|
constexpr ImU32 colors[] = {
|
||||||
0xBB0000FF, // red
|
0xBB0000FF, // red
|
||||||
0xBB00FF00, // green
|
0xBB00FF00, // green
|
||||||
|
|
|
@ -54,11 +54,13 @@ namespace SHADE
|
||||||
out << YAML::EndSeq;
|
out << YAML::EndSeq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector<EntityID>& createdEntities, EntityID parentEID = MAX_EID)
|
static EntityID DeserializeEntity(YAML::iterator& it, YAML::Node const& node, std::vector<EntityID>& createdEntities, EntityID parentEID = MAX_EID)
|
||||||
{
|
{
|
||||||
if (!node[EIDNode])
|
EntityID eid = MAX_EID;
|
||||||
return;
|
if(!node)
|
||||||
EntityID eid = node[EIDNode].as<EntityID>();
|
return eid;
|
||||||
|
if (node[EIDNode])
|
||||||
|
eid = node[EIDNode].as<EntityID>();
|
||||||
std::string name = "Default";
|
std::string name = "Default";
|
||||||
if (node[EntityNameNode])
|
if (node[EntityNameNode])
|
||||||
name = node[EntityNameNode].as<std::string>();
|
name = node[EntityNameNode].as<std::string>();
|
||||||
|
@ -117,7 +119,11 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DeserializeEntity(it, (*it), createdEntities);
|
DeserializeEntity(it, (*it), createdEntities);
|
||||||
}
|
}
|
||||||
|
if(createdEntities.empty())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
||||||
|
return;
|
||||||
|
}
|
||||||
//Initialize Entity
|
//Initialize Entity
|
||||||
auto entityVecIt = createdEntities.begin();
|
auto entityVecIt = createdEntities.begin();
|
||||||
for (auto it = entities.begin(); it != entities.end(); ++it)
|
for (auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
|
@ -136,17 +142,19 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SHSerialization::SerializeEntitiesToString(std::vector<EntityID> const& entities)
|
std::string SHSerialization::SerializeEntitiesToString(std::vector<EntityID> const& entities) noexcept
|
||||||
{
|
{
|
||||||
YAML::Emitter out;
|
YAML::Emitter out;
|
||||||
YAML::Node node;
|
YAML::Node node;
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
|
out << YAML::BeginSeq;
|
||||||
for (auto const& eid : entities)
|
for (auto const& eid : entities)
|
||||||
{
|
{
|
||||||
auto entityNode = sceneGraph.GetNode(eid);
|
auto entityNode = sceneGraph.GetNode(eid);
|
||||||
EmitEntity(entityNode, out);
|
EmitEntity(entityNode, out);
|
||||||
}
|
}
|
||||||
return std::basic_string<char>(out.c_str());
|
out << YAML::EndSeq;
|
||||||
|
return std::string(out.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path)
|
void SHSerialization::SerializeEntityToFile(std::filesystem::path const& path)
|
||||||
|
@ -193,6 +201,30 @@ namespace SHADE
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityID SHSerialization::DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID) noexcept
|
||||||
|
{
|
||||||
|
if(data.empty())
|
||||||
|
return MAX_EID;
|
||||||
|
YAML::Node entities = YAML::Load(data.c_str());
|
||||||
|
EntityID eid{MAX_EID};
|
||||||
|
std::vector<EntityID> createdEntities;
|
||||||
|
for(auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
|
{
|
||||||
|
eid = DeserializeEntity(it, *it, createdEntities, parentEID);
|
||||||
|
}
|
||||||
|
if(createdEntities.empty())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
||||||
|
return MAX_EID;
|
||||||
|
}
|
||||||
|
auto entityVecIt = createdEntities.begin();
|
||||||
|
for(auto it = entities.begin(); it != entities.end(); ++it)
|
||||||
|
{
|
||||||
|
InitializeEntity(*it, *entityVecIt++);
|
||||||
|
}
|
||||||
|
return eid;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
std::optional<ComponentTypeID> GetComponentID(YAML::Node const& componentNode)
|
std::optional<ComponentTypeID> GetComponentID(YAML::Node const& componentNode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,14 +29,18 @@ namespace SHADE
|
||||||
static void SerializeSceneToFile(std::filesystem::path const& path);
|
static void SerializeSceneToFile(std::filesystem::path const& path);
|
||||||
static std::string SerializeSceneToString();
|
static std::string SerializeSceneToString();
|
||||||
static void SerializeSceneToEmitter(YAML::Emitter& out);
|
static void SerializeSceneToEmitter(YAML::Emitter& out);
|
||||||
|
|
||||||
static void DeserializeSceneFromFile(std::filesystem::path const& path);
|
static void DeserializeSceneFromFile(std::filesystem::path const& path);
|
||||||
|
|
||||||
|
|
||||||
static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out);
|
static void EmitEntity(SHSceneNode* entityNode, YAML::Emitter& out);
|
||||||
static std::string SerializeEntitiesToString(std::vector<EntityID> const& entities);
|
|
||||||
|
static std::string SerializeEntitiesToString(std::vector<EntityID> const& entities) noexcept;
|
||||||
static void SerializeEntityToFile(std::filesystem::path const& path);
|
static void SerializeEntityToFile(std::filesystem::path const& path);
|
||||||
static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode);
|
static YAML::Node SerializeEntityToNode(SHSceneNode* sceneNode);
|
||||||
|
|
||||||
|
static EntityID DeserializeEntitiesFromString(std::string const& data, EntityID const& parentEID = MAX_EID) noexcept;
|
||||||
|
|
||||||
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
|
static std::vector<ComponentTypeID> GetComponentIDList(YAML::Node const& componentsNode);
|
||||||
private:
|
private:
|
||||||
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
|
static void InitializeEntity(YAML::Node const& entityNode, EntityID const& eid);
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHClipboardUtilities.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
void SHClipboardUtilities::WriteToClipboard(std::string const& str) noexcept
|
||||||
|
{
|
||||||
|
if(str.empty())
|
||||||
|
return;
|
||||||
|
HWND const hwnd = GetDesktopWindow();
|
||||||
|
OpenClipboard(hwnd);
|
||||||
|
EmptyClipboard();
|
||||||
|
|
||||||
|
auto const size = str.size() + 1;
|
||||||
|
const HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, size);
|
||||||
|
if(hGlobal)
|
||||||
|
{
|
||||||
|
std::memcpy(GlobalLock(hGlobal), str.c_str(), size);
|
||||||
|
GlobalUnlock(hGlobal);
|
||||||
|
SetClipboardData(CF_TEXT, hGlobal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Failed to write to clipboard: {}", str.c_str())
|
||||||
|
}
|
||||||
|
CloseClipboard();
|
||||||
|
GlobalFree(hGlobal);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const SHClipboardUtilities::GetDataFromClipboard() noexcept
|
||||||
|
{
|
||||||
|
HWND const hwnd = GetDesktopWindow();
|
||||||
|
if(!OpenClipboard(hwnd))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Failed to open clipboard")
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(HANDLE const dataHandle = GetClipboardData(CF_TEXT); dataHandle)
|
||||||
|
{
|
||||||
|
std::string data(static_cast<char*>(GlobalLock(dataHandle)));
|
||||||
|
GlobalUnlock(dataHandle);
|
||||||
|
CloseClipboard();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
CloseClipboard();
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHClipboardUtilities
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void WriteToClipboard(std::string const& str) noexcept;
|
||||||
|
static std::string const GetDataFromClipboard() noexcept;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue