Restructured Asset Manager with Generalised Template Types for Asset Data #111
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);
|
||||
#endif
|
||||
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
||||
editor->PollPicking();
|
||||
//editor->PollPicking();
|
||||
}
|
||||
|
||||
// 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::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
|
||||
std::cout << "Target vec: " << target.x<<", "<<target.y<<", "<<target.z << std::endl;
|
||||
target += camera.position;
|
||||
////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll));
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace SHADE
|
|||
class SHCommand : SHBaseCommand
|
||||
{
|
||||
public:
|
||||
using SHCommandPtr = std::unique_ptr<T>;
|
||||
typedef std::function<void(T const&)> SetterFunction;
|
||||
|
||||
SHCommand(T const& oldVal, T const& value, SetterFunction setFnc)
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace SHADE
|
|||
SHCommandManager::CommandStack SHCommandManager::undoStack{};
|
||||
SHCommandManager::CommandStack SHCommandManager::redoStack{};
|
||||
|
||||
void SHCommandManager::PerformCommand(CommandPtr commandPtr, bool const& overrideValue)
|
||||
void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
|
||||
{
|
||||
redoStack = CommandStack();
|
||||
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()
|
||||
|
@ -59,4 +59,14 @@ namespace SHADE
|
|||
{
|
||||
return redoStack.size();
|
||||
}
|
||||
|
||||
void SHCommandManager::PopLatestCommandFromRedoStack()
|
||||
{
|
||||
redoStack.pop();
|
||||
}
|
||||
|
||||
void SHCommandManager::PopLatestCommandFromUndoStack()
|
||||
{
|
||||
undoStack.pop();
|
||||
}
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -19,16 +19,21 @@ namespace SHADE
|
|||
//#==============================================================#
|
||||
//|| Type Aliases ||
|
||||
//#==============================================================#
|
||||
using CommandPtr = std::shared_ptr<SHBaseCommand>;
|
||||
using CommandStack = std::stack<CommandPtr>;
|
||||
using BaseCommandPtr = std::shared_ptr<SHBaseCommand>;
|
||||
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 RegisterCommand(CommandPtr commandPtr);
|
||||
static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false);
|
||||
static void RegisterCommand(BaseCommandPtr commandPtr);
|
||||
static void UndoCommand();
|
||||
static void RedoCommand();
|
||||
static std::size_t GetUndoStackSize();
|
||||
static std::size_t GetRedoStackSize();
|
||||
|
||||
static void PopLatestCommandFromRedoStack();
|
||||
static void PopLatestCommandFromUndoStack();
|
||||
|
||||
private:
|
||||
static CommandStack undoStack;
|
||||
static CommandStack redoStack;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <imgui.h>
|
||||
|
||||
#include "Serialization/SHSerialization.h"
|
||||
#include "Tools/SHClipboardUtilities.h"
|
||||
|
||||
|
||||
namespace SHADE
|
||||
|
@ -52,6 +53,7 @@ namespace SHADE
|
|||
if(const auto root = sceneGraph.GetRoot())
|
||||
{
|
||||
auto const& children = root->GetChildren();
|
||||
|
||||
for (const auto child : children)
|
||||
{
|
||||
RecursivelyDrawEntityNode(child);
|
||||
|
@ -79,6 +81,8 @@ namespace SHADE
|
|||
|
||||
void SHHierarchyPanel::SetScrollTo(EntityID eid)
|
||||
{
|
||||
if(eid == MAX_EID)
|
||||
return;
|
||||
scrollTo = eid;
|
||||
}
|
||||
|
||||
|
@ -104,7 +108,7 @@ namespace SHADE
|
|||
}
|
||||
if (ImGui::SmallButton(ICON_MD_ADD_CIRCLE))
|
||||
{
|
||||
SHEntityManager::CreateEntity();
|
||||
SHCommandManager::PerformCommand(std::make_shared<SHCreateEntityCommand>());
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
|
@ -144,23 +148,32 @@ namespace SHADE
|
|||
|
||||
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
|
||||
//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());
|
||||
|
||||
//Check For Begin Drag
|
||||
if (SHDragDrop::BeginSource())
|
||||
{
|
||||
ImGui::Text("Moving EID: %zu", eid);
|
||||
SHDragDrop::SetPayload<EntityID>(DRAG_EID, &eid);
|
||||
std::string moveLabel = "Moving 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();
|
||||
}
|
||||
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;
|
||||
if(!sceneGraph.GetChild(dropEID, eid))
|
||||
sceneGraph.SetParent(dropEID, eid); //Set dropEID parent to eid (belonging to current Node)
|
||||
ParentSelectedEntities(eid);
|
||||
SHDragDrop::EndTarget();
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +188,15 @@ namespace SHADE
|
|||
}
|
||||
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()))
|
||||
{
|
||||
|
@ -184,7 +205,7 @@ namespace SHADE
|
|||
|
||||
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();
|
||||
}
|
||||
|
@ -196,7 +217,15 @@ namespace SHADE
|
|||
{
|
||||
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.push_back(eid);
|
||||
}//if not selected
|
||||
|
@ -243,4 +272,90 @@ namespace SHADE
|
|||
{
|
||||
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
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "imgui_internal.h"
|
||||
#include "ECS_Base/SHECSMacros.h"
|
||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||
|
||||
#include "Editor/Command/SHCommand.hpp"
|
||||
namespace SHADE
|
||||
{
|
||||
class SHSceneNode;
|
||||
|
@ -28,8 +28,40 @@ namespace SHADE
|
|||
void DrawMenuBar() const noexcept;
|
||||
ImRect RecursivelyDrawEntityNode(SHSceneNode*);
|
||||
void CreateChildEntity(EntityID parentEID) const noexcept;
|
||||
void ParentSelectedEntities(EntityID parentEID) const noexcept;
|
||||
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
|
||||
std::string filter;
|
||||
bool isAnyNodeSelected = false;
|
||||
EntityID scrollTo = MAX_EID;
|
||||
};//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
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
//|| SHADE Includes ||
|
||||
//#==============================================================#
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
#include "Editor/IconsFontAwesome6.h"
|
||||
#include "ECS_Base/Components/SHComponent.h"
|
||||
#include "Editor/SHEditorWidgets.hpp"
|
||||
#include "Physics/Components/SHColliderComponent.h"
|
||||
|
@ -216,7 +217,7 @@ namespace SHADE
|
|||
|
||||
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());
|
||||
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];
|
||||
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
||||
|
||||
if(!entity)
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
|
||||
SHEditorWidgets::CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); });
|
||||
ImGui::SameLine();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <imgui.h>
|
||||
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/Command/SHCommandManager.h"
|
||||
#include "FRC/SHFramerateController.h"
|
||||
|
||||
namespace SHADE
|
||||
|
@ -38,6 +39,11 @@ namespace SHADE
|
|||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -43,9 +43,12 @@ namespace SHADE
|
|||
bool result = ImGui::Begin(windowName.data(), &isOpen, windowFlags);
|
||||
|
||||
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};
|
||||
beginContentRegionAvailable = {contentRegionAvail.x, contentRegionAvail.y};
|
||||
|
||||
OnResize();
|
||||
}
|
||||
auto wndPos = ImGui::GetWindowPos();
|
||||
|
|
|
@ -26,6 +26,10 @@ namespace SHADE
|
|||
bool isOpen;
|
||||
bool isWindowHovered;
|
||||
std::string_view windowName;
|
||||
SHVec2 windowSize;
|
||||
SHVec2 windowPos;
|
||||
SHVec2 viewportMousePos;
|
||||
SHVec2 beginContentRegionAvailable;
|
||||
protected:
|
||||
virtual bool Begin();
|
||||
virtual void OnResize();
|
||||
|
@ -33,8 +37,6 @@ namespace SHADE
|
|||
|
||||
ImGuiWindowFlags windowFlags = 0;
|
||||
ImGuiIO& io;
|
||||
SHVec2 windowSize;
|
||||
SHVec2 windowPos;
|
||||
SHVec2 viewportMousePos;
|
||||
|
||||
};//class SHEditorWindow
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
#include "SHpch.h"
|
||||
#include "Editor/SHImGuiHelpers.hpp"
|
||||
#include "SHEditorViewport.h"
|
||||
|
||||
#include "ImGuizmo.h"
|
||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
#include "Editor/IconsMaterialDesign.h"
|
||||
#include "Editor/SHEditor.hpp"
|
||||
#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
||||
#include <Editor/IconsFontAwesome6.h>
|
||||
|
||||
constexpr std::string_view windowName = "\xef\x80\x95 Viewport";
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
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();
|
||||
if(Begin())
|
||||
{
|
||||
ImGuizmo::SetDrawlist();
|
||||
DrawMenuBar();
|
||||
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
|
||||
auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
|
||||
auto mousePos = ImGui::GetMousePos();
|
||||
auto cursorPos = ImGui::GetCursorScreenPos();
|
||||
viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y};
|
||||
beginCursorPos = ImGui::GetCursorScreenPos();
|
||||
viewportMousePos = {mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y};
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
void SHEditorViewport::Exit()
|
||||
|
@ -66,7 +71,11 @@ namespace SHADE
|
|||
|
||||
//auto pos = ImGui::GetCursorPos();
|
||||
//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()
|
||||
|
@ -74,10 +83,46 @@ namespace SHADE
|
|||
SHEditorWindow::OnPosChange();
|
||||
}
|
||||
|
||||
void SHEditorViewport::DrawMenuBar() const noexcept
|
||||
void SHEditorViewport::DrawMenuBar() noexcept
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "imgui_internal.h"
|
||||
#include "ECS_Base/SHECSMacros.h"
|
||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||
#include "Editor/Gizmos/SHTransformGizmo.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
|
@ -20,10 +21,12 @@ namespace SHADE
|
|||
void Init() override;
|
||||
void Update() override;
|
||||
void Exit() override;
|
||||
SHTransformGizmo transformGizmo;
|
||||
protected:
|
||||
void OnResize() override;
|
||||
void OnPosChange() override;
|
||||
private:
|
||||
void DrawMenuBar() const noexcept;
|
||||
void DrawMenuBar() noexcept;
|
||||
SHVec2 beginCursorPos;
|
||||
};//class SHEditorViewport
|
||||
}//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 "IconsMaterialDesign.h"
|
||||
#include "IconsFontAwesome6.h"
|
||||
#include "DragDrop/SHDragDrop.hpp"
|
||||
|
||||
//#==============================================================#
|
||||
|
@ -36,6 +37,7 @@
|
|||
#include <imgui.h>
|
||||
#include <SDL.h>
|
||||
#include <rttr/registration>
|
||||
#include <ImGuizmo.h>
|
||||
|
||||
//#==============================================================#
|
||||
//|| ImGui Backend Includes ||
|
||||
|
@ -87,10 +89,10 @@ namespace SHADE
|
|||
|
||||
//Add editor windows
|
||||
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
|
||||
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
||||
|
||||
io = &ImGui::GetIO();
|
||||
|
||||
|
@ -98,7 +100,7 @@ namespace SHADE
|
|||
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
|
||||
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
|
||||
io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini";
|
||||
|
||||
io->ConfigWindowsMoveFromTitleBarOnly = true;
|
||||
InitLayout();
|
||||
|
||||
InitFonts();
|
||||
|
@ -127,9 +129,13 @@ namespace SHADE
|
|||
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
||||
{
|
||||
if(window->isOpen)
|
||||
{
|
||||
window->Update();
|
||||
}
|
||||
}
|
||||
|
||||
PollPicking();
|
||||
|
||||
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||
{
|
||||
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
|
||||
|
||||
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;
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -338,7 +345,7 @@ namespace SHADE
|
|||
if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>())
|
||||
{
|
||||
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();
|
||||
if(pickedEID == MAX_EID)
|
||||
|
@ -366,6 +373,7 @@ namespace SHADE
|
|||
ImGui_ImplVulkan_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
ImGuizmo::BeginFrame();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include "Resource/SHHandle.h"
|
||||
#include "EditorWindow/SHEditorWindow.h"
|
||||
#include "Tools/SHLogger.h"
|
||||
#include "Gizmos/SHTransformGizmo.h"
|
||||
|
||||
|
||||
//#==============================================================#
|
||||
//|| Library Includes ||
|
||||
|
@ -200,5 +202,7 @@ namespace SHADE
|
|||
SDL_Window* sdlWindow {nullptr};
|
||||
|
||||
ImGuiIO* io{nullptr};
|
||||
|
||||
//SHTransformGizmo transformGizmo;
|
||||
};//class SHEditor
|
||||
}//namespace SHADE
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
//#==============================================================#
|
||||
#ifndef SH_IM_MATH
|
||||
#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);}
|
||||
#define IM_VEC3_CLASS_EXTRA \
|
||||
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 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[] = {
|
||||
0xBB0000FF, // red
|
||||
0xBB00FF00, // green
|
||||
|
|
|
@ -54,11 +54,13 @@ namespace SHADE
|
|||
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])
|
||||
return;
|
||||
EntityID eid = node[EIDNode].as<EntityID>();
|
||||
EntityID eid = MAX_EID;
|
||||
if(!node)
|
||||
return eid;
|
||||
if (node[EIDNode])
|
||||
eid = node[EIDNode].as<EntityID>();
|
||||
std::string name = "Default";
|
||||
if (node[EntityNameNode])
|
||||
name = node[EntityNameNode].as<std::string>();
|
||||
|
@ -117,7 +119,11 @@ namespace SHADE
|
|||
{
|
||||
DeserializeEntity(it, (*it), createdEntities);
|
||||
}
|
||||
|
||||
if(createdEntities.empty())
|
||||
{
|
||||
SHLOG_ERROR("Failed to create entities from deserializaiton")
|
||||
return;
|
||||
}
|
||||
//Initialize Entity
|
||||
auto entityVecIt = createdEntities.begin();
|
||||
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::Node node;
|
||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||
out << YAML::BeginSeq;
|
||||
for (auto const& eid : entities)
|
||||
{
|
||||
auto entityNode = sceneGraph.GetNode(eid);
|
||||
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)
|
||||
|
@ -193,6 +201,30 @@ namespace SHADE
|
|||
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>
|
||||
std::optional<ComponentTypeID> GetComponentID(YAML::Node const& componentNode)
|
||||
{
|
||||
|
|
|
@ -29,14 +29,18 @@ namespace SHADE
|
|||
static void SerializeSceneToFile(std::filesystem::path const& path);
|
||||
static std::string SerializeSceneToString();
|
||||
static void SerializeSceneToEmitter(YAML::Emitter& out);
|
||||
|
||||
static void DeserializeSceneFromFile(std::filesystem::path const& path);
|
||||
|
||||
|
||||
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 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);
|
||||
private:
|
||||
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