Implemented a custom physics engine #316
|
@ -364,3 +364,7 @@ MigrationBackup/
|
||||||
*.filters
|
*.filters
|
||||||
|
|
||||||
Assets/Editor/Layouts/UserLayout.ini
|
Assets/Editor/Layouts/UserLayout.ini
|
||||||
|
|
||||||
|
JSON/Schemas/Catalog/
|
||||||
|
|
||||||
|
Assets/Editor/Editor.SHConfig
|
||||||
|
|
|
@ -67,6 +67,9 @@ namespace Sandbox
|
||||||
SHFileUtilities::SetWorkDirToExecDir();
|
SHFileUtilities::SetWorkDirToExecDir();
|
||||||
WindowData wndData{};
|
WindowData wndData{};
|
||||||
auto& appConfig = SHConfigurationManager::LoadApplicationConfig(&wndData);
|
auto& appConfig = SHConfigurationManager::LoadApplicationConfig(&wndData);
|
||||||
|
#if SHEDITOR
|
||||||
|
auto& editorConfig = SHConfigurationManager::LoadEditorConfig(&wndData);
|
||||||
|
#endif
|
||||||
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow, wndData);
|
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow, wndData);
|
||||||
|
|
||||||
// Create Systems
|
// Create Systems
|
||||||
|
@ -156,8 +159,11 @@ namespace Sandbox
|
||||||
|
|
||||||
SHSystemManager::Init();
|
SHSystemManager::Init();
|
||||||
|
|
||||||
|
#if SHEDITOR
|
||||||
|
SHSceneManager::InitSceneManager<SBMainScene>(editorConfig.workingSceneID);
|
||||||
|
#else
|
||||||
SHSceneManager::InitSceneManager<SBMainScene>(appConfig.startingSceneID);
|
SHSceneManager::InitSceneManager<SBMainScene>(appConfig.startingSceneID);
|
||||||
|
#endif
|
||||||
SHFrameRateController::UpdateFRC();
|
SHFrameRateController::UpdateFRC();
|
||||||
|
|
||||||
// Link up SHDebugDraw
|
// Link up SHDebugDraw
|
||||||
|
|
|
@ -18,11 +18,17 @@ namespace SHADE
|
||||||
|
|
||||||
SHCommandManager::CommandStackPtr SHCommandManager::pCurrUndoStack(&undoStack);
|
SHCommandManager::CommandStackPtr SHCommandManager::pCurrUndoStack(&undoStack);
|
||||||
SHCommandManager::CommandStackPtr SHCommandManager::pCurrRedoStack(&redoStack);
|
SHCommandManager::CommandStackPtr SHCommandManager::pCurrRedoStack(&redoStack);
|
||||||
|
bool SHCommandManager::failedExecution(false);
|
||||||
|
|
||||||
void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
|
void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
|
||||||
{
|
{
|
||||||
*pCurrRedoStack = CommandStack(defaultStackSize);
|
|
||||||
commandPtr->Execute();
|
commandPtr->Execute();
|
||||||
|
if(failedExecution)
|
||||||
|
{
|
||||||
|
failedExecution = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*pCurrRedoStack = CommandStack(defaultStackSize);
|
||||||
if (overrideValue && !pCurrUndoStack->Empty())
|
if (overrideValue && !pCurrUndoStack->Empty())
|
||||||
{
|
{
|
||||||
pCurrUndoStack->Top()->Merge(commandPtr);
|
pCurrUndoStack->Top()->Merge(commandPtr);
|
||||||
|
@ -68,11 +74,13 @@ namespace SHADE
|
||||||
|
|
||||||
void SHCommandManager::PopLatestCommandFromRedoStack()
|
void SHCommandManager::PopLatestCommandFromRedoStack()
|
||||||
{
|
{
|
||||||
|
if(!pCurrRedoStack->Empty())
|
||||||
pCurrRedoStack->Pop();
|
pCurrRedoStack->Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCommandManager::PopLatestCommandFromUndoStack()
|
void SHCommandManager::PopLatestCommandFromUndoStack()
|
||||||
{
|
{
|
||||||
|
if(!pCurrUndoStack->Empty())
|
||||||
pCurrUndoStack->Pop();
|
pCurrUndoStack->Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace SHADE
|
||||||
static void SwapStacks();
|
static void SwapStacks();
|
||||||
static void ClearAll();
|
static void ClearAll();
|
||||||
|
|
||||||
|
static bool failedExecution;
|
||||||
static constexpr CommandStack::SizeType defaultStackSize = 100;
|
static constexpr CommandStack::SizeType defaultStackSize = 100;
|
||||||
private:
|
private:
|
||||||
static CommandStackPtr pCurrUndoStack;
|
static CommandStackPtr pCurrUndoStack;
|
||||||
|
|
|
@ -84,8 +84,7 @@ namespace SHADE
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
}
|
}
|
||||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
||||||
if (ImGui::IsWindowFocused())
|
|
||||||
{
|
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_A))
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_A))
|
||||||
{
|
{
|
||||||
SelectAllEntities();
|
SelectAllEntities();
|
||||||
|
@ -106,11 +105,10 @@ namespace SHADE
|
||||||
PasteEntities(editor->selectedEntities.back());
|
PasteEntities(editor->selectedEntities.back());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ImGui::IsKeyReleased(ImGuiKey_Delete))
|
if (ImGui::IsKeyReleased(ImGuiKey_Delete))
|
||||||
{
|
{
|
||||||
DeleteSelectedEntities();
|
DeleteSelectedEntities();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
#include "Physics/Interface/SHColliderComponent.h"
|
#include "Physics/Interface/SHColliderComponent.h"
|
||||||
#include "Reflection/SHReflectionMetadata.h"
|
#include "Reflection/SHReflectionMetadata.h"
|
||||||
#include "Resource/SHResourceManager.h"
|
#include "Resource/SHResourceManager.h"
|
||||||
|
#include "Serialization/SHSerializationHelper.hpp"
|
||||||
|
#include "Tools/Utilities/SHClipboardUtilities.h"
|
||||||
|
#include "SHInspectorCommands.h"
|
||||||
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -46,11 +49,12 @@ namespace SHADE
|
||||||
|
|
||||||
if (ImGui::Selectable(std::format("{} Copy {}", ICON_MD_CONTENT_COPY, componentName.data()).data()))
|
if (ImGui::Selectable(std::format("{} Copy {}", ICON_MD_CONTENT_COPY, componentName.data()).data()))
|
||||||
{
|
{
|
||||||
//SHClipboardUtil::WriteStringToClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT, SHComponentToString(component));
|
SHClipboardUtilities::WriteToClipboard(SHSerializationHelper::SerializeComponentToString<T>(component->GetEID()));
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable(std::format("{} Paste {}", ICON_MD_CONTENT_PASTE, componentName.data()).data()))
|
if (ImGui::Selectable(std::format("{} Paste {}", ICON_MD_CONTENT_PASTE, componentName.data()).data()))
|
||||||
{
|
{
|
||||||
//SHStringToComponent(component, SHClipboardUtil::ReadStringFromClipboard(SHClipboardUtil::CFNAME::CFCOMPONENT));
|
//SHSerializationHelper::DeserializeComponentFromString<T>(SHClipboardUtilities::GetDataFromClipboard(), component->GetEID());
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>( std::make_shared<SHPasteComponentCommand<T>>(component->GetEID(), SHClipboardUtilities::GetDataFromClipboard())));
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable(std::format("{} Delete {}", ICON_MD_DELETE, componentName.data()).data()))
|
if (ImGui::Selectable(std::format("{} Delete {}", ICON_MD_DELETE, componentName.data()).data()))
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Editor/Command/SHCommand.hpp"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
class SHPasteComponentCommand final : SHBaseCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
EntityID eid;
|
||||||
|
std::string oldComponentData;
|
||||||
|
std::string newComponentData;
|
||||||
|
};
|
||||||
|
|
||||||
|
SHPasteComponentCommand(EntityID eid, std::string const& newComponentData);
|
||||||
|
|
||||||
|
void Execute() override;
|
||||||
|
void Undo() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Data data;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "SHInspectorCommands.hpp"
|
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
#include "SHInspectorCommands.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
SHPasteComponentCommand<T>::SHPasteComponentCommand(EntityID eid, std::string const& newComponentData)
|
||||||
|
:data(eid, {}, newComponentData)
|
||||||
|
{
|
||||||
|
data.oldComponentData = SHSerializationHelper::SerializeComponentToString<T>(eid);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SHPasteComponentCommand<T>::Execute()
|
||||||
|
{
|
||||||
|
bool result = SHSerializationHelper::DeserializeComponentFromString<T>(data.newComponentData, data.eid);
|
||||||
|
if(!result)
|
||||||
|
SHCommandManager::failedExecution = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SHPasteComponentCommand<T>::Undo()
|
||||||
|
{
|
||||||
|
SHSerializationHelper::DeserializeComponentFromString<T>(data.oldComponentData, data.eid);
|
||||||
|
}
|
||||||
|
}
|
|
@ -82,155 +82,19 @@ namespace SHADE
|
||||||
|
|
||||||
if (ImGui::BeginMainMenuBar())
|
if (ImGui::BeginMainMenuBar())
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenu("File"))
|
DrawFileMenu();
|
||||||
{
|
DrawEditMenu();
|
||||||
if(ImGui::Selectable("New Scene"))
|
DrawScriptsMenu();
|
||||||
{
|
DrawWindowMenu();
|
||||||
SHSystemManager::GetSystem<SHEditor>()->NewScene();
|
DrawThemeMenu();
|
||||||
}
|
DrawLayoutMenu();
|
||||||
if(ImGui::Selectable("Save"))
|
DrawApplicationConfig();
|
||||||
{
|
DrawPhysicsSettings();
|
||||||
SHSystemManager::GetSystem<SHEditor>()->SaveScene();
|
|
||||||
}
|
|
||||||
if(ImGui::Selectable("Load"))
|
|
||||||
{
|
|
||||||
//SHSystemManager::GetSystem<SHEditor>()->LoadScene()
|
|
||||||
}
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
if(ImGui::BeginMenu("Edit"))
|
|
||||||
{
|
|
||||||
ImGui::BeginDisabled(!SHCommandManager::GetUndoStackSize());
|
|
||||||
if(ImGui::Button(std::format("{} Undo", ICON_MD_UNDO).data()))
|
|
||||||
{
|
|
||||||
SHCommandManager::UndoCommand();
|
|
||||||
}
|
|
||||||
ImGui::EndDisabled();
|
|
||||||
ImGui::BeginDisabled(!SHCommandManager::GetRedoStackSize());
|
|
||||||
if(ImGui::Button(std::format("{} Redo", ICON_MD_REDO).data()))
|
|
||||||
{
|
|
||||||
SHCommandManager::RedoCommand();
|
|
||||||
}
|
|
||||||
ImGui::EndDisabled();
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
if (ImGui::BeginMenu("Scripts"))
|
|
||||||
{
|
|
||||||
if (ImGui::Selectable("Generate Visual Studio Project"))
|
|
||||||
{
|
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
|
||||||
scriptEngine->GenerateScriptsCsProjFile();
|
|
||||||
}
|
|
||||||
if (ImGui::Selectable("Open Visual Studio Project"))
|
|
||||||
{
|
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
|
||||||
scriptEngine->OpenSolution();
|
|
||||||
}
|
|
||||||
ImGui::BeginDisabled(SHSystemManager::GetSystem<SHEditor>()->editorState != SHEditor::State::STOP);
|
|
||||||
if (ImGui::Selectable("Build Scripts - Debug"))
|
|
||||||
{
|
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
|
||||||
SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID());
|
|
||||||
scriptEngine->BuildScriptAssembly(true, true);
|
|
||||||
SHSceneManager::RestartScene(SHSceneManager::GetCurrentSceneAssetID());
|
|
||||||
}
|
|
||||||
if (ImGui::Selectable("Build Scripts - Release"))
|
|
||||||
{
|
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
|
||||||
SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID());
|
|
||||||
scriptEngine->BuildScriptAssembly(false, true);
|
|
||||||
SHSceneManager::RestartScene(SHSceneManager::GetCurrentSceneAssetID());
|
|
||||||
}
|
|
||||||
ImGui::EndDisabled();
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Window"))
|
std::string const sceneName{std::format("Current Scene: {}",SHSceneManager::GetSceneName().data())};
|
||||||
{
|
auto const size = ImGui::CalcTextSize(sceneName.data());
|
||||||
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - size.x - ImGui::GetStyle().FramePadding.x);
|
||||||
{
|
ImGui::Text("%s", sceneName.data());
|
||||||
if (window.get() != this)
|
|
||||||
ImGui::Checkbox(window->windowName.data(), &window->isOpen);
|
|
||||||
}
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
if (ImGui::BeginMenu("Theme"))
|
|
||||||
{
|
|
||||||
const auto styles = rttr::type::get<SHEditor::Style>().get_enumeration();
|
|
||||||
auto values = styles.get_values();
|
|
||||||
for (auto style : values)
|
|
||||||
{
|
|
||||||
if (ImGui::Selectable(style.to_string().c_str()))
|
|
||||||
{
|
|
||||||
if (auto editor = SHSystemManager::GetSystem<SHEditor>())
|
|
||||||
editor->SetStyle(style.convert<SHEditor::Style>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
if(ImGui::BeginMenu("Layout"))
|
|
||||||
{
|
|
||||||
for(auto const& entry : layoutPaths)
|
|
||||||
{
|
|
||||||
if(ImGui::Selectable(entry.stem().string().c_str()))
|
|
||||||
{
|
|
||||||
ImGui::LoadIniSettingsFromDisk(entry.string().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Application Config"))
|
|
||||||
{
|
|
||||||
auto& appConfig = SHConfigurationManager::applicationConfig;
|
|
||||||
ImGui::InputText("Window Title", &appConfig.windowTitle);
|
|
||||||
ImGui::Checkbox("Start in Fullscreen", &appConfig.startInFullScreen);
|
|
||||||
SHEditorWidgets::DragN<float, 2>("Window Size", { "Width", "Height" }, { &appConfig.windowSize.x, &appConfig.windowSize.y });
|
|
||||||
//ImGui::InputScalar("Starting Scene", ImGuiDataType_U32, &appConfig.startingSceneID);
|
|
||||||
auto sceneAsset = SHAssetManager::GetData<SHSceneAsset>(appConfig.startingSceneID);
|
|
||||||
|
|
||||||
if(ImGui::BeginCombo("Starting Scne", sceneAsset ? sceneAsset->name.data() : ""))
|
|
||||||
{
|
|
||||||
auto scenes = SHAssetManager::GetAllRecordOfType(AssetType::SCENE);
|
|
||||||
for(auto const& scene : scenes)
|
|
||||||
{
|
|
||||||
if(ImGui::Selectable(scene.name.data()))
|
|
||||||
{
|
|
||||||
appConfig.startingSceneID = scene.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndCombo();
|
|
||||||
}
|
|
||||||
if (ImGui::Button("Save"))
|
|
||||||
{
|
|
||||||
SHConfigurationManager::SaveApplicationConfig();
|
|
||||||
}
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Physics Settings"))
|
|
||||||
{
|
|
||||||
if (auto* physicsDebugDraw = SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>())
|
|
||||||
{
|
|
||||||
bool drawColliders = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDERS);
|
|
||||||
if (ImGui::Checkbox("Draw Colliders", &drawColliders))
|
|
||||||
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDERS, drawColliders);
|
|
||||||
|
|
||||||
bool drawContactPoints = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACTS);
|
|
||||||
if (ImGui::Checkbox("Draw Contact Points", &drawContactPoints))
|
|
||||||
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACTS, drawContactPoints);
|
|
||||||
|
|
||||||
bool drawRays = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS);
|
|
||||||
if (ImGui::Checkbox("Draw Rays", &drawRays))
|
|
||||||
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays);
|
|
||||||
|
|
||||||
bool drawBroadphase = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::BROADPHASE);
|
|
||||||
if (ImGui::Checkbox("Draw Broadphase", &drawBroadphase))
|
|
||||||
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::BROADPHASE, drawBroadphase);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndMainMenuBar();
|
ImGui::EndMainMenuBar();
|
||||||
}
|
}
|
||||||
|
@ -297,4 +161,176 @@ namespace SHADE
|
||||||
ImGui::PopStyleVar(3);
|
ImGui::PopStyleVar(3);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
void SHEditorMenuBar::DrawFileMenu() noexcept
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("File"))
|
||||||
|
{
|
||||||
|
if (ImGui::Selectable("New Scene"))
|
||||||
|
{
|
||||||
|
SHSystemManager::GetSystem<SHEditor>()->NewScene();
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable("Save"))
|
||||||
|
{
|
||||||
|
SHSystemManager::GetSystem<SHEditor>()->SaveScene();
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable("Load"))
|
||||||
|
{
|
||||||
|
//SHSystemManager::GetSystem<SHEditor>()->LoadScene()
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SHEditorMenuBar::DrawEditMenu() noexcept
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Edit"))
|
||||||
|
{
|
||||||
|
ImGui::BeginDisabled(!SHCommandManager::GetUndoStackSize());
|
||||||
|
if (ImGui::Button(std::format("{} Undo", ICON_MD_UNDO).data()))
|
||||||
|
{
|
||||||
|
SHCommandManager::UndoCommand();
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::BeginDisabled(!SHCommandManager::GetRedoStackSize());
|
||||||
|
if (ImGui::Button(std::format("{} Redo", ICON_MD_REDO).data()))
|
||||||
|
{
|
||||||
|
SHCommandManager::RedoCommand();
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SHEditorMenuBar::DrawScriptsMenu() noexcept
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Scripts"))
|
||||||
|
{
|
||||||
|
if (ImGui::Selectable("Generate Visual Studio Project"))
|
||||||
|
{
|
||||||
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->GenerateScriptsCsProjFile();
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable("Open Visual Studio Project"))
|
||||||
|
{
|
||||||
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->OpenSolution();
|
||||||
|
}
|
||||||
|
ImGui::BeginDisabled(SHSystemManager::GetSystem<SHEditor>()->editorState != SHEditor::State::STOP);
|
||||||
|
if (ImGui::Selectable("Build Scripts - Debug"))
|
||||||
|
{
|
||||||
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
|
scriptEngine->BuildScriptAssembly(true, true);
|
||||||
|
SHSceneManager::RestartScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
|
}
|
||||||
|
if (ImGui::Selectable("Build Scripts - Release"))
|
||||||
|
{
|
||||||
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
SHSerialization::SerializeSceneToFile(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
|
scriptEngine->BuildScriptAssembly(false, true);
|
||||||
|
SHSceneManager::RestartScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SHEditorMenuBar::DrawWindowMenu() noexcept
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Window"))
|
||||||
|
{
|
||||||
|
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
||||||
|
{
|
||||||
|
if (window.get() != this)
|
||||||
|
ImGui::Checkbox(window->windowName.data(), &window->isOpen);
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SHEditorMenuBar::DrawThemeMenu() noexcept
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Theme"))
|
||||||
|
{
|
||||||
|
const auto styles = rttr::type::get<SHEditor::Style>().get_enumeration();
|
||||||
|
auto values = styles.get_values();
|
||||||
|
for (auto style : values)
|
||||||
|
{
|
||||||
|
if (ImGui::Selectable(style.to_string().c_str()))
|
||||||
|
{
|
||||||
|
if (auto editor = SHSystemManager::GetSystem<SHEditor>())
|
||||||
|
editor->SetStyle(style.convert<SHEditor::Style>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SHEditorMenuBar::DrawLayoutMenu() noexcept
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Layout"))
|
||||||
|
{
|
||||||
|
for (auto const& entry : layoutPaths)
|
||||||
|
{
|
||||||
|
if (ImGui::Selectable(entry.stem().string().c_str()))
|
||||||
|
{
|
||||||
|
ImGui::LoadIniSettingsFromDisk(entry.string().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SHEditorMenuBar::DrawApplicationConfig() noexcept
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Application Config"))
|
||||||
|
{
|
||||||
|
auto& appConfig = SHConfigurationManager::applicationConfig;
|
||||||
|
ImGui::InputText("Window Title", &appConfig.windowTitle);
|
||||||
|
ImGui::Checkbox("Start in Fullscreen", &appConfig.startInFullScreen);
|
||||||
|
SHEditorWidgets::DragN<float, 2>("Window Size", { "Width", "Height" }, { &appConfig.windowSize.x, &appConfig.windowSize.y });
|
||||||
|
//ImGui::InputScalar("Starting Scene", ImGuiDataType_U32, &appConfig.startingSceneID);
|
||||||
|
auto sceneAsset = SHAssetManager::GetData<SHSceneAsset>(appConfig.startingSceneID);
|
||||||
|
|
||||||
|
if (ImGui::BeginCombo("Starting Scene", sceneAsset ? sceneAsset->name.data() : ""))
|
||||||
|
{
|
||||||
|
auto scenes = SHAssetManager::GetAllRecordOfType(AssetType::SCENE);
|
||||||
|
for (auto const& scene : scenes)
|
||||||
|
{
|
||||||
|
if (ImGui::Selectable(scene.name.data()))
|
||||||
|
{
|
||||||
|
appConfig.startingSceneID = scene.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Save"))
|
||||||
|
{
|
||||||
|
SHConfigurationManager::SaveApplicationConfig();
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHEditorMenuBar::DrawPhysicsSettings() noexcept
|
||||||
|
{
|
||||||
|
if (ImGui::BeginMenu("Physics Settings"))
|
||||||
|
{
|
||||||
|
if (auto* physicsDebugDraw = SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>())
|
||||||
|
{
|
||||||
|
bool drawColliders = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDERS);
|
||||||
|
if (ImGui::Checkbox("Draw Colliders", &drawColliders))
|
||||||
|
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDERS, drawColliders);
|
||||||
|
|
||||||
|
bool drawContactPoints = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACTS);
|
||||||
|
if (ImGui::Checkbox("Draw Contact Points", &drawContactPoints))
|
||||||
|
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::CONTACTS, drawContactPoints);
|
||||||
|
|
||||||
|
bool drawRays = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS);
|
||||||
|
if (ImGui::Checkbox("Draw Rays", &drawRays))
|
||||||
|
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::RAYCASTS, drawRays);
|
||||||
|
|
||||||
|
bool drawBroadphase = physicsDebugDraw->GetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::BROADPHASE);
|
||||||
|
if (ImGui::Checkbox("Draw Broadphase", &drawBroadphase))
|
||||||
|
physicsDebugDraw->SetFlagState(SHPhysicsDebugDrawSystem::DebugDrawFlags::BROADPHASE, drawBroadphase);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -17,6 +17,16 @@ namespace SHADE
|
||||||
void DrawMainMenuBar() noexcept;
|
void DrawMainMenuBar() noexcept;
|
||||||
void DrawSecondaryBar() const noexcept;
|
void DrawSecondaryBar() const noexcept;
|
||||||
void DrawStatusBar() const noexcept;
|
void DrawStatusBar() const noexcept;
|
||||||
|
|
||||||
|
void DrawFileMenu() noexcept;
|
||||||
|
void DrawEditMenu() noexcept;
|
||||||
|
void DrawScriptsMenu() noexcept;
|
||||||
|
void DrawWindowMenu() noexcept;
|
||||||
|
void DrawThemeMenu() noexcept;
|
||||||
|
void DrawLayoutMenu() noexcept;
|
||||||
|
void DrawApplicationConfig() noexcept;
|
||||||
|
void DrawPhysicsSettings() noexcept;
|
||||||
|
|
||||||
float menuBarHeight = 20.0f;
|
float menuBarHeight = 20.0f;
|
||||||
std::vector<std::filesystem::path> layoutPaths;
|
std::vector<std::filesystem::path> layoutPaths;
|
||||||
};//class SHEditorMenuBar
|
};//class SHEditorMenuBar
|
||||||
|
|
|
@ -94,6 +94,8 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
editorConfig = &SHConfigurationManager::LoadEditorConfig();
|
||||||
|
|
||||||
//Add editor windows
|
//Add editor windows
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
|
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
|
||||||
|
@ -122,7 +124,7 @@ namespace SHADE
|
||||||
|
|
||||||
InitBackend();
|
InitBackend();
|
||||||
|
|
||||||
SetStyle(Style::SHADE);
|
SetStyle(static_cast<Style>(editorConfig->style));
|
||||||
|
|
||||||
|
|
||||||
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
||||||
|
@ -160,26 +162,7 @@ namespace SHADE
|
||||||
RenderUnsavedChangesPrompt();
|
RenderUnsavedChangesPrompt();
|
||||||
//PollPicking();
|
//PollPicking();
|
||||||
|
|
||||||
if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
ProcessShortcuts();
|
||||||
{
|
|
||||||
SHCommandManager::RedoCommand();
|
|
||||||
}
|
|
||||||
else if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
|
||||||
{
|
|
||||||
SHCommandManager::UndoCommand();
|
|
||||||
}
|
|
||||||
if(ImGui::IsKeyReleased(ImGuiKey_F5))
|
|
||||||
{
|
|
||||||
Play();
|
|
||||||
}
|
|
||||||
else if (ImGui::IsKeyReleased(ImGuiKey_F6))
|
|
||||||
{
|
|
||||||
Pause();
|
|
||||||
}
|
|
||||||
else if (ImGui::IsKeyReleased(ImGuiKey_F7))
|
|
||||||
{
|
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
Render();
|
Render();
|
||||||
}
|
}
|
||||||
|
@ -376,10 +359,14 @@ namespace SHADE
|
||||||
ImGui_ImplVulkan_Shutdown();
|
ImGui_ImplVulkan_Shutdown();
|
||||||
ImGui_ImplSDL2_Shutdown();
|
ImGui_ImplSDL2_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
|
editorConfig->startMaximized = shWindow->GetWindowData().isMaximised;
|
||||||
|
SHConfigurationManager::SaveEditorConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::SetStyle(Style style)
|
void SHEditor::SetStyle(Style style)
|
||||||
{
|
{
|
||||||
|
editorConfig->style = static_cast<uint32_t>(style);
|
||||||
switch (style)
|
switch (style)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
@ -583,6 +570,7 @@ namespace SHADE
|
||||||
|
|
||||||
SHSceneManager::SetCurrentSceneName(newSceneName);
|
SHSceneManager::SetCurrentSceneName(newSceneName);
|
||||||
SHSceneManager::SetCurrentSceneAssetID(SHAssetManager::CreateNewAsset(AssetType::SCENE, newSceneName));
|
SHSceneManager::SetCurrentSceneAssetID(SHAssetManager::CreateNewAsset(AssetType::SCENE, newSceneName));
|
||||||
|
editorConfig->workingSceneID = SHSceneManager::GetCurrentSceneAssetID();
|
||||||
}
|
}
|
||||||
//Get data, if data is null, asset doesn't exist, prompt for a name and create a new asset with the name
|
//Get data, if data is null, asset doesn't exist, prompt for a name and create a new asset with the name
|
||||||
|
|
||||||
|
@ -591,7 +579,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if(shWindow->IsUnsavedChanges())
|
if(shWindow->IsUnsavedChanges())
|
||||||
shWindow->ToggleUnsavedChanges();
|
shWindow->ToggleUnsavedChanges();
|
||||||
|
editorConfig->workingSceneID = SHSceneManager::GetCurrentSceneAssetID();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -659,6 +647,37 @@ namespace SHADE
|
||||||
LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditor::ProcessShortcuts()
|
||||||
|
{
|
||||||
|
if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
|
||||||
|
{
|
||||||
|
if(ImGui::IsKeyReleased(ImGuiKey_S))
|
||||||
|
{
|
||||||
|
SaveScene();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||||
|
{
|
||||||
|
SHCommandManager::RedoCommand();
|
||||||
|
}
|
||||||
|
else if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
|
||||||
|
{
|
||||||
|
SHCommandManager::UndoCommand();
|
||||||
|
}
|
||||||
|
if (ImGui::IsKeyReleased(ImGuiKey_F5))
|
||||||
|
{
|
||||||
|
Play();
|
||||||
|
}
|
||||||
|
else if (ImGui::IsKeyReleased(ImGuiKey_F6))
|
||||||
|
{
|
||||||
|
Pause();
|
||||||
|
}
|
||||||
|
else if (ImGui::IsKeyReleased(ImGuiKey_F7))
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHEditor::NewFrame()
|
void SHEditor::NewFrame()
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
@ -672,6 +691,18 @@ namespace SHADE
|
||||||
ImGuizmo::BeginFrame();
|
ImGuizmo::BeginFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditor::SetSHWindow(SHWindow* inWindow)
|
||||||
|
{
|
||||||
|
shWindow = inWindow;
|
||||||
|
shWindow->RegisterWindowSizeCallback([&](uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
if(width > 0 && height > 0)
|
||||||
|
{
|
||||||
|
auto [width, height] = shWindow->GetWindowSize();
|
||||||
|
editorConfig->windowSize = { static_cast<float>(width), static_cast<float>(height) };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void SHEditor::EditorRoutine::Execute(double dt) noexcept
|
void SHEditor::EditorRoutine::Execute(double dt) noexcept
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "Events/SHEventDefines.h"
|
#include "Events/SHEventDefines.h"
|
||||||
#include "Events/SHEvent.h"
|
#include "Events/SHEvent.h"
|
||||||
#include "Graphics/Windowing/SHWindow.h"
|
#include "Graphics/Windowing/SHWindow.h"
|
||||||
|
#include "Serialization/Configurations/SHConfigurationManager.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
|
@ -108,7 +109,7 @@ namespace SHADE
|
||||||
void InitBackend();
|
void InitBackend();
|
||||||
|
|
||||||
void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;};
|
void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;};
|
||||||
void SetSHWindow(SHWindow* inWindow){shWindow = inWindow;}
|
void SetSHWindow(SHWindow* inWindow);
|
||||||
|
|
||||||
void PollPicking();
|
void PollPicking();
|
||||||
|
|
||||||
|
@ -122,11 +123,15 @@ namespace SHADE
|
||||||
void Pause();
|
void Pause();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
|
void ProcessShortcuts();
|
||||||
|
|
||||||
// List of selected entities
|
// List of selected entities
|
||||||
std::vector<EntityID> selectedEntities;
|
std::vector<EntityID> selectedEntities;
|
||||||
|
|
||||||
State editorState = State::STOP;
|
State editorState = State::STOP;
|
||||||
|
|
||||||
|
SHEditorConfig* editorConfig;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Start new frame for editor
|
* @brief Start new frame for editor
|
||||||
|
|
|
@ -160,7 +160,7 @@ namespace SHADE
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
template <typename T, std::size_t N>
|
||||||
static bool DragN(const std::string& label, std::vector<std::string>const& componentLabels,
|
static bool DragN(const std::string& label, std::vector<std::string>const& componentLabels,
|
||||||
std::vector<T*> values, float speed = 0.1f, const char* displayFormat = "", T valueMin = T(), T valueMax = T(),
|
std::vector<T*> values, float speed = 0.1f, const char* displayFormat = "%.3f", T valueMin = T(), T valueMax = T(),
|
||||||
ImGuiSliderFlags flags = 0, bool* isHovered = nullptr)
|
ImGuiSliderFlags flags = 0, bool* isHovered = nullptr)
|
||||||
{
|
{
|
||||||
const ImGuiWindow* const window = ImGui::GetCurrentWindow();
|
const ImGuiWindow* const window = ImGui::GetCurrentWindow();
|
||||||
|
|
|
@ -115,6 +115,11 @@ namespace SHADE
|
||||||
SetFocus(wndHWND);
|
SetFocus(wndHWND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!wndData.isFullscreen && wndData.isMaximised)
|
||||||
|
{
|
||||||
|
Maximize();
|
||||||
|
}
|
||||||
|
|
||||||
if (!wndData.icoPath.empty())
|
if (!wndData.icoPath.empty())
|
||||||
{
|
{
|
||||||
//HICON hIcon = ::LoadIcon(nullptr, MAKEINTRESOURCE(wndData.icoPath.c_str()));
|
//HICON hIcon = ::LoadIcon(nullptr, MAKEINTRESOURCE(wndData.icoPath.c_str()));
|
||||||
|
@ -208,10 +213,12 @@ namespace SHADE
|
||||||
if (!IsZoomed(wndHWND))
|
if (!IsZoomed(wndHWND))
|
||||||
{
|
{
|
||||||
ShowWindow(wndHWND, SW_MAXIMIZE);
|
ShowWindow(wndHWND, SW_MAXIMIZE);
|
||||||
|
wndData.isMaximised = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShowWindow(wndHWND, SW_RESTORE);
|
ShowWindow(wndHWND, SW_RESTORE);
|
||||||
|
wndData.isMaximised = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,7 +435,9 @@ namespace SHADE
|
||||||
wndData.isMinimised = true;
|
wndData.isMinimised = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
wndData.isMinimised = false;
|
wndData.isMinimised = false;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto const& entry : windowResizeCallbacks)
|
for (auto const& entry : windowResizeCallbacks)
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,6 +64,8 @@ namespace SHADE
|
||||||
|
|
||||||
bool isMinimised = false;
|
bool isMinimised = false;
|
||||||
|
|
||||||
|
bool isMaximised = true;
|
||||||
|
|
||||||
std::wstring title = L"SHADE ENGINE";
|
std::wstring title = L"SHADE ENGINE";
|
||||||
|
|
||||||
std::wstring name = L"SHADEEngineApp";
|
std::wstring name = L"SHADEEngineApp";
|
||||||
|
|
|
@ -52,15 +52,27 @@ namespace SHADE
|
||||||
SHFileIO::WriteStringToFile(editorConfigPath, out.c_str());
|
SHFileIO::WriteStringToFile(editorConfigPath, out.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
SHEditorConfig& SHConfigurationManager::LoadEditorConfig()
|
SHEditorConfig& SHConfigurationManager::LoadEditorConfig(WindowData* windowData)
|
||||||
{
|
{
|
||||||
|
if (!std::filesystem::exists(editorConfigPath))
|
||||||
|
{
|
||||||
|
SaveApplicationConfig();
|
||||||
|
return editorConfig;
|
||||||
|
}
|
||||||
|
|
||||||
auto const node = YAML::Load(SHFileIO::GetStringFromFile(editorConfigPath));
|
auto const node = YAML::Load(SHFileIO::GetStringFromFile(editorConfigPath));
|
||||||
auto properties = rttr::type::get<SHApplicationConfig>().get_properties();
|
auto properties = rttr::type::get<SHEditorConfig>().get_properties();
|
||||||
for(auto const& property : properties)
|
for(auto const& property : properties)
|
||||||
{
|
{
|
||||||
if(node[property.get_name().data()].IsDefined())
|
if(node[property.get_name().data()].IsDefined())
|
||||||
SHSerializationHelper::InitializeProperty(&editorConfig, property, node[property.get_name().data()]);
|
SHSerializationHelper::InitializeProperty(&editorConfig, property, node[property.get_name().data()]);
|
||||||
}
|
}
|
||||||
|
if(windowData)
|
||||||
|
{
|
||||||
|
windowData->isMaximised = editorConfig.startMaximized;
|
||||||
|
windowData->width = static_cast<uint32_t>(editorConfig.windowSize.x);
|
||||||
|
windowData->height = static_cast<uint32_t>(editorConfig.windowSize.y);
|
||||||
|
}
|
||||||
return editorConfig;
|
return editorConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,4 +98,10 @@ RTTR_REGISTRATION
|
||||||
.property("Starting Scene ID", &SHApplicationConfig::startingSceneID)
|
.property("Starting Scene ID", &SHApplicationConfig::startingSceneID)
|
||||||
.property("Window Size", &SHApplicationConfig::windowSize)
|
.property("Window Size", &SHApplicationConfig::windowSize)
|
||||||
.property("Window Title", &SHApplicationConfig::windowTitle);
|
.property("Window Title", &SHApplicationConfig::windowTitle);
|
||||||
|
|
||||||
|
registration::class_<SHEditorConfig>("Editor Config")
|
||||||
|
.property("Start Maximized", &SHEditorConfig::startMaximized)
|
||||||
|
.property("Working Scene ID", &SHEditorConfig::workingSceneID)
|
||||||
|
.property("Window Size", &SHEditorConfig::windowSize)
|
||||||
|
.property("Style", &SHEditorConfig::style);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
struct SHApplicationConfig
|
struct SHApplicationConfig
|
||||||
{
|
{
|
||||||
bool startInFullScreen{ false };
|
bool startInFullScreen{ false };
|
||||||
|
@ -19,7 +18,11 @@ namespace SHADE
|
||||||
|
|
||||||
struct SHEditorConfig
|
struct SHEditorConfig
|
||||||
{
|
{
|
||||||
|
bool startMaximized{true};
|
||||||
|
AssetID workingSceneID{};
|
||||||
|
SHVec2 windowSize {1920, 1080};
|
||||||
|
uint32_t style = 0;
|
||||||
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
class SH_API SHConfigurationManager
|
class SH_API SHConfigurationManager
|
||||||
|
@ -33,7 +36,7 @@ namespace SHADE
|
||||||
static SHApplicationConfig applicationConfig;
|
static SHApplicationConfig applicationConfig;
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
static void SaveEditorConfig();
|
static void SaveEditorConfig();
|
||||||
static SHEditorConfig& LoadEditorConfig();
|
static SHEditorConfig& LoadEditorConfig(WindowData* windowData = nullptr);
|
||||||
static SHEditorConfig editorConfig;
|
static SHEditorConfig editorConfig;
|
||||||
private:
|
private:
|
||||||
static void FetchEditorCameraData();
|
static void FetchEditorCameraData();
|
||||||
|
|
|
@ -171,24 +171,14 @@ namespace SHADE
|
||||||
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>
|
||||||
static void AddComponentToComponentNode(YAML::Node& componentsNode, EntityID const& eid)
|
static void AddComponentToComponentNode(YAML::Node& componentsNode, EntityID const& eid)
|
||||||
{
|
{
|
||||||
if (const ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
|
YAML::Node node{};
|
||||||
{
|
|
||||||
componentsNode[rttr::type::get<ComponentType>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(component);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
|
||||||
static void AddConvComponentToComponentNode(YAML::Node& componentsNode, EntityID const& eid)
|
|
||||||
{
|
|
||||||
if (ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
|
if (ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
|
||||||
{
|
{
|
||||||
auto componentNode = YAML::convert<ComponentType>::encode(*component);
|
node = SHSerializationHelper::SerializeComponentToNode(component);
|
||||||
componentNode[IsActive.data()] = component->isActive;
|
componentsNode[rttr::type::get<ComponentType>().get_name().data()] = node;
|
||||||
componentsNode[rttr::type::get<ComponentType>().get_name().data()] = componentNode;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode)
|
YAML::Node SHSerialization::SerializeEntityToNode(SHSceneNode* sceneNode)
|
||||||
{
|
{
|
||||||
YAML::Node node;
|
YAML::Node node;
|
||||||
|
@ -211,15 +201,15 @@ namespace SHADE
|
||||||
AddComponentToComponentNode<SHTransformComponent>(components, eid);
|
AddComponentToComponentNode<SHTransformComponent>(components, eid);
|
||||||
AddComponentToComponentNode<SHCameraComponent>(components, eid);
|
AddComponentToComponentNode<SHCameraComponent>(components, eid);
|
||||||
AddComponentToComponentNode<SHCameraArmComponent>(components, eid);
|
AddComponentToComponentNode<SHCameraArmComponent>(components, eid);
|
||||||
AddConvComponentToComponentNode<SHRenderable>(components, eid);
|
AddComponentToComponentNode<SHRenderable>(components, eid);
|
||||||
AddComponentToComponentNode<SHLightComponent>(components, eid);
|
AddComponentToComponentNode<SHLightComponent>(components, eid);
|
||||||
AddComponentToComponentNode<SHRigidBodyComponent>(components, eid);
|
AddComponentToComponentNode<SHRigidBodyComponent>(components, eid);
|
||||||
AddConvComponentToComponentNode<SHColliderComponent>(components, eid);
|
AddComponentToComponentNode<SHColliderComponent>(components, eid);
|
||||||
|
|
||||||
AddComponentToComponentNode<SHCanvasComponent>(components, eid);
|
AddComponentToComponentNode<SHCanvasComponent>(components, eid);
|
||||||
AddComponentToComponentNode<SHButtonComponent>(components, eid);
|
AddComponentToComponentNode<SHButtonComponent>(components, eid);
|
||||||
|
|
||||||
AddConvComponentToComponentNode<SHTextRenderableComponent>(components, eid);
|
AddComponentToComponentNode<SHTextRenderableComponent>(components, eid);
|
||||||
|
|
||||||
node[ComponentsNode] = components;
|
node[ComponentsNode] = components;
|
||||||
|
|
||||||
|
@ -351,12 +341,12 @@ namespace SHADE
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHCameraComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHCameraComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHCameraArmComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHCameraArmComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHRigidBodyComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHRigidBodyComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::ConvertNodeToComponent<SHRenderable>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHRenderable>(componentsNode, eid);
|
||||||
SHSerializationHelper::ConvertNodeToComponent<SHColliderComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHColliderComponent>(componentsNode, eid);
|
||||||
|
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHCanvasComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHCanvasComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHButtonComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHButtonComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::ConvertNodeToComponent<SHTextRenderableComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHTextRenderableComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,12 +104,6 @@ namespace SHADE
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
|
||||||
static std::string SerializeComponentToString(ComponentType* component)
|
|
||||||
{
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
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>
|
||||||
static void SerializeComponentToFile(ComponentType* component, std::filesystem::path const& path)
|
static void SerializeComponentToFile(ComponentType* component, std::filesystem::path const& path)
|
||||||
{
|
{
|
||||||
|
@ -118,14 +112,29 @@ namespace SHADE
|
||||||
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>
|
||||||
static YAML::Node SerializeComponentToNode(ComponentType* component)
|
static YAML::Node SerializeComponentToNode(ComponentType* component)
|
||||||
{
|
{
|
||||||
YAML::Node node{};
|
if constexpr (YAML::HasYAMLConv<ComponentType>())
|
||||||
|
{
|
||||||
|
if (component)
|
||||||
|
{
|
||||||
|
auto componentNode = YAML::convert<ComponentType>::encode(*component);
|
||||||
|
componentNode[IsActive.data()] = component->isActive;
|
||||||
|
return componentNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (component)
|
||||||
|
{
|
||||||
|
YAML::Node compNode{};
|
||||||
if (!component)
|
if (!component)
|
||||||
return node;
|
return compNode;
|
||||||
auto componentType = rttr::type::get<ComponentType>();
|
auto componentType = rttr::type::get<ComponentType>();
|
||||||
node = RTTRToNode(*component);
|
compNode = RTTRToNode(*component);
|
||||||
node[IsActive.data()] = component->isActive;
|
compNode[IsActive.data()] = component->isActive;
|
||||||
|
return compNode;
|
||||||
|
|
||||||
return node;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
|
@ -192,16 +201,31 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
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>
|
||||||
static void InitializeComponentFromNode(YAML::Node const& componentsNode, EntityID const& eid)
|
static bool InitializeComponentFromNode(YAML::Node const& componentsNode, EntityID const& eid)
|
||||||
|
{
|
||||||
|
if constexpr (YAML::HasYAMLConv<ComponentType>())
|
||||||
|
{
|
||||||
|
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||||
|
if (componentsNode.IsNull() || !component)
|
||||||
|
return false;
|
||||||
|
auto componentNode = GetComponentNode<ComponentType>(componentsNode, eid);
|
||||||
|
if (componentNode.IsNull() || !componentNode.IsDefined())
|
||||||
|
return false;
|
||||||
|
if (componentNode[IsActive.data()].IsDefined())
|
||||||
|
component->isActive = componentNode[IsActive.data()].as<bool>();
|
||||||
|
YAML::convert<ComponentType>::decode(componentNode, *component);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
||||||
if (componentsNode.IsNull() && !component)
|
if (componentsNode.IsNull() && !component)
|
||||||
return;
|
return false;
|
||||||
auto rttrType = rttr::type::get<ComponentType>();
|
auto rttrType = rttr::type::get<ComponentType>();
|
||||||
auto componentNode = componentsNode[rttrType.get_name().data()];
|
auto componentNode = componentsNode[rttrType.get_name().data()];
|
||||||
if (!componentNode.IsDefined())
|
if (!componentNode.IsDefined())
|
||||||
return;
|
return false;
|
||||||
if(componentNode[IsActive.data()].IsDefined())
|
if (componentNode[IsActive.data()].IsDefined())
|
||||||
component->isActive = componentNode[IsActive.data()].as<bool>();
|
component->isActive = componentNode[IsActive.data()].as<bool>();
|
||||||
|
|
||||||
auto properties = rttrType.get_properties();
|
auto properties = rttrType.get_properties();
|
||||||
|
@ -213,6 +237,8 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
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>
|
||||||
static YAML::Node GetComponentNode(YAML::Node const& componentsNode, EntityID const& eid)
|
static YAML::Node GetComponentNode(YAML::Node const& componentsNode, EntityID const& eid)
|
||||||
|
@ -227,16 +253,49 @@ namespace SHADE
|
||||||
return componentNode;
|
return componentNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//template<typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
//static void AddComponentToComponentNode(YAML::Node& componentsNode, EntityID const& eid)
|
||||||
|
//{
|
||||||
|
// if constexpr (YAML::HasYAMLConv<ComponentType>())
|
||||||
|
// {
|
||||||
|
// if (ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
|
||||||
|
// {
|
||||||
|
// auto componentNode = YAML::convert<ComponentType>::encode(*component);
|
||||||
|
// componentNode[IsActive.data()] = component->isActive;
|
||||||
|
// componentsNode[rttr::type::get<ComponentType>().get_name().data()] = componentNode;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// if (const ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
|
||||||
|
// {
|
||||||
|
// componentsNode[rttr::type::get<ComponentType>().get_name().data()] = SHSerializationHelper::SerializeComponentToNode(component);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
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>
|
||||||
static void ConvertNodeToComponent(YAML::Node const& componentsNode, EntityID const& eid)
|
static std::string SerializeComponentToString(EntityID const& eid)
|
||||||
{
|
{
|
||||||
auto component = SHComponentManager::GetComponent_s<ComponentType>(eid);
|
if (ComponentType* component = SHComponentManager::GetComponent_s<ComponentType>(eid))
|
||||||
if (componentsNode.IsNull() && !component)
|
{
|
||||||
return;
|
YAML::Emitter out;
|
||||||
auto componentNode = GetComponentNode<ComponentType>(componentsNode, eid);
|
YAML::Node node{};
|
||||||
if (componentNode[IsActive.data()].IsDefined())
|
|
||||||
component->isActive = componentNode[IsActive.data()].as<bool>();
|
node[rttr::type::get<ComponentType>().get_name().data()] = SerializeComponentToNode(component);
|
||||||
YAML::convert<ComponentType>::decode(componentNode, *component);
|
out << node;
|
||||||
|
|
||||||
|
return out.c_str();
|
||||||
|
}
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ComponentType, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true>
|
||||||
|
static bool DeserializeComponentFromString(std::string data, EntityID const& eid)
|
||||||
|
{
|
||||||
|
YAML::Node node = YAML::Load(data);
|
||||||
|
return InitializeComponentFromNode<ComponentType>(node, 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>
|
||||||
|
|
|
@ -18,6 +18,16 @@ namespace YAML
|
||||||
{
|
{
|
||||||
using namespace SHADE;
|
using namespace SHADE;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct HasYAMLConv : std::false_type{};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct HasYAMLConv<SHColliderComponent> : std::true_type {};
|
||||||
|
template<>
|
||||||
|
struct HasYAMLConv<SHRenderable> : std::true_type {};
|
||||||
|
template<>
|
||||||
|
struct HasYAMLConv<SHTextRenderableComponent> : std::true_type {};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct convert<SHVec4>
|
struct convert<SHVec4>
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue