Canvas and UI Component #222

Merged
maverickdgg merged 5 commits from SP3-20-UI-System into main 2022-11-18 12:29:40 +08:00
8 changed files with 309 additions and 6 deletions

View File

@ -33,6 +33,7 @@
#include "Physics/System/SHPhysicsSystem.h"
#include "Physics/System/SHPhysicsDebugDrawSystem.h"
#include "Scripting/SHScriptEngine.h"
#include "UI/SHUISystem.h"
// Components
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
@ -77,6 +78,7 @@ namespace Sandbox
SHSystemManager::CreateSystem<SHAudioSystem>();
SHSystemManager::CreateSystem<SHCameraSystem>();
SHSystemManager::CreateSystem<SHUISystem>();
SHSystemManager::CreateSystem<SHGraphicsSystem>();
@ -120,6 +122,8 @@ namespace Sandbox
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
//SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::EditorCameraUpdate>();
SHSystemManager::RegisterRoutine<SHUISystem, SHUISystem::AddUIComponentRoutine>();
SHSystemManager::RegisterRoutine<SHUISystem, SHUISystem::UpdateUIMatrixRoutine>();
SHSystemManager::RegisterRoutine<SHCameraSystem, SHCameraSystem::CameraSystemUpdate>();
#ifdef SHEDITOR

View File

@ -37,8 +37,6 @@ namespace SHADE
void Exit (void);
friend class EditorCameraUpdate;
class SH_API CameraSystemUpdate final: public SHSystemRoutine
{
public:

View File

@ -0,0 +1,60 @@
#include "SHpch.h"
#include "SHCanvasComponent.h"
namespace SHADE
{
SHCanvasComponent::SHCanvasComponent()
:width(1),height(1), dirtyMatrix(false), canvasMatrix()
{
}
void SHCanvasComponent::SetCanvasSize(CanvasSizeType width, CanvasSizeType height) noexcept
{
this->width = width;
this->height = height;
}
void SHCanvasComponent::SetCanvasWidth(CanvasSizeType val) noexcept
{
width = val;
}
void SHCanvasComponent::SetCanvasHeight(CanvasSizeType val) noexcept
{
height = val;
}
SHCanvasComponent::CanvasSizeType SHCanvasComponent::GetCanvasWidth() const noexcept
{
return width;
}
SHCanvasComponent::CanvasSizeType SHCanvasComponent::GetCanvasHeight() const noexcept
{
return height;
}
SHMatrix const& SHCanvasComponent::GetMatrix() const noexcept
{
return canvasMatrix;
}
}
RTTR_REGISTRATION
{
using namespace SHADE;
using namespace rttr;
registration::class_<SHCanvasComponent>("Canvas Component")
.property("Canvas Width", &SHCanvasComponent::GetCanvasWidth, &SHCanvasComponent::SetCanvasWidth)
.property("Canvas Height", &SHCanvasComponent::GetCanvasHeight, &SHCanvasComponent::SetCanvasHeight)
;
}

View File

@ -1,7 +1,10 @@
#pragma once
#include <rttr/registration>
#include "SH_API.h"
#include "ECS_Base/Components/SHComponent.h"
#include "Math/SHMatrix.h"
namespace SHADE
@ -13,6 +16,9 @@ namespace SHADE
public:
friend class SHUISystem;
SHCanvasComponent();
~SHCanvasComponent() = default;
@ -20,15 +26,18 @@ namespace SHADE
void SetCanvasWidth(CanvasSizeType width) noexcept;
void SetCanvasHeight(CanvasSizeType height) noexcept;
CanvasSizeType const GetCanvasWidth() const noexcept;
CanvasSizeType const GetCanvasHeight() const noexcept;
CanvasSizeType GetCanvasWidth() const noexcept;
CanvasSizeType GetCanvasHeight() const noexcept;
SHMatrix const& GetMatrix() const noexcept;
private:
CanvasSizeType width;
CanvasSizeType height;
bool dirtyMatrix;
SHMatrix canvasMatrix;
RTTR_ENABLE()
};

View File

@ -0,0 +1,32 @@
#include "SHpch.h"
#include "SHUIComponent.h"
namespace SHADE
{
SHUIComponent::SHUIComponent()
{
}
SHMatrix const& SHUIComponent::GetMatrix()const noexcept
{
return localToCanvasMatrix;
}
}
RTTR_REGISTRATION
{
using namespace SHADE;
using namespace rttr;
registration::class_<SHUIComponent>("Canvas Component")
;
}

View File

@ -0,0 +1,32 @@
#pragma once
#include <rttr/registration>
#include "SH_API.h"
#include "ECS_Base/Components/SHComponent.h"
#include "Math/SHMatrix.h"
namespace SHADE
{
class SH_API SHUIComponent final: public SHComponent
{
public:
friend class SHUISystem;
SHUIComponent();
~SHUIComponent() = default;
SHMatrix const& GetMatrix() const noexcept;
private:
SHMatrix localToCanvasMatrix;
EntityID canvasID;
RTTR_ENABLE()
};
}

View File

@ -0,0 +1,113 @@
#include "SHpch.h"
#include "SHUISystem.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Math/Transform/SHTransformComponent.h"
namespace SHADE
{
void SHUISystem::Init()
{
SystemFamily::GetID<SHUISystem>();
SHComponentManager::CreateComponentSparseSet<SHCanvasComponent>();
SHComponentManager::CreateComponentSparseSet<SHUIComponent>();
}
void SHUISystem::Exit()
{
}
void SHUISystem::AddUIComponentRoutine::Execute(double dt) noexcept
{
auto& dense = SHComponentManager::GetDense<SHCanvasComponent>();
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
//Go through all the canvases and make sure all the children has a UIComponent.
for (auto& canvas : dense)
{
auto& children = sceneGraph.GetChildren(canvas.GetEID());
for (auto& child : children)
{
RecurssiveUIComponentCheck(child, canvas);
}
}
//Go through all the UI Component and make sure the parent has a UI or Canvas Component
std::vector<EntityID> entitiesToRemove;
auto& UIDense = SHComponentManager::GetDense<SHUIComponent>();
for (auto& ui : UIDense)
{
SHSceneNode* parentNode = sceneGraph.GetParent(ui.GetEID());
if (parentNode == nullptr || !(SHComponentManager::HasComponent<SHUIComponent>(parentNode->GetEntityID()) || SHComponentManager::HasComponent<SHCanvasComponent>(parentNode->GetEntityID())))
entitiesToRemove.push_back(ui.GetEID());
}
for (auto& id : entitiesToRemove)
{
SHComponentManager::RemoveComponent<SHUIComponent>(id);
}
}
void SHUISystem::AddUIComponentRoutine::RecurssiveUIComponentCheck(SHSceneNode* node, SHCanvasComponent& canvas) noexcept
{
if (node == nullptr)
return;
EntityID eid = node->GetEntityID();
if(SHComponentManager::HasComponent<SHUIComponent>(eid) == false)
SHComponentManager::AddComponent<SHUIComponent>(eid);
else
{
SHComponentManager::GetComponent<SHUIComponent>(eid)->canvasID = canvas.GetEID();
}
auto& children = SHSceneManager::GetCurrentSceneGraph().GetChildren(eid);
for (auto& child : children)
{
RecurssiveUIComponentCheck(child, canvas);
}
}
void SHUISystem::UpdateUIMatrixRoutine::Execute(double dt) noexcept
{
SHUISystem* system = (SHUISystem* )GetSystem();
auto& dense = SHComponentManager::GetDense<SHUIComponent>();
for (auto& comp : dense)
{
system->UpdateUIComponent(comp);
}
}
void SHUISystem::UpdateUIComponent(SHUIComponent& comp) noexcept
{
auto canvasComp = SHComponentManager::GetComponent_s<SHCanvasComponent>(comp.canvasID);
if (SHComponentManager::HasComponent<SHTransformComponent>(comp.GetEID()))
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID());
if (canvasComp != nullptr)
comp.localToCanvasMatrix = canvasComp->GetMatrix() * transform->GetTRS();
else
comp.localToCanvasMatrix = transform->GetTRS();
}
else //If for some reason UI Components entities does not have a transform.
{
if (canvasComp != nullptr)
comp.localToCanvasMatrix = canvasComp->GetMatrix();
else
comp.localToCanvasMatrix = SHMatrix::Identity;
}
}
}//end namespace

View File

@ -0,0 +1,55 @@
#pragma once
#include "SH_API.h"
#include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystemRoutine.h"
#include "SHUIComponent.h"
#include "SHCanvasComponent.h"
#include "Scene/SHSceneGraph.h"
#include "Scene/SHSceneManager.h"
namespace SHADE
{
class SH_API SHUISystem final: public SHSystem
{
public:
SHUISystem() = default;
~SHUISystem() = default;
class SH_API AddUIComponentRoutine final: public SHSystemRoutine
{
public:
AddUIComponentRoutine() :SHSystemRoutine("Add UI Component Routine", true) {};
virtual void Execute(double dt) noexcept override final;
private:
void RecurssiveUIComponentCheck(SHSceneNode* node, SHCanvasComponent& canvas) noexcept;
};
friend class AddUIComponentRoutine;
class SH_API UpdateUIMatrixRoutine final: public SHSystemRoutine
{
public:
UpdateUIMatrixRoutine() : SHSystemRoutine("Update UI Matrix Routine", true) {};
virtual void Execute(double dt) noexcept override final;
};
friend class UpdateUIMatrixRoutine;
void Init();
void Exit();
private:
void UpdateUIComponent(SHUIComponent& comp) noexcept;
};
}