Collider Component Inspector, Editor routine #88

Merged
srishamharan merged 4 commits from SP3-4-editor_fix into main 2022-10-14 15:58:43 +08:00
8 changed files with 506 additions and 299 deletions

View File

@ -56,46 +56,58 @@ namespace Sandbox
) )
{ {
// Set working directory // Set working directory
SHADE::SHFileUtilities::SetWorkDirToExecDir(); SHFileUtilities::SetWorkDirToExecDir();
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow); window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
// Create Systems // Create Systems
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>(); SHSystemManager::CreateSystem<SHGraphicsSystem>();
SHADE::SHSystemManager::CreateSystem<SHADE::SHScriptEngine>(); SHSystemManager::CreateSystem<SHScriptEngine>();
SHADE::SHSystemManager::CreateSystem<SHADE::SHPhysicsSystem>(); SHSystemManager::CreateSystem<SHPhysicsSystem>();
SHADE::SHSystemManager::CreateSystem<SHADE::SHTransformSystem>(); SHSystemManager::CreateSystem<SHTransformSystem>();
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>()); SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
SHADE::SHSystemManager::CreateSystem<SHADE::SHAudioSystem>(); SHSystemManager::CreateSystem<SHAudioSystem>();
#ifdef SHEDITOR
SDL_Init(SDL_INIT_VIDEO);
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
SHSystemManager::CreateSystem<SHEditor>();
SHSystemManager::GetSystem<SHEditor>()->SetSDLWindow(sdlWindow);
#endif
// Create Routines // Create Routines
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameSetUpRoutine>(); SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::FrameSetUpRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::UpdateRoutine>(); SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::UpdateRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::LateUpdateRoutine>(); SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::LateUpdateRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHScriptEngine, SHADE::SHScriptEngine::FrameCleanUpRoutine>(); SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::FrameCleanUpRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHPhysicsSystem, SHADE::SHPhysicsSystem::PhysicsPreUpdate>(); SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHPhysicsSystem, SHADE::SHPhysicsSystem::PhysicsFixedUpdate>(); SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHPhysicsSystem, SHADE::SHPhysicsSystem::PhysicsPostUpdate>(); SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHTransformSystem, SHADE::SHTransformSystem::TransformUpdateRoutine>(); SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformUpdateRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BatcherDispatcherRoutine>(); SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
//SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::BeginRoutine>(); SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
//SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::RenderRoutine>();
//SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>();
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRigidBodyComponent>(); #ifdef SHEDITOR
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHColliderComponent>(); SHSystemManager::RegisterRoutine<SHEditor, SHEditor::EditorRoutine>();
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>(); #endif
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::RenderRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::EndRoutine>();
SHComponentManager::CreateComponentSparseSet<SHRigidBodyComponent>();
SHComponentManager::CreateComponentSparseSet<SHColliderComponent>();
SHComponentManager::CreateComponentSparseSet<SHTransformComponent>();
SHComponentManager::CreateComponentSparseSet<SHRenderable>();
//TODO: REMOVE AFTER PRESENTATION //TODO: REMOVE AFTER PRESENTATION
//SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf"); //SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh"); SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh");
//SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds"); //SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
//SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds"); //SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
SHADE::SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex"); SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex");
//TODO: REMOVE AFTER PRESENTATION //TODO: REMOVE AFTER PRESENTATION
@ -103,19 +115,12 @@ namespace Sandbox
auto id2 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>(); auto id2 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>(); auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHAudioSystem, SHADE::SHAudioSystem::AudioRoutine>(); SHSystemManager::RegisterRoutine<SHAudioSystem, SHAudioSystem::AudioRoutine>();
// Set up graphics system and windows // Set up graphics system and windows
graphicsSystem->SetWindow(&window); graphicsSystem->SetWindow(&window);
SHADE::SHSystemManager::Init(); SHSystemManager::Init();
#ifdef SHEDITOR
SDL_Init(SDL_INIT_VIDEO);
sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
SHADE::SHEditor::Initialise(sdlWindow);
#else
#endif
SHSceneManager::InitSceneManager<SBTestScene>("TestScene"); SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
@ -124,26 +129,15 @@ namespace Sandbox
void SBApplication::Update(void) void SBApplication::Update(void)
{ {
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>()); SHGraphicsSystem* graphicsSystem = SHADE::SHSystemManager::GetSystem<SHGraphicsSystem>();
//TODO: Change true to window is open //TODO: Change true to window is open
while (!window.WindowShouldClose()) while (!window.WindowShouldClose())
{ {
SHFrameRateController::UpdateFRC(); SHFrameRateController::UpdateFRC();
SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime()); SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime());
SHSceneManager::UpdateSceneManager(); SHSceneManager::UpdateSceneManager();
SHSceneManager::SceneUpdate(1/60.0f); SHSceneManager::SceneUpdate(0.016f);
//#ifdef SHEDITOR SHSystemManager::RunRoutines(false, 0.016f);
//#endif
graphicsSystem->BeginRender();
#ifdef SHEDITOR
SHADE::SHEditor::Update(0.16f);
#endif
graphicsSystem->Run(1.0f);
graphicsSystem->EndRender();
SHADE::SHSystemManager::RunRoutines(false, 0.016f);
} }
// Finish all graphics jobs first // Finish all graphics jobs first
@ -154,13 +148,12 @@ namespace Sandbox
void SBApplication::Exit(void) void SBApplication::Exit(void)
{ {
#ifdef SHEDITOR #ifdef SHEDITOR
SHADE::SHEditor::Exit();
SDL_DestroyWindow(sdlWindow); SDL_DestroyWindow(sdlWindow);
SDL_Quit(); SDL_Quit();
#endif #endif
SHSceneManager::Exit(); SHSceneManager::Exit();
SHADE::SHSystemManager::Exit(); SHSystemManager::Exit();
} }
} }

View File

@ -6,11 +6,11 @@
//#==============================================================# //#==============================================================#
//|| SHADE Includes || //|| SHADE Includes ||
//#==============================================================# //#==============================================================#
#include "Editor/SHEditor.hpp"
#include "Editor/SHImGuiHelpers.hpp" #include "Editor/SHImGuiHelpers.hpp"
#include "Editor/SHEditorWidgets.hpp" #include "Editor/SHEditorWidgets.hpp"
#include "SHHierarchyPanel.h" #include "SHHierarchyPanel.h"
#include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHEntityManager.h"
#include "Editor/SHEditor.hpp"
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
#include "Editor/DragDrop/SHDragDrop.hpp" #include "Editor/DragDrop/SHDragDrop.hpp"
#include "Tools/SHException.h" #include "Tools/SHException.h"
@ -62,7 +62,8 @@ namespace SHADE
if(ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) if(ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
{ {
SHEditor::selectedEntities.clear(); if(auto editor = SHSystemManager::GetSystem<SHEditor>())
editor->selectedEntities.clear();
} }
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal); ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
ImGui::End(); ImGui::End();
@ -102,7 +103,9 @@ namespace SHADE
//Get node data (Children, eid, selected) //Get node data (Children, eid, selected)
auto& children = currentNode->GetChildren(); auto& children = currentNode->GetChildren();
EntityID eid = currentNode->GetEntityID(); EntityID eid = currentNode->GetEntityID();
const bool isSelected = (std::ranges::find(SHEditor::selectedEntities, eid) != SHEditor::selectedEntities.end()); auto editor = SHSystemManager::GetSystem<SHEditor>();
const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end());
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow); const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
@ -140,8 +143,8 @@ namespace SHADE
{ {
if(!isSelected) if(!isSelected)
{ {
SHEditor::selectedEntities.clear(); editor->selectedEntities.clear();
SHEditor::selectedEntities.push_back(eid); editor->selectedEntities.push_back(eid);
} }
if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data())) if(ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data()))
{ {
@ -163,19 +166,19 @@ namespace SHADE
if (!isSelected) if (!isSelected)
{ {
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
SHEditor::selectedEntities.clear(); editor->selectedEntities.clear();
SHEditor::selectedEntities.push_back(eid); editor->selectedEntities.push_back(eid);
}//if not selected }//if not selected
else else
{ {
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
{ {
auto it = std::ranges::remove(SHEditor::selectedEntities, eid).begin(); auto it = std::ranges::remove(editor->selectedEntities, eid).begin();
}//if mod ctrl is not pressed }//if mod ctrl is not pressed
else else
{ {
SHEditor::selectedEntities.clear(); editor->selectedEntities.clear();
SHEditor::selectedEntities.push_back(eid); editor->selectedEntities.push_back(eid);
} }
}//if selected }//if selected
}//if left mouse button released }//if left mouse button released

View File

@ -12,6 +12,7 @@
#include "Editor/IconsMaterialDesign.h" #include "Editor/IconsMaterialDesign.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 "Reflection/SHReflectionMetadata.h" #include "Reflection/SHReflectionMetadata.h"
namespace SHADE namespace SHADE
{ {
@ -45,7 +46,7 @@ namespace SHADE
{ {
if (!component) if (!component)
return; return;
auto componentType = rttr::type::get(*component); const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::CollapsingHeader(componentType.get_name().data())) if (ImGui::CollapsingHeader(componentType.get_name().data()))
@ -190,4 +191,69 @@ namespace SHADE
} }
else DrawContextMenu(component); else DrawContextMenu(component);
} }
template<>
static void DrawComponent(SHColliderComponent* component)
{
if (!component)
return;
const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
ImGui::SameLine();
if (ImGui::CollapsingHeader(componentType.get_name().data()))
{
DrawContextMenu(component);
auto& colliders = component->GetColliders();
int const size = static_cast<int>(colliders.size());
ImGui::BeginChild("Colliders", {0.0f, colliders.empty() ? 1.0f : 250.0f}, true);
for (int i{}; i < size; ++i)
{
SHCollider& collider = component->GetCollider(i);
auto cursorPos = ImGui::GetCursorPos();
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 });
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);});
}
else if (collider.GetType() == SHCollider::Type::SPHERE)
{
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
SHEditorWidgets::DragFloat("Radius", [sphere] {return sphere->GetRadius(); }, [sphere](float const& value) {sphere->SetRadius(value);});
}
else if (collider.GetType() == SHCollider::Type::CAPSULE)
{
}
{
SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f });
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider.GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider.SetPositionOffset(vec); });
SHEditorWidgets::EndPanel();
}
if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
{
component->RemoveCollider(i);
}
SHEditorWidgets::EndPanel();
}
ImGui::EndChild();
if (ImGui::BeginMenu("Add Collider"))
{
if(ImGui::Selectable("Box Collider"))
{
component->AddBoundingBox();
}
if(ImGui::Selectable("Sphere Collider"))
{
component->AddBoundingSphere();
}
ImGui::EndMenu();
}
}
else DrawContextMenu(component);
}
} }

View File

@ -1,5 +1,6 @@
#include "SHpch.h" #include "SHpch.h"
#include "Editor/SHEditor.hpp"
#include "SHEditorInspector.h" #include "SHEditorInspector.h"
#include "ECS_Base/SHECSMacros.h" #include "ECS_Base/SHECSMacros.h"
@ -7,7 +8,6 @@
#include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHEntityManager.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Editor/SHEditor.hpp"
#include "Editor/SHImGuiHelpers.hpp" #include "Editor/SHImGuiHelpers.hpp"
#include "Editor/SHEditorWidgets.hpp" #include "Editor/SHEditorWidgets.hpp"
#include "SHEditorComponentView.hpp" #include "SHEditorComponentView.hpp"
@ -24,12 +24,15 @@
namespace SHADE 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>
void DrawAddComponentButton(EntityID const& eid) bool DrawAddComponentButton(EntityID const& eid)
{ {
if(!SHComponentManager::HasComponent<ComponentType>(eid) && ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data())) bool selected = false;
if(!SHComponentManager::HasComponent<ComponentType>(eid))
{ {
if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()); selected)
SHComponentManager::AddComponent<ComponentType>(eid); SHComponentManager::AddComponent<ComponentType>(eid);
} }
return selected;
} }
SHEditorInspector::SHEditorInspector() SHEditorInspector::SHEditorInspector()
@ -47,15 +50,10 @@ namespace SHADE
SHEditorWindow::Update(); SHEditorWindow::Update();
if (Begin()) if (Begin())
{ {
if (ImGui::Button("AUDIO")) auto editor = SHSystemManager::GetSystem<SHEditor>();
if (editor && !editor->selectedEntities.empty())
{ {
auto audioSystem = SHSystemManager::GetSystem<SHADE::SHAudioSystem>(); EntityID const& eid = editor->selectedEntities[0];
audioSystem->PlayEventOnce("event:/Characters/sfx_footsteps_raccoon");
}
if (!SHEditor::selectedEntities.empty())
{
EntityID const& eid = SHEditor::selectedEntities[0];
SHEntity* entity = SHEntityManager::GetEntityByID(eid); SHEntity* entity = SHEntityManager::GetEntityByID(eid);
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid); ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
@ -90,7 +88,13 @@ namespace SHADE
DrawAddComponentButton<SHTransformComponent>(eid); DrawAddComponentButton<SHTransformComponent>(eid);
DrawAddComponentButton<SHRenderable>(eid); DrawAddComponentButton<SHRenderable>(eid);
DrawAddComponentButton<SHColliderComponent>(eid); DrawAddComponentButton<SHColliderComponent>(eid);
DrawAddComponentButton<SHRigidBodyComponent>(eid); if(DrawAddComponentButton<SHRigidBodyComponent>(eid))
{
if(SHComponentManager::GetComponent_s<SHTransformComponent>(eid) == nullptr)
{
SHComponentManager::AddComponent<SHTransformComponent>(eid);
}
}
ImGui::EndMenu(); ImGui::EndMenu();
} }

View File

@ -3,11 +3,11 @@
//#==============================================================# //#==============================================================#
//|| SHADE Includes || //|| SHADE Includes ||
//#==============================================================# //#==============================================================#
#include "Editor/SHEditor.hpp"
#include "SHEditorMenuBar.h" #include "SHEditorMenuBar.h"
#include "Editor/IconsMaterialDesign.h" #include "Editor/IconsMaterialDesign.h"
#include "Editor/Command/SHCommandManager.h" #include "Editor/Command/SHCommandManager.h"
#include "Scripting/SHScriptEngine.h" #include "Scripting/SHScriptEngine.h"
#include "Editor/SHEditor.hpp"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
//#==============================================================# //#==============================================================#
@ -95,7 +95,8 @@ namespace SHADE
{ {
if(ImGui::Selectable(style.to_string().c_str())) if(ImGui::Selectable(style.to_string().c_str()))
{ {
SHEditor::SetStyle(style.convert<SHEditor::Style>()); if(auto editor = SHSystemManager::GetSystem<SHEditor>())
editor->SetStyle(style.convert<SHEditor::Style>());
} }
} }
ImGui::EndMenu(); ImGui::EndMenu();

View File

@ -60,18 +60,18 @@ RTTR_REGISTRATION
namespace SHADE namespace SHADE
{ {
//#==============================================================# //#==============================================================#
//|| Initialise static members || //|| Init static members ||
//#==============================================================# //#==============================================================#
Handle<SHVkCommandPool> SHEditor::imguiCommandPool; //Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer; //Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
SHEditor::EditorWindowMap SHEditor::editorWindows{}; SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
SHEditor::EditorWindowID SHEditor::windowCount{}; SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
std::vector<EntityID> SHEditor::selectedEntities; //std::vector<EntityID> SHEditor::selectedEntities;
//#==============================================================# //#==============================================================#
//|| Public Member Functions || //|| Public Member Functions ||
//#==============================================================# //#==============================================================#
void SHEditor::Initialise(SDL_Window* const sdlWindow) void SHEditor::Init()
{ {
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
if(auto context = ImGui::CreateContext()) if(auto context = ImGui::CreateContext())
@ -90,28 +90,28 @@ namespace SHADE
InitFonts(); InitFonts();
auto id = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>(); auto id = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
auto id2 = SHFamilyID<SHSystem>::GetID<SHTransformSystem>(); auto id2 = SHFamilyID<SHSystem>::GetID<SHTransformSystem>();
auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>(); auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
InitBackend(sdlWindow);
InitBackend();
SetStyle(Style::SHADE); SetStyle(Style::SHADE);
//Add editor windows //Add editor windows
CreateEditorWindow<SHEditorMenuBar>(); SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
CreateEditorWindow<SHHierarchyPanel>(); SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
CreateEditorWindow<SHEditorInspector>(); SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
CreateEditorWindow<SHEditorProfiler>(); SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
SHLOG_INFO("Successfully initialised SHADE Engine Editor") SHLOG_INFO("Successfully initialised SHADE Engine Editor")
} }
void SHEditor::Update(float const dt) void SHEditor::Update(double const dt)
{ {
(void)dt; (void)dt;
NewFrame(); NewFrame();
for (const auto& window : editorWindows | std::views::values) for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
{ {
if(window->isOpen) if(window->isOpen)
window->Update(); window->Update();
@ -147,7 +147,7 @@ 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
static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.PixelSnapH = true; 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 ImFont* UIFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path
io.Fonts->Build(); io.Fonts->Build();
@ -260,7 +260,7 @@ namespace SHADE
//#==============================================================# //#==============================================================#
//|| Private Member Functions || //|| Private Member Functions ||
//#==============================================================# //#==============================================================#
void SHEditor::InitBackend(SDL_Window* sdlWindow) void SHEditor::InitBackend()
{ {
if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false) if(ImGui_ImplSDL2_InitForVulkan(sdlWindow) == false)
{ {
@ -322,4 +322,9 @@ namespace SHADE
} }
void SHEditor::EditorRoutine::Execute(double dt) noexcept
{
reinterpret_cast<SHEditor*>(system)->Update(dt);
}
}//namespace SHADE }//namespace SHADE

View File

@ -11,6 +11,8 @@
//#==============================================================# //#==============================================================#
#include "SH_API.h" #include "SH_API.h"
#include "ECS_Base/SHECSMacros.h" #include "ECS_Base/SHECSMacros.h"
#include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/Handle.h" #include "Resource/Handle.h"
#include "EditorWindow/SHEditorWindow.h" #include "EditorWindow/SHEditorWindow.h"
#include "Tools/SHLogger.h" #include "Tools/SHLogger.h"
@ -28,11 +30,7 @@ namespace SHADE
class SHVkCommandBuffer; class SHVkCommandBuffer;
class SHVkCommandPool; class SHVkCommandPool;
/** class SHEditorWindowManager
* @brief SHEditor static class contains editor variables and implementation of editor functions.
*
*/
class SH_API SHEditor
{ {
public: public:
//#==============================================================# //#==============================================================#
@ -41,46 +39,6 @@ namespace SHADE
using EditorWindowID = uint8_t; using EditorWindowID = uint8_t;
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>; using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>; using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
/**
* @brief Style options
*
*/
enum class Style : uint8_t
{
SHADE,
DARK,
LIGHT,
CLASSIC
};
/**
* @brief Initialise the editor
*
* @param sdlWindow pointer to SDL_Window object created in application
*/
static void Initialise(SDL_Window* sdlWindow);
/**
* @brief Update the editor and add to ImGui DrawList
*
* @param dt Delta-time of the frame
*/
static void Update(float dt);
/**
* @brief Safely shutdown the editor
*
*/
static void Exit();
/**
* @brief Set the Style for the editor
*
* @param style Desired style
*/
static void SetStyle(Style style);
/** /**
* @brief Get ID for the Editor Window Type * @brief Get ID for the Editor Window Type
* *
@ -100,39 +58,6 @@ namespace SHADE
return id; return id;
} }
/**
* @brief Get pointer to the Editor Window
*
* @tparam T Type of editor window to retrieve
* @return T* Pointer to the editor window
*/
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
static T* GetEditorWindow()
{
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
}
// List of selected entities
static std::vector<EntityID> selectedEntities;
private:
/**
* @brief Initialise Backend for ImGui (SDL and Vulkan backend)
*
* @param sdlWindow Pointer to SDL_Window
*/
static void InitBackend(SDL_Window* sdlWindow);
/**
* @brief Start new frame for editor
*
*/
static void NewFrame();
/**
* @brief Perform ImGui and ImGui Backend Render
*
*/
static void Render();
/** /**
* @brief Create an Editor Window * @brief Create an Editor Window
* *
@ -153,16 +78,114 @@ namespace SHADE
} }
} }
static void InitFonts() noexcept; /**
* @brief Get pointer to the Editor Window
// Handle to command pool used for ImGui Vulkan Backend *
static Handle<SHVkCommandPool> imguiCommandPool; * @tparam T Type of editor window to retrieve
// Handle to command buffer used for ImGui Vulkan Backend * @return T* Pointer to the editor window
static Handle<SHVkCommandBuffer> imguiCommandBuffer; */
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
static T* GetEditorWindow()
{
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
}
private:
// Number of windows; used for Editor Window ID Generation // Number of windows; used for Editor Window ID Generation
static EditorWindowID windowCount; static EditorWindowID windowCount;
// Map of Editor Windows // Map of Editor Windows
static EditorWindowMap editorWindows; static EditorWindowMap editorWindows;
friend class SHEditor;
};
/**
* @brief SHEditor static class contains editor variables and implementation of editor functions.
*
*/
class SH_API SHEditor final : public SHSystem
{
public:
class SH_API EditorRoutine final : public SHSystemRoutine
{
public:
EditorRoutine() = default;
void Execute(double dt) noexcept override final;
};
/**
* @brief Style options
*
*/
enum class Style : uint8_t
{
SHADE,
DARK,
LIGHT,
CLASSIC
};
/**
* @brief Initialise the editor
*
* @param sdlWindow pointer to SDL_Window object created in application
*/
void Init();
/**
* @brief Update the editor and add to ImGui DrawList
*
* @param dt Delta-time of the frame
*/
void Update(double dt);
/**
* @brief Safely shutdown the editor
*
*/
void Exit();
/**
* @brief Set the Style for the editor
*
* @param style Desired style
*/
void SetStyle(Style style);
/**
* @brief Initialise Backend for ImGui (SDL and Vulkan backend)
*
* @param sdlWindow Pointer to SDL_Window
*/
void InitBackend();
void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;};
// List of selected entities
std::vector<EntityID> selectedEntities;
private:
/**
* @brief Start new frame for editor
*
*/
void NewFrame();
/**
* @brief Perform ImGui and ImGui Backend Render
*
*/
void Render();
void InitFonts() noexcept;
// Handle to command pool used for ImGui Vulkan Backend
Handle<SHVkCommandPool> imguiCommandPool;
// Handle to command buffer used for ImGui Vulkan Backend
Handle<SHVkCommandBuffer> imguiCommandBuffer;
SDL_Window* sdlWindow;
};//class SHEditor };//class SHEditor
}//namespace SHADE }//namespace SHADE

View File

@ -35,6 +35,118 @@ namespace SHADE
//#==============================================================# //#==============================================================#
//|| Custom Widgets || //|| Custom Widgets ||
//#==============================================================# //#==============================================================#
inline static ImVector<ImRect> panelStack{};
static void BeginPanel(std::string_view const& name, const ImVec2& size)
{
ImGui::BeginGroup();
auto cursorPos = ImGui::GetCursorScreenPos();
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
auto frameHeight = ImGui::GetFrameHeight();
ImGui::BeginGroup();
ImVec2 effectiveSize = size;
if (size.x < 0.0f)
effectiveSize.x = ImGui::GetContentRegionAvail().x;
else
effectiveSize.x = size.x;
ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f));
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
ImGui::SameLine(0.0f, 0.0f);
ImGui::BeginGroup();
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
ImGui::SameLine(0.0f, 0.0f);
ImGui::TextUnformatted(name.data());
auto labelMin = ImGui::GetItemRectMin();
auto labelMax = ImGui::GetItemRectMax();
ImGui::SameLine(0.0f, 0.0f);
ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y));
ImGui::BeginGroup();
ImGui::PopStyleVar(2);
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f;
ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f;
ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f;
ImGui::GetCurrentWindow()->Size.x -= frameHeight;
auto itemWidth = ImGui::CalcItemWidth();
ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight));
panelStack.push_back(ImRect(labelMin, labelMax));
}
static void EndPanel()
{
ImGui::PopItemWidth();
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
auto frameHeight = ImGui::GetFrameHeight();
ImGui::EndGroup();
ImGui::EndGroup();
ImGui::SameLine(0.0f, 0.0f);
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y));
ImGui::EndGroup();
auto itemMin = ImGui::GetItemRectMin();
auto itemMax = ImGui::GetItemRectMax();
auto labelRect = panelStack.back();
panelStack.pop_back();
ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f;
ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f));
labelRect.Min.x -= itemSpacing.x;
labelRect.Max.x += itemSpacing.x;
for (int i = 0; i < 4; ++i)
{
switch (i)
{
// left half-plane
case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break;
// right half-plane
case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break;
// top
case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, -FLT_MAX), ImVec2(labelRect.Max.x, labelRect.Min.y), true); break;
// bottom
case 3: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break;
}
ImGui::GetWindowDrawList()->AddRect(
frameRect.Min, frameRect.Max,
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Button)),
halfFrame.x);
ImGui::PopClipRect();
}
ImGui::PopStyleVar(2);
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f;
ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f;
ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f;
ImGui::GetCurrentWindow()->Size.x += frameHeight;
ImGui::Dummy(ImVec2(0.0f, 0.0f));
ImGui::EndGroup();
}
static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f) static bool Splitter(bool verticalSplit, float thickness, float* size1, float* size2, float minSize1, float minSize2, float splitterAxisSize = -1.0f)
{ {
ImGuiWindow* window = ImGui::GetCurrentWindow(); ImGuiWindow* window = ImGui::GetCurrentWindow();