Merge branch 'SP3-1-Rendering' of https://github.com/SHADE-DP/SHADE_Y3 into SP3-1-Rendering

This commit is contained in:
Kah Wei 2022-09-21 20:03:03 +08:00
commit 791c4cd0d0
35 changed files with 498 additions and 286 deletions

View File

@ -21,6 +21,11 @@
#include "Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h" #include "Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h"
#include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHEntityManager.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Scene/SHSceneManager.h"
#include "Scenes/SBTestScene.h"
using namespace SHADE;
namespace Sandbox namespace Sandbox
{ {
@ -45,7 +50,7 @@ namespace Sandbox
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::RenderRoutine>(); SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::RenderRoutine>();
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>(); SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::EndRoutine>();
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>(); SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
graphicsSystem->SetWindow(&window); graphicsSystem->SetWindow(&window);
sdlWindow = SDL_CreateWindowFrom(window.GetHWND()); sdlWindow = SDL_CreateWindowFrom(window.GetHWND());
@ -61,28 +66,17 @@ namespace Sandbox
// Set up scripting // Set up scripting
SHADE::SHScriptEngine::Init(); SHADE::SHScriptEngine::Init();
// Create temp meshes SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem);
graphicsSystem->BuildMeshBuffers();
// Create Materials
auto matInst = graphicsSystem->AddMaterialInstance();
// Create entity and add mesh
auto entity = SHADE::SHEntityManager::CreateEntity<SHADE::SHRenderable>();
auto& renderable = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHRenderable>(entity);
renderable.Mesh = CUBE_MESH;
renderable.SetMaterial(matInst);
renderable.TransformMatrix.Translate(0.0f, 0.0f, 2.0f);
} }
void SBApplication::Update(void) void SBApplication::Update(void)
{ {
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>()); SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
//TODO: Change true to window is open //TODO: Change true to window is open
while (!window.WindowShouldClose()) while (!window.WindowShouldClose())
{ {
SHSceneManager::UpdateSceneManager();
SHSceneManager::SceneUpdate(1/60.0f);
//#ifdef SHEDITOR //#ifdef SHEDITOR
//#endif //#endif
graphicsSystem->BeginRender(); graphicsSystem->BeginRender();
@ -108,7 +102,7 @@ namespace Sandbox
#ifdef SHEDITOR #ifdef SHEDITOR
SHADE::SHEditor::Exit(); SHADE::SHEditor::Exit();
#endif #endif
SHSceneManager::Exit();
SHADE::SHScriptEngine::Exit(); SHADE::SHScriptEngine::Exit();
SHADE::SHSystemManager::Exit(); SHADE::SHSystemManager::Exit();
SDL_DestroyWindow(sdlWindow); SDL_DestroyWindow(sdlWindow);

View File

@ -1,6 +1,13 @@
#include "SBpch.h" #include "SBpch.h"
#include "SBTestScene.h" #include "SBTestScene.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Graphics/MiddleEnd/Meshes/SHPrimitiveGenerator.h"
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Scene/SHSceneManager.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
using namespace SHADE; using namespace SHADE;
namespace Sandbox namespace Sandbox
@ -21,7 +28,20 @@ namespace Sandbox
} }
void SBTestScene::Init() void SBTestScene::Init()
{ {
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
// Create temp meshes
const auto CUBE_MESH = SHADE::SHPrimitiveGenerator::Cube(*graphicsSystem);
graphicsSystem->BuildMeshBuffers();
// Create Materials
auto matInst = graphicsSystem->AddMaterialInstance();
// Create entity and add mesh
auto entity = SHADE::SHEntityManager::CreateEntity<SHADE::SHRenderable>();
auto& renderable = *SHADE::SHComponentManager::GetComponent_s<SHADE::SHRenderable>(entity);
renderable.Mesh = CUBE_MESH;
renderable.SetMaterial(matInst);
renderable.TransformMatrix.Translate(0.0f, 0.0f, 2.0f);
} }
void SBTestScene::Update(float dt) void SBTestScene::Update(float dt)
{ {

View File

@ -47,32 +47,57 @@ namespace SHADE
void SHEntity::SetParent(SHEntity* newParent) noexcept void SHEntity::SetParent(SHEntity* newParent) noexcept
{ {
(void)newParent; SHSceneManager::GetCurrentSceneGraph().SetParent(GetEID(), newParent->GetEID());
//TODO
} }
void SHEntity::SetParent(EntityID newParentID) noexcept void SHEntity::SetParent(EntityID newParentID) noexcept
{ {
(void)newParentID; SHSceneManager::GetCurrentSceneGraph().SetParent(GetEID(), newParentID);
//TODO
} }
SHEntity* SHEntity::GetParent()const noexcept SHEntity* SHEntity::GetParent()const noexcept
{ {
//TODO SHSceneNode* parent = SHSceneManager::GetCurrentSceneGraph().GetParent(GetEID());
return nullptr; if (parent != nullptr)
return SHEntityManager::GetEntityByID(parent->GetEntityID());
else
return nullptr;
}
EntityID SHEntity::GetParentEID()const noexcept
{
SHSceneNode* parent = SHSceneManager::GetCurrentSceneGraph().GetParent(GetEID());
if (parent != nullptr)
return parent->GetEntityID();
else
return MAX_EID;
} }
std::vector<SHEntity*>const& SHEntity::GetChildren()const noexcept std::vector<SHEntity*>const& SHEntity::GetChildren()const noexcept
{ {
//TODO std::vector<SHEntity*> childrenEntity;
return std::vector<SHEntity*>{};
auto& childrenNodes = SHSceneManager::GetCurrentSceneGraph().GetChildren(GetEID());
for (auto& childNode : childrenNodes)
{
childrenEntity.push_back(SHEntityManager::GetEntityByID(childNode->GetEntityID()));
}
return childrenEntity;
} }
std::vector<EntityID>const& SHEntity::GetChildrenID()const noexcept std::vector<EntityID>const& SHEntity::GetChildrenID()const noexcept
{ {
return std::vector<EntityID>{}; std::vector<EntityID> childrenEntity;
auto& childrenNodes = SHSceneManager::GetCurrentSceneGraph().GetChildren(GetEID());
for (auto& childNode : childrenNodes)
{
childrenEntity.push_back(childNode->GetEntityID());
}
return childrenEntity;
} }
} }

View File

@ -127,6 +127,13 @@ namespace SHADE
***************************************************************************/ ***************************************************************************/
SHEntity* GetParent()const noexcept; SHEntity* GetParent()const noexcept;
/********************************************************************
* \brief
* Get the entity ID of the parent.
* \return
* return the entity ID of the parent
********************************************************************/
EntityID GetParentEID() const noexcept;
/************************************************************************** /**************************************************************************
* \brief * \brief

View File

@ -0,0 +1,13 @@
#pragma once
#include "ECS_Base/Entity/SHEntity.h"
namespace SHADE
{
struct SHEntityCreationEvent
{
EntityID eid;
std::vector<ComponentTypeID> componentTypeIDs;
EntityID parentEID;
};
}

View File

@ -0,0 +1,11 @@
#pragma once
#include "ECS_Base/Entity/SHEntity.h"
namespace SHADE
{
struct SHEntityDestroyedEvent
{
EntityID eid;
};
}

View File

@ -103,6 +103,18 @@ namespace SHADE
SHComponentManager::AddComponent(eID, id); SHComponentManager::AddComponent(eID, id);
} }
//Link up with scene graph.
if (parentEID != MAX_EID)
SHSceneManager::GetCurrentSceneGraph().AddNode(eID, SHSceneManager::GetCurrentSceneGraph().GetNode(parentEID));
else
SHSceneManager::GetCurrentSceneGraph().AddNode(eID);
//set up event stuff
SHEntityCreationEvent event{ eID,componentTypeIDs, parentEID };
SHEventManager::BroadcastEvent<SHEntityCreationEvent>(event, SH_ENTITY_CREATION_EVENT);
//(SHComponentManager::AddComponent<ComponentTypes>(eID), ...); //(SHComponentManager::AddComponent<ComponentTypes>(eID), ...);
//if (entityHandle.IsValid(parentEID) == false) //if (entityHandle.IsValid(parentEID) == false)
@ -134,6 +146,14 @@ namespace SHADE
//Call all the children to Destroy themselves first before the parent is destroyed. //Call all the children to Destroy themselves first before the parent is destroyed.
if (entityVec[eIndex]) if (entityVec[eIndex])
{ {
auto& children = SHSceneManager::GetCurrentSceneGraph().GetChildren(eID);
for (auto& child : children)
{
DestroyEntity(child->GetEntityID());
}
SHSceneManager::GetCurrentSceneGraph().RemoveNode(eID);
//auto& children = entityVec[eIndex]->GetChildrenID(); //auto& children = entityVec[eIndex]->GetChildrenID();
//while(!children.empty()) //while(!children.empty())
//{ //{
@ -153,6 +173,14 @@ namespace SHADE
entityHandle.RemoveHandle(eID); entityHandle.RemoveHandle(eID);
entityVec[eIndex].reset(nullptr); entityVec[eIndex].reset(nullptr);
SHEntityDestroyedEvent event{eID};
SHEventManager::BroadcastEvent<SHEntityDestroyedEvent>(event, SH_ENTITY_DESTROYED_EVENT);
} }
} }

View File

@ -20,6 +20,10 @@
#include "../Components/SHComponent.h" #include "../Components/SHComponent.h"
#include "../General/SHHandleGenerator.h" #include "../General/SHHandleGenerator.h"
#include "../SHECSMacros.h" #include "../SHECSMacros.h"
#include "ECS_Base/Events/SHEntityCreationEvent.h"
#include "ECS_Base/Events/SHEntityDestroyedEvent.h"
#include "Scene/SHSceneManager.h"
#include "Events/SHEventManager.hpp"
#include "SH_API.h" #include "SH_API.h"
namespace SHADE namespace SHADE
@ -125,6 +129,23 @@ namespace SHADE
entityVec[eIndex]->name = name; entityVec[eIndex]->name = name;
(SHComponentManager::AddComponent<ComponentTypes>(eID), ...); (SHComponentManager::AddComponent<ComponentTypes>(eID), ...);
//set up event stuff
std::vector<ComponentTypeID> typeIDVec;
(typeIDVec.push_back(ComponentFamily::GetID<ComponentTypes>()), ...);
//Link up with scene graph.
if (parentEID != MAX_EID)
SHSceneManager::GetCurrentSceneGraph().AddNode(eID, SHSceneManager::GetCurrentSceneGraph().GetNode(parentEID));
else
SHSceneManager::GetCurrentSceneGraph().AddNode(eID);
SHEntityCreationEvent event{ eID,typeIDVec,parentEID };
SHEventManager::BroadcastEvent<SHEntityCreationEvent>(event, SH_ENTITY_CREATION_EVENT);
/*if (entityHandle.IsValid(parentEID) == false) /*if (entityHandle.IsValid(parentEID) == false)
{ {
entityVec[eIndex]->sceneNode.ConnectToRoot(); entityVec[eIndex]->sceneNode.ConnectToRoot();
@ -135,8 +156,6 @@ namespace SHADE
}*/ }*/
//Link up with scene graph.
return eID; return eID;
} }

View File

@ -41,7 +41,7 @@ namespace SHADE
std::string const GetName() const noexcept; std::string const GetName() const noexcept;
SHRoutineStats const& GetStats()const noexcept; SHRoutineStats const& GetStats()const noexcept;
virtual void Execute(double dt) noexcept {}; virtual void Execute(double dt) noexcept { (void)dt; };
}; };

View File

@ -30,9 +30,9 @@ namespace SHADE
SHLOG_INFO("Test for add and remove component") SHLOG_INFO("Test for add and remove component")
EntityID id1 = SHEntityManager::CreateEntity(); EntityID id1 = SHEntityManager::CreateEntity();
EntityID id2 = SHEntityManager::CreateEntity(); SHEntityManager::CreateEntity();
EntityID id3 = SHEntityManager::CreateEntity(); SHEntityManager::CreateEntity();
SHComponentManager::AddComponent<SHComponent_A>(id1); SHComponentManager::AddComponent<SHComponent_A>(id1);
} }

View File

@ -30,7 +30,7 @@ namespace SHADE
virtual void Execute(double dt) noexcept virtual void Execute(double dt) noexcept
{ {
(void)dt;
std::cout << GetName() << " System Version: " << GetSystem()->GetSystemVersion() << std::endl; std::cout << GetName() << " System Version: " << GetSystem()->GetSystemVersion() << std::endl;
} }
}; };

View File

@ -16,7 +16,17 @@ namespace SHADE
struct SHEvent struct SHEvent
{ {
SHEventIdentifier type; SHEventIdentifier type;
SHEventDataPtr dataPtr;
SHEventHandle handle; SHEventHandle handle;
}; };
template<typename T>
struct SHEventSpec : SHEvent
{
SHEventSpec(SHEventIdentifier t, SHEventHandle e, std::shared_ptr<const T> dp)
:SHEvent{ t, e }, data{ dp } {}
std::shared_ptr<const T> data;
};
using SHEventPtr = std::shared_ptr<const SHEvent>;
} }

View File

@ -3,7 +3,8 @@
typedef uint32_t SHEventIdentifier; typedef uint32_t SHEventIdentifier;
typedef uint32_t SHEventHandle; typedef uint32_t SHEventHandle;
typedef void* SHEventDataPtr;
//Add your event identifiers here: //Add your event identifiers here:
constexpr SHEventIdentifier SH_EXAMPLE_EVENT{0}; constexpr SHEventIdentifier SH_EXAMPLE_EVENT{0};
constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT{ 1 };
constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT{ 2 };

View File

@ -1,107 +0,0 @@
/******************************************************************************
* \file SHEventManager.cpp
* \author Loh Xiao Qi
* \brief Function Implmentations for SHEventManager
*
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
* or disclosure of this file or its contents without the prior
* written consent of Digipen Institute of Technology is prohibited
******************************************************************************/
#include "SHpch.h"
#include "SHEventManager.h"
namespace SHADE
{
std::unordered_map<SHEventIdentifier, ResponseVec> SHEventManager::packageReceiverRegistry;
std::unordered_map<SHEventHandle, SHEventDataPtr> SHEventManager::dataEventMap;
SHEventHandle SHEventManager::handleCounter{ 0 };
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Templated type for every type of event
* \brief Receives event from the listeners.
****************************************************************************/
void SHEventManager::CatchEvent(SHEvent event)
{
// Do something with the event
Broadcast(event);
}
/****************************************************************************
* \param ResponseFunction - function pointer from receiver to be passed
* into event manager to be called when events are broadcasted.
* \param SHEventIdentifier - package type that corresponding subscriber is
* subscribing to.
* \brief Links a function pointer from a subscriber to a particular
* package type
****************************************************************************/
void SHEventManager::SubscribeTo(SHEventIdentifier pkgType, ReceiverPtr receiver)
{
RegisterReceiverToType(pkgType, receiver);
}
template<typename T>
T* SHEventManager::BroadcastEvent(T data, SHEventIdentifier eventType)
{
SHEventDataPtr ptr = new std::byte[sizeof(data)];
std::memcpy(ptr, &data, sizeof(data));
CatchEvent(
{
eventType,
ptr,
handleCounter++
}
);
return reinterpret_cast<T*>(ptr);
}
/****************************************************************************
* \param ReceiverPtr - Pointer to receiver
* \param ListenerConstPtr - Const pointer to listener that receiver is
* subscribing to.
* \brief Registers receiver as a subscriber to listener in the registry.
****************************************************************************/
void SHEventManager::RegisterReceiverToType(
SHEventIdentifier pkgType, ReceiverPtr receiver)
{
if (packageReceiverRegistry.contains(pkgType))
{
packageReceiverRegistry[pkgType].emplace_back(receiver);
}
else
{
packageReceiverRegistry.emplace(pkgType, std::vector{ receiver });
}
}
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Event data
* \brief Broadcast event to all receivers that are subscribed to this
* listener.
****************************************************************************/
void SHEventManager::Broadcast(SHEvent const& event)
{
ResponseVec& receivers{ packageReceiverRegistry[event.type] };
for (auto& receiver : receivers)
{
receiver->Receive(event);
}
//auto& funcs{ ackageReceiverRegistry[event.GetType()] };
//for (auto func : funcs)
//{
// func(event.GetData());
//}
}
}

View File

@ -1,5 +1,5 @@
/****************************************************************************** /******************************************************************************
* \file SHEventManager.h * \file SHEventManager.hpp
* \author Loh Xiao Qi * \author Loh Xiao Qi
* \brief Class declaration for event manager. * \brief Class declaration for event manager.
* *
@ -9,10 +9,9 @@
******************************************************************************/ ******************************************************************************/
#pragma once #pragma once
#include "SHpch.h"
#include "SHEvent.h" #include "SHEvent.h"
#include "SHEventReceiver.h" #include "SHEventReceiver.h"
#include <unordered_map>
#include <functional>
/****************************************************************************** /******************************************************************************
INSTRUCTIONS FOR USE: INSTRUCTIONS FOR USE:
@ -24,11 +23,16 @@
3. When ready to send the event, call 3. When ready to send the event, call
SHEventManager::BroadcastEvent<ExampleClass>(exampleClass, EVENT_IDENTIFIER); SHEventManager::BroadcastEvent<ExampleClass>(exampleClass, EVENT_IDENTIFIER);
Headers required: SHEventManager.h NOTE: If your custom struct to contain data requires a deep copy, please
overload the assignment operator accordingly. It is fine to send
a single object of a basic type such as int/float.
Headers required: SHEventManager.hpp
On Receiver side: On Receiver side:
1. Create a function with the signature: 1. Create a function with the signature:
SHEventHandle FunctionName(SHEvent); SHEventHandle FunctionName(SHEventPtr);
2. In the init function of the class, copy the below in and replace the 2. In the init function of the class, copy the below in and replace the
necessary: necessary:
@ -42,25 +46,71 @@
3. Note: The EventIdentifier should match all that is defined in 3. Note: The EventIdentifier should match all that is defined in
SHEventDefines.h so check there. When the receiver catches the event, it SHEventDefines.h so check there. When the receiver catches the event, it
needs to know the struct that the broadcaster is using to cast the void* needs to know the struct that the broadcaster is using to cast the event
properly. ptr as such:
Headers required: SHEventManager.h, SHEventReceiver.h reinterpret_cast<std::shared_ptr<SHEventSpec<CustomClass>>>(event)
4. Inside the new ptr should be a shared pointer of const CustomClass type.
Headers required: SHEventManager.hpp, SHEventReceiver.h
If you have any questions/suggestions for improvement lmk. If you have any questions/suggestions for improvement lmk.
******************************************************************************/ ******************************************************************************/
namespace SHADE namespace SHADE
{ {
using ResponseFunction = std::function<SHEventHandle(SHEvent)>; //using ResponseFunction = std::function<SHEventHandle(SHEventPtr)>;
using ReceiverPtr = std::shared_ptr<SHEventReceiver>; using ReceiverPtr = std::shared_ptr<SHEventReceiver>;
using ResponseVec = std::vector<ReceiverPtr>; using ResponseVec = std::vector<ReceiverPtr>;
using StaticResponseVec = std::vector<ResponseFunction>;
using EventManagerListener = std::function<void(SHEvent)>; using EventManagerListener = std::function<void(SHEvent)>;
class SHEventManager class SHEventManager
{ {
private:
// Registry for broadcasters and subscribers
inline static std::unordered_map<SHEventIdentifier, ResponseVec> packageReceiverRegistry;
inline static SHEventHandle handleCounter {0};
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Event data
* \brief Broadcast event to all receivers that are subscribed to this
* listener.
****************************************************************************/
static void Broadcast(SHEventPtr event)
{
ResponseVec& receivers{ packageReceiverRegistry[event->type] };
for (auto& receiver : receivers)
{
receiver->Receive(event);
}
}
/****************************************************************************
* \param ReceiverPtr - Pointer to receiver
* \param ListenerConstPtr - Const pointer to listener that receiver is
* subscribing to.
* \brief Registers receiver as a subscriber to listener in the registry.
****************************************************************************/
static void RegisterReceiverToType(SHEventIdentifier pkgType, ReceiverPtr receiver)
{
if (packageReceiverRegistry.find(pkgType) == packageReceiverRegistry.end())
{
packageReceiverRegistry.emplace(pkgType, std::vector{ receiver });
}
else
{
packageReceiverRegistry[pkgType].emplace_back(receiver);
}
}
public: public:
/**************************************************************************** /****************************************************************************
@ -69,7 +119,13 @@ namespace SHADE
* \brief Receives event from the listeners. * \brief Receives event from the listeners.
****************************************************************************/ ****************************************************************************/
static void CatchEvent(SHEvent); static void CatchEvent(SHEventPtr event)
{
// Do something with the event
Broadcast(event);
}
/**************************************************************************** /****************************************************************************
* \param ResponseFunction - function pointer from receiver to be passed * \param ResponseFunction - function pointer from receiver to be passed
@ -80,37 +136,20 @@ namespace SHADE
* \brief Links a function pointer from a subscriber to a particular * \brief Links a function pointer from a subscriber to a particular
* package type * package type
****************************************************************************/ ****************************************************************************/
static void SubscribeTo(SHEventIdentifier, ReceiverPtr); static void SubscribeTo(SHEventIdentifier pkgType, ReceiverPtr receiver)
{
RegisterReceiverToType(pkgType, receiver);
}
template<typename T> template<typename T>
static T* BroadcastEvent(T data, SHEventIdentifier eventType); static void BroadcastEvent(T data, SHEventIdentifier eventType)
{
private: std::shared_ptr<const T> ptr = std::make_shared<T>(data);
// Registry for broadcasters and subscribers
static std::unordered_map<SHEventIdentifier, ResponseVec> packageReceiverRegistry;
static std::unordered_map<SHEventHandle, SHEventDataPtr> dataEventMap;
static SHEventHandle handleCounter;
/****************************************************************************
* \param ListenerConstPtr - Const pointer to listener that sent event.
* \param EventType - Event data
* \brief Broadcast event to all receivers that are subscribed to this
* listener.
****************************************************************************/
static void Broadcast(SHEvent const&);
/****************************************************************************
* \param ReceiverPtr - Pointer to receiver
* \param ListenerConstPtr - Const pointer to listener that receiver is
* subscribing to.
* \brief Registers receiver as a subscriber to listener in the registry.
****************************************************************************/
static void RegisterReceiverToType(SHEventIdentifier, ReceiverPtr);
CatchEvent(
std::make_shared<SHEventSpec<T>>(eventType, handleCounter++, ptr)
);
}
}; };
} }

View File

@ -8,7 +8,7 @@ namespace SHADE
{ {
private: private:
public: public:
virtual void Receive(SHEvent) = 0; virtual void Receive(SHEventPtr) = 0;
}; };
template<typename T> template<typename T>
@ -16,16 +16,16 @@ namespace SHADE
{ {
private: private:
T* object; T* object;
SHEventHandle(T::*callback)(SHEvent); SHEventHandle(T::*callback)(SHEventPtr);
public: public:
SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventDataPtr)) SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventPtr))
:SHEventReceiver(), object{ obj }, callback{ cb } :SHEventReceiver(), object{ obj }, callback{ cb }
{ {
} }
void Receive(SHEvent evt) override void Receive(SHEventPtr evt) override
{ {
(object->*callback)(evt); (object->*callback)(evt);
} }

View File

@ -8,6 +8,7 @@
#include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "Graphics/Framebuffer/SHVkFramebuffer.h"
#include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/Pipeline/SHVkPipeline.h"
#include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
namespace SHADE namespace SHADE
@ -353,6 +354,11 @@ namespace SHADE
} }
} }
void SHVkCommandBuffer::BindDescriptorSet(Handle<SHVkDescriptorSetGroup> descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets)
{
vkCommandBuffer.bindDescriptorSets (bindPoint, boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets);
}
/***************************************************************************/ /***************************************************************************/
/*! /*!

View File

@ -15,6 +15,7 @@ namespace SHADE
class SHVkFramebuffer; class SHVkFramebuffer;
class SHVkPipeline; class SHVkPipeline;
class SHVkBuffer; class SHVkBuffer;
class SHVkDescriptorSetGroup;
enum class SH_CMD_BUFFER_TYPE enum class SH_CMD_BUFFER_TYPE
{ {
@ -110,6 +111,7 @@ namespace SHADE
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept; void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;
void BindVertexBuffer (uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept; void BindVertexBuffer (uint32_t bindingPoint, Handle<SHVkBuffer> const& buffer, vk::DeviceSize offset) noexcept;
void BindIndexBuffer (Handle<SHVkBuffer> const& buffer, uint32_t startingIndex) const noexcept; void BindIndexBuffer (Handle<SHVkBuffer> const& buffer, uint32_t startingIndex) const noexcept;
void BindDescriptorSet (Handle<SHVkDescriptorSetGroup> descSetGroup, vk::PipelineBindPoint bindPoint, uint32_t firstSet, std::span<uint32_t> dynamicOffsets);
// Draw Commands // Draw Commands
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept; void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept;

View File

@ -46,12 +46,15 @@ namespace SHADE
//for (auto& layout : layouts) //for (auto& layout : layouts)
for (uint32_t i = 0; i < layouts.size(); ++i) for (uint32_t i = 0; i < layouts.size(); ++i)
{ {
vkLayouts.push_back(layouts[i]->GetVkHandle()); vkLayouts[i] = layouts[i]->GetVkHandle();
} }
// Check for variable descriptor count // Check for variable descriptor count
if (variableDescCounts.size() != layouts.size()) if (variableDescCounts.size() != layouts.size())
{
SHLOG_ERROR("Number of variable descriptor counts does not match number of layouts. If a layout does not use variable counts, pass in 0. "); SHLOG_ERROR("Number of variable descriptor counts does not match number of layouts. If a layout does not use variable counts, pass in 0. ");
return;
}
// Prepare variable descriptor counts // Prepare variable descriptor counts
vk::DescriptorSetVariableDescriptorCountAllocateInfo variableAllocInfo{}; vk::DescriptorSetVariableDescriptorCountAllocateInfo variableAllocInfo{};

View File

@ -56,10 +56,10 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Descriptor set writing */ /* Descriptor set writing */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void ModifyWriteDescImage (uint32_t set, uint32_t binding, std::vector<std::pair<vk::ImageView, vk::Sampler>> const& imageViewsAndSamplers) noexcept; void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::vector<std::pair<vk::ImageView, vk::Sampler>> const& imageViewsAndSamplers) noexcept;
void UpdateDescriptorSet (void) noexcept; void UpdateDescriptorSet(void) noexcept;
void UpdateSingleDescriptorSetImages (uint32_t set, uint32_t binding) noexcept; void UpdateSingleDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Getter Functions */ /* Getter Functions */
@ -70,6 +70,7 @@ namespace SHADE
/// <returns>Handle to the Vulkan Descriptor Set.</returns> /// <returns>Handle to the Vulkan Descriptor Set.</returns>
[[nodiscard]] [[nodiscard]]
inline const std::vector<vk::DescriptorSet>& GetVkHandle() { return descSets; } inline const std::vector<vk::DescriptorSet>& GetVkHandle() { return descSets; }
inline const uint32_t GetNumDescriptorSets(void) const noexcept { return static_cast<uint32_t>(descSets.size()); }
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */

View File

@ -208,21 +208,8 @@ namespace SHADE
InitializeVMA(); InitializeVMA();
// TODO: Create pipeline caches uboBufferMemoryAlignment = parentPhysicalDeviceHdl->GetDeviceProperties().limits.minUniformBufferOffsetAlignment;
// TODO: Create Descriptor pools ssboBufferMemoryAlignment = parentPhysicalDeviceHdl->GetDeviceProperties().limits.minStorageBufferOffsetAlignment;
//auto poolSizes = std::array
//{
// SHDescriptorPoolSize {SHDescriptorType::COMBINED_SAMPLER, 1000} // hard coded descriptor count
//};
//SHDescriptorPoolParams poolParams
//{
// .poolSizes = poolSizes,
// .maxDescriptorSets = 1000,
//};
//descriptorPool.Initialize(*this, poolParams);
//deviceStorage.Init(*this, queueFamilyIndices.indices[static_cast<uint32_t>(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS)].value());
} }
SHVkLogicalDevice::SHVkLogicalDevice(SHVkLogicalDevice&& rhs) noexcept SHVkLogicalDevice::SHVkLogicalDevice(SHVkLogicalDevice&& rhs) noexcept
@ -299,6 +286,17 @@ namespace SHADE
return VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM; return VkMemoryPropertyFlagBits::VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM;
} }
uint32_t SHVkLogicalDevice::PadUBOSize(uint32_t originalSize) const noexcept
{
uint32_t alignedSize = originalSize;
//uint32_t minBuffer
if (uboBufferMemoryAlignment > 0)
{
alignedSize = (alignedSize + uboBufferMemoryAlignment - 1) & ~(uboBufferMemoryAlignment - 1);
}
return alignedSize;
}
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -672,6 +670,11 @@ namespace SHADE
return static_cast<SHQueueFamilyIndex>(SH_Q_FAM::INVALID); return static_cast<SHQueueFamilyIndex>(SH_Q_FAM::INVALID);
} }
Handle<SHVkPhysicalDevice> SHVkLogicalDevice::GetParentPhysicalDevice(void) const noexcept
{
return parentPhysicalDeviceHdl;
}
//SHDescriptorPool const& SHLogicalDevice::GetDescriptorPool(void) const noexcept //SHDescriptorPool const& SHLogicalDevice::GetDescriptorPool(void) const noexcept
//{ //{
// return descriptorPool; // return descriptorPool;

View File

@ -69,7 +69,11 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */ /* PRIVATE MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
//vk::DeviceSize bufferMemoryAlignment{ 64 }; //! UBO alignment
vk::DeviceSize uboBufferMemoryAlignment;
//! SSBO alignment
vk::DeviceSize ssboBufferMemoryAlignment;
//! Vulkan handle //! Vulkan handle
vk::Device vkLogicalDevice; vk::Device vkLogicalDevice;
@ -113,9 +117,12 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER VARIABLES */ /* PUBLIC MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// Miscellaneous functions
void WaitIdle (void) noexcept; void WaitIdle (void) noexcept;
uint32_t FindMemoryType (uint32_t typeFilter, vk::MemoryPropertyFlags properties); uint32_t FindMemoryType (uint32_t typeFilter, vk::MemoryPropertyFlags properties);
uint32_t PadUBOSize (uint32_t originalSize) const noexcept;
// creation functions
Handle<SHVkSurface> CreateSurface (HWND const& windowHandle) const noexcept; Handle<SHVkSurface> CreateSurface (HWND const& windowHandle) const noexcept;
Handle<SHVkSwapchain> CreateSwapchain ( Handle<SHVkSwapchain> CreateSwapchain (
Handle<SHVkSurface> const& surfaceHdl, Handle<SHVkSurface> const& surfaceHdl,
@ -190,10 +197,12 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */ /* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
vk::Device const& GetVkLogicalDevice (void) const noexcept; vk::Device const& GetVkLogicalDevice (void) const noexcept;
Handle<SHVkQueue> const& GetQueue (SH_Q_FAM queueFamArrayIndex, uint8_t queueIndex) const; Handle<SHVkQueue> const& GetQueue (SH_Q_FAM queueFamArrayIndex, uint8_t queueIndex) const;
VmaAllocator const& GetVMAAllocator (void) noexcept; VmaAllocator const& GetVMAAllocator (void) noexcept;
SHQueueFamilyIndex GetQueueFamilyIndex (SH_Q_FAM family) const noexcept; SHQueueFamilyIndex GetQueueFamilyIndex (SH_Q_FAM family) const noexcept;
Handle<SHVkPhysicalDevice> GetParentPhysicalDevice (void) const noexcept;
//vk::DeviceSize GetBufferAlignment (void) const noexcept; //vk::DeviceSize GetBufferAlignment (void) const noexcept;
//SHDescriptorPool const& GetDescriptorPool(void) const noexcept; //SHDescriptorPool const& GetDescriptorPool(void) const noexcept;

View File

@ -27,6 +27,7 @@ namespace SHADE
queueFamilyProperties = vkPhysicalDevice.getQueueFamilyProperties(); queueFamilyProperties = vkPhysicalDevice.getQueueFamilyProperties();
deviceFeatures = vkPhysicalDevice.getFeatures2(); deviceFeatures = vkPhysicalDevice.getFeatures2();
} }
SHVkPhysicalDevice::SHVkPhysicalDevice(SHVkPhysicalDevice&& rhs) noexcept SHVkPhysicalDevice::SHVkPhysicalDevice(SHVkPhysicalDevice&& rhs) noexcept

View File

@ -167,7 +167,7 @@ namespace SHADE
debugWorldRenderer->SetCamera(worldCamera);*/ debugWorldRenderer->SetCamera(worldCamera);*/
// Add world renderer to default viewport // Add world renderer to default viewport
worldRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph); worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), descPool, globalData->GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
worldRenderer->SetCamera(worldCamera); worldRenderer->SetCamera(worldCamera);

View File

@ -18,16 +18,23 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Buffers/SHVkBuffer.h"
#include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "Graphics/Framebuffer/SHVkFramebuffer.h"
#include "SHMaterial.h" #include "SHMaterial.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Constructor/Destructors */ /* Constructor/Destructors */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHRenderer::SHRenderer(Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph) SHRenderer::SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph)
: viewport { viewport } : viewport { viewport }
, renderGraph { renderGraph } , renderGraph { renderGraph }
{} {
cameraDescriptorSet = logicalDevice->CreateDescriptorSetGroup(descriptorPool, { cameraDescLayout }, { 1 });
cpuCameraData.resize(numFrames);
cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData));
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Camera Registration */ /* Camera Registration */
@ -45,6 +52,13 @@ namespace SHADE
renderGraph->Execute(frameIndex, graphScopeBuffers); renderGraph->Execute(frameIndex, graphScopeBuffers);
} }
void SHRenderer::BindDescriptorSet(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
{
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
}
Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept
{ {
return renderGraph; return renderGraph;

View File

@ -19,6 +19,8 @@ of DigiPen Institute of Technology is prohibited.
#include "SHCamera.h" #include "SHCamera.h"
#include "Resource/Handle.h" #include "Resource/Handle.h"
#include "Graphics/RenderGraph/SHRenderGraph.h" #include "Graphics/RenderGraph/SHRenderGraph.h"
#include "Math/SHMath.h"
#include <vector>
namespace SHADE namespace SHADE
{ {
@ -36,6 +38,13 @@ namespace SHADE
class SHCamera; class SHCamera;
class SHVkDescriptorSetGroup; class SHVkDescriptorSetGroup;
class SHGraphicsGlobalData; class SHGraphicsGlobalData;
class SHVkDescriptorPool;
struct SHShaderCameraData
{
SHVec4 cameraPosition;
SHMatrix viewProjectionMatrix;
};
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -54,7 +63,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructor/Destructors */ /* Constructor/Destructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
SHRenderer(Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph); SHRenderer(Handle<SHVkLogicalDevice> logicalDevice, uint32_t numFrames, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHViewport> viewport, Handle<SHRenderGraph> renderGraph);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Camera Registration */ /* Camera Registration */
@ -65,6 +74,7 @@ namespace SHADE
/* Drawing Functions */ /* Drawing Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void Draw(uint32_t frameIndex, std::initializer_list<std::pair<Handle<SHVkBuffer>, uint32_t>> graphScopeBuffers) noexcept; void Draw(uint32_t frameIndex, std::initializer_list<std::pair<Handle<SHVkBuffer>, uint32_t>> graphScopeBuffers) noexcept;
void BindDescriptorSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Setters and Getters */ /* Setters and Getters */
@ -75,8 +85,14 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHViewport> viewport; //! Vulkan UBOs need to be aligned, this is pad SHShaderCameraData struct
Handle<SHCamera> camera; uint32_t cameraDataAlignedSize;
Handle<SHRenderGraph> renderGraph;
Handle<SHViewport> viewport;
Handle<SHCamera> camera;
Handle<SHRenderGraph> renderGraph;
Handle<SHVkDescriptorSetGroup> cameraDescriptorSet;
std::vector<SHShaderCameraData> cpuCameraData;
}; };
} }

View File

@ -49,10 +49,10 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Renderer Registration Functions */ /* Renderer Registration Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Handle<SHRenderer> SHViewport::AddRenderer(ResourceManager& resourceManager, Handle<SHRenderGraph> renderGraph) Handle<SHRenderer> SHViewport::AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph)
{ {
// Create the renderer // Create the renderer
auto renderer = resourceManager.Create<SHRenderer>(GetHandle(), renderGraph); auto renderer = resourceManager.Create<SHRenderer>(device, numFrames, descriptorPool, cameraDescLayout, GetHandle(), renderGraph);
// Store // Store
renderers.emplace_back(renderer); renderers.emplace_back(renderer);

View File

@ -30,6 +30,8 @@ namespace SHADE
class SHVkImageView; class SHVkImageView;
class ResourceManager; class ResourceManager;
class SHRenderGraph; class SHRenderGraph;
class SHVkDescriptorPool;
class SHVkDescriptorSetLayout;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -56,7 +58,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Renderers Registration Functions */ /* Renderers Registration Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHRenderer> AddRenderer(ResourceManager& resourceManager, Handle<SHRenderGraph> renderGraph); Handle<SHRenderer> AddRenderer(ResourceManager& resourceManager, uint32_t numFrames, Handle<SHVkDescriptorPool> descriptorPool, Handle<SHVkDescriptorSetLayout> cameraDescLayout, Handle<SHRenderGraph> renderGraph);
void RemoveRenderer(Handle<SHRenderer> renderer); void RemoveRenderer(Handle<SHRenderer> renderer);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -31,5 +31,6 @@
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
#include <cstddef> #include <cstddef>
#include <span>
#include "Common/SHCommonTypes.h" #include "Common/SHCommonTypes.h"

View File

@ -12,6 +12,7 @@
#define SH_SCENE_H #define SH_SCENE_H
#include <string> #include <string>
#include "SHSceneGraph.h"
namespace SHADE namespace SHADE
{ {
@ -19,15 +20,19 @@ namespace SHADE
class SHScene class SHScene
{ {
private: private:
SHSceneGraph sceneGraph;
protected: protected:
SHScene() = default; SHScene() = default;
public: public:
virtual ~SHScene() = default;
std::string sceneName; std::string sceneName;
virtual ~SHScene() = default; SHSceneGraph& GetSceneGraph() noexcept { return sceneGraph; }
virtual void Load() = 0; virtual void Load() = 0;
virtual void Init() = 0; virtual void Init() = 0;

View File

@ -8,7 +8,7 @@
* of DigiPen Institute of Technology is prohibited. * of DigiPen Institute of Technology is prohibited.
****************************************************************************************/ ****************************************************************************************/
#include <SHpch.h> #include "SHpch.h"
// Primary Header // Primary Header
#include "SHSceneGraph.h" #include "SHSceneGraph.h"
@ -76,7 +76,10 @@ namespace SHADE
SHSceneGraph::SHSceneGraph() noexcept SHSceneGraph::SHSceneGraph() noexcept
: root { nullptr } : root { nullptr }
{} {
// The root is set to the maximum entity. It should not be interfaced with.
root = AllocateNode(MAX_EID);
}
SHSceneGraph::~SHSceneGraph() noexcept SHSceneGraph::~SHSceneGraph() noexcept
{ {
@ -90,6 +93,8 @@ namespace SHADE
for (auto* node : entityNodeMap | std::views::values) for (auto* node : entityNodeMap | std::views::values)
ReleaseNode(node); ReleaseNode(node);
delete root;
#ifdef _DEBUG #ifdef _DEBUG
SHLOG_INFO("Scene Graph Destroyed Successfully!") SHLOG_INFO("Scene Graph Destroyed Successfully!")
#endif #endif
@ -99,23 +104,38 @@ namespace SHADE
/* Getter Function Definitions */ /* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
EntityID SHSceneNode::GetEntityID() const noexcept
{
return entityID;
}
SHSceneNode* SHSceneNode::GetParent() const noexcept
{
return parent;
}
const std::vector<SHSceneNode*>& SHSceneNode::GetChildren() const noexcept
{
return children;
}
SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept
{ {
////////////////////////////////////////
// Error handling // Error handling
if (!SHEntityManager::IsValidEID(childID))
{ {
if (!SHEntityManager::IsValidEID(childID)) SHLOG_ERROR("Child Entity {} is invalid! Unable to get child from Entity {}", childID, entityID)
{ return nullptr;
SHLOG_ERROR("Child Entity {} is invalid! Unable to get child from Entity {}", childID, entityID)
return nullptr;
}
if (children.empty())
{
SHLOG_WARNING("Entity {} has no children!", entityID)
return nullptr;
}
} }
if (children.empty())
{
SHLOG_WARNING("Entity {} has no children!", entityID)
return nullptr;
}
////////////////////////////////////////
// Find child // Find child
const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; }; const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; };
@ -129,17 +149,19 @@ namespace SHADE
return *CHILD_ITER; return *CHILD_ITER;
} }
SHSceneNode* SHSceneGraph::GetRoot() const noexcept const SHSceneNode* SHSceneGraph::GetRoot() const noexcept
{ {
if (root != nullptr) if (root != nullptr)
return root; return root;
SHLOG_WARNING("Scene has no root object!") SHLOG_WARNING("Scene has no root object!")
return nullptr; return nullptr;
} }
SHSceneNode* SHSceneGraph::GetNode(EntityID entityID) const noexcept SHSceneNode* SHSceneGraph::GetNode(EntityID entityID) const noexcept
{ {
////////////////////////////////////////
// Error handling
if (!SHEntityManager::IsValidEID(entityID)) if (!SHEntityManager::IsValidEID(entityID))
{ {
SHLOG_ERROR("Entity {} is invalid! Unable to Get Scene node!", entityID) SHLOG_ERROR("Entity {} is invalid! Unable to Get Scene node!", entityID)
@ -152,12 +174,15 @@ namespace SHADE
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to Get Scene node!", entityID) SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to Get Scene node!", entityID)
return nullptr; return nullptr;
} }
////////////////////////////////////////
return NODE_ITER->second; return NODE_ITER->second;
} }
SHSceneNode* SHSceneGraph::GetParent(EntityID entityID) const noexcept SHSceneNode* SHSceneGraph::GetParent(EntityID entityID) const noexcept
{ {
////////////////////////////////////////
// Error handling
if (!SHEntityManager::IsValidEID(entityID)) if (!SHEntityManager::IsValidEID(entityID))
{ {
SHLOG_ERROR("Entity {} is invalid! Unable to get Parent node!", entityID) SHLOG_ERROR("Entity {} is invalid! Unable to get Parent node!", entityID)
@ -170,13 +195,15 @@ namespace SHADE
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to get Parent node!", entityID) SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to get Parent node!", entityID)
return nullptr; return nullptr;
} }
////////////////////////////////////////
return NODE_ITER->second->GetParent(); return NODE_ITER->second->GetParent();
} }
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, SHSceneNode* childNode) const noexcept SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, SHSceneNode* childNode) const noexcept
{ {
// Error Handling ////////////////////////////////////////
// Error handling
if (!SHEntityManager::IsValidEID(entityID)) if (!SHEntityManager::IsValidEID(entityID))
{ {
SHLOG_ERROR("Entity {} is invalid!", entityID) SHLOG_ERROR("Entity {} is invalid!", entityID)
@ -203,12 +230,15 @@ namespace SHADE
SHLOG_WARNING("Entity {} is not a child of Entity {}!", childNode->GetEntityID(), entityID) SHLOG_WARNING("Entity {} is not a child of Entity {}!", childNode->GetEntityID(), entityID)
return nullptr; return nullptr;
} }
////////////////////////////////////////
return *CHILD_ITER; return *CHILD_ITER;
} }
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, EntityID childEntityID) const noexcept SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, EntityID childEntityID) const noexcept
{ {
////////////////////////////////////////
// Error handling
if (!SHEntityManager::IsValidEID(entityID)) if (!SHEntityManager::IsValidEID(entityID))
{ {
SHLOG_ERROR("Entity {} is invalid!", entityID) SHLOG_ERROR("Entity {} is invalid!", entityID)
@ -221,14 +251,15 @@ namespace SHADE
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID) SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
return nullptr; return nullptr;
} }
////////////////////////////////////////
return NODE_ITER->second->GetChild(childEntityID); return NODE_ITER->second->GetChild(childEntityID);
} }
const std::vector<SHSceneNode*>& SHSceneGraph::GetChildren(EntityID entityID) const noexcept const std::vector<SHSceneNode*>& SHSceneGraph::GetChildren(EntityID entityID) const noexcept
{ {
// TODO(Diren): Discuss with team best way to handle this ////////////////////////////////////////
// Error handling
if (!SHEntityManager::IsValidEID(entityID)) if (!SHEntityManager::IsValidEID(entityID))
{ {
SHLOG_ERROR("Entity {} is invalid!", entityID) SHLOG_ERROR("Entity {} is invalid!", entityID)
@ -241,6 +272,7 @@ namespace SHADE
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID) SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
return root->GetChildren(); return root->GetChildren();
} }
////////////////////////////////////////
return NODE_ITER->second->GetChildren(); return NODE_ITER->second->GetChildren();
} }
@ -252,11 +284,17 @@ namespace SHADE
void SHSceneNode::SetParent(SHSceneNode* parentNode) noexcept void SHSceneNode::SetParent(SHSceneNode* parentNode) noexcept
{ {
if (parentNode == nullptr) if (parentNode == nullptr)
{
SHLOG_WARNING("Removing Entity {}'s parent", entityID) SHLOG_WARNING("Removing Entity {}'s parent", entityID)
}
// Handle self assignment
if (parentNode == parent) if (parentNode == parent)
return; return;
if (parent)
parent->RemoveChild(this);
parent = parentNode; parent = parentNode;
// Update parent's children // Update parent's children
parent->AddChild(this); parent->AddChild(this);
@ -264,6 +302,8 @@ namespace SHADE
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept
{ {
////////////////////////////////////////
// Error Handling
if (!SHEntityManager::IsValidEID(entityID)) if (!SHEntityManager::IsValidEID(entityID))
{ {
SHLOG_ERROR("Entity {} is invalid!", entityID) SHLOG_ERROR("Entity {} is invalid!", entityID)
@ -276,12 +316,15 @@ namespace SHADE
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID) SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
return; return;
} }
////////////////////////////////////////
NODE_ITER->second->SetParent(parent); NODE_ITER->second->SetParent(parent);
} }
void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept
{ {
////////////////////////////////////////
// Error Handling
if (!SHEntityManager::IsValidEID(entityID)) if (!SHEntityManager::IsValidEID(entityID))
{ {
SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID) SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID)
@ -301,12 +344,13 @@ namespace SHADE
return; return;
} }
auto PARENT_ITER = entityNodeMap.find(entityID); auto PARENT_ITER = entityNodeMap.find(parent);
if (PARENT_ITER == entityNodeMap.end()) if (PARENT_ITER == entityNodeMap.end())
{ {
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID) SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID)
return; return;
} }
////////////////////////////////////////
SHSceneNode* currentNode = NODE_ITER->second; SHSceneNode* currentNode = NODE_ITER->second;
currentNode->SetParent(PARENT_ITER->second); currentNode->SetParent(PARENT_ITER->second);
@ -318,50 +362,69 @@ namespace SHADE
void SHSceneNode::AddChild(SHSceneNode* newChild) noexcept void SHSceneNode::AddChild(SHSceneNode* newChild) noexcept
{ {
////////////////////////////////////////
// Error Handling
if (newChild == nullptr) if (newChild == nullptr)
{ {
SHLOG_WARNING("Attempting to add a non-existent child to an entity!") SHLOG_WARNING("Attempting to add a non-existent child to an entity!")
return; return;
} }
////////////////////////////////////////
if (newChild->parent)
newChild->parent->RemoveChild(newChild);
newChild->parent = this;
children.emplace_back(newChild); children.emplace_back(newChild);
} }
bool SHSceneNode::RemoveChild(EntityID childID) noexcept bool SHSceneNode::RemoveChild(EntityID childID) noexcept
{ {
////////////////////////////////////////
// Error Handling
if (!SHEntityManager::IsValidEID(childID)) if (!SHEntityManager::IsValidEID(childID))
{ {
SHLOG_ERROR("Entity {} is invalid!", childID) SHLOG_ERROR("Entity {} is invalid!", childID)
return false; return false;
} }
////////////////////////////////////////
SHSceneNode* removedChild = nullptr; auto childIter = std::find_if(children.begin(), children.end(), [&](SHSceneNode* node)
const auto ENTITY_MATCH = [&](SHSceneNode* node)
{ {
if (node->GetEntityID() == childID) return node->GetEntityID() == childID;
{ });
removedChild = node;
return true;
}
if (childIter == children.end())
{
SHLOG_WARNING("Unable to remove Entity {} from Entity {} since it is not it's child!", childID, entityID)
return false; return false;
}; }
children.end() = std::remove_if(children.begin(), children.end(), ENTITY_MATCH); (*childIter)->parent = nullptr;
removedChild->parent = nullptr; childIter = children.erase(childIter);
return removedChild == nullptr; return true;
} }
bool SHSceneNode::RemoveChild(SHSceneNode* childToRemove) noexcept bool SHSceneNode::RemoveChild(SHSceneNode* childToRemove) noexcept
{ {
////////////////////////////////////////
// Error Handling
if (childToRemove == nullptr) if (childToRemove == nullptr)
{ {
SHLOG_WARNING("Attempting to remove non-existent child from Entity {}", entityID) SHLOG_WARNING("Attempting to remove non-existent child from Entity {}", entityID)
return false; return false;
} }
////////////////////////////////////////
children.end() = std::remove(children.begin(), children.end(), childToRemove); auto childIter = std::find(children.begin(), children.end(), childToRemove);
if (childIter == children.end())
{
SHLOG_WARNING("Unable to remove Entity {} from Entity {} since it is not it's child!", childToRemove->entityID, entityID)
return false;
}
childIter = children.erase(childIter);
childToRemove->parent = nullptr; childToRemove->parent = nullptr;
return true; return true;
@ -375,22 +438,28 @@ namespace SHADE
children.clear(); children.clear();
} }
SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent) SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent)
{ {
////////////////////////////////////////
// Error Handling
if (!SHEntityManager::IsValidEID(entityID)) if (!SHEntityManager::IsValidEID(entityID))
{ {
SHLOG_ERROR("Entity {} is invalid!", entityID) SHLOG_ERROR("Entity {} is invalid!", entityID)
return nullptr; return nullptr;
} }
////////////////////////////////////////
if (auto NODE_ITER = entityNodeMap.find(entityID); NODE_ITER != entityNodeMap.end()) if (auto NODE_ITER = entityNodeMap.find(entityID); NODE_ITER != entityNodeMap.end())
{ {
SHLOG_WARNING("Entity {} already exists in the scene!", entityID) SHLOG_WARNING("Entity {} already exists in the scene!", entityID)
return NODE_ITER->second; return NODE_ITER->second;
} }
SHSceneNode* newNode = AllocateNode(entityID); SHSceneNode* newNode = AllocateNode(entityID);
if (parent == nullptr)
parent = root;
newNode->SetParent(parent); newNode->SetParent(parent);
return newNode; return newNode;

View File

@ -14,6 +14,7 @@
// Project Headers // Project Headers
#include "ECS_Base/Entity/SHEntity.h" #include "ECS_Base/Entity/SHEntity.h"
#include "SH_API.h"
namespace SHADE namespace SHADE
{ {
@ -21,7 +22,7 @@ namespace SHADE
/* Type Definitions */ /* Type Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
class SHSceneNode class SH_API SHSceneNode
{ {
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -34,40 +35,40 @@ namespace SHADE
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
~SHSceneNode () = default; ~SHSceneNode () = default;
SHSceneNode (EntityID eid, SHSceneNode* parent = nullptr) noexcept; SHSceneNode (EntityID eid, SHSceneNode* parent = nullptr) noexcept;
SHSceneNode (const SHSceneNode& rhs) noexcept; SHSceneNode (const SHSceneNode& rhs) noexcept;
SHSceneNode (SHSceneNode&& rhs) noexcept; SHSceneNode (SHSceneNode&& rhs) noexcept;
SHSceneNode& operator= (const SHSceneNode& rhs) noexcept; SHSceneNode& operator= (const SHSceneNode& rhs) noexcept;
SHSceneNode& operator= (SHSceneNode&& rhs) noexcept; SHSceneNode& operator= (SHSceneNode&& rhs) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] EntityID GetEntityID () const noexcept { return entityID ;} [[nodiscard]] EntityID GetEntityID () const noexcept;
[[nodiscard]] SHSceneNode* GetParent () const noexcept { return parent; } [[nodiscard]] SHSceneNode* GetParent () const noexcept;
[[nodiscard]] std::vector<SHSceneNode*>& GetChildren () noexcept { return children; } [[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept; [[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Setter Functions */ /* Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SetParent (SHSceneNode* parentNode) noexcept; void SetParent (SHSceneNode* parentNode) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void AddChild (SHSceneNode* newChild) noexcept; void AddChild (SHSceneNode* newChild) noexcept;
bool RemoveChild (EntityID childID) noexcept; bool RemoveChild (EntityID childID) noexcept;
bool RemoveChild (SHSceneNode* childToRemove) noexcept; bool RemoveChild (SHSceneNode* childToRemove) noexcept;
void RemoveAllChildren () noexcept; void RemoveAllChildren () noexcept;
private: private:
EntityID entityID; EntityID entityID;
@ -75,7 +76,7 @@ namespace SHADE
std::vector<SHSceneNode*> children; std::vector<SHSceneNode*> children;
}; };
class SHSceneGraph class SH_API SHSceneGraph
{ {
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -88,19 +89,19 @@ namespace SHADE
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHSceneGraph () noexcept; SHSceneGraph () noexcept;
~SHSceneGraph () noexcept; ~SHSceneGraph () noexcept;
SHSceneGraph (const SHSceneGraph&) = delete; SHSceneGraph (const SHSceneGraph&) = delete;
SHSceneGraph (SHSceneGraph&&) = delete; SHSceneGraph (SHSceneGraph&&) = delete;
SHSceneGraph& operator= (const SHSceneGraph&) = delete; SHSceneGraph& operator= (const SHSceneGraph&) = delete;
SHSceneGraph& operator= (SHSceneGraph&&) = delete; SHSceneGraph& operator= (SHSceneGraph&&) = delete;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] SHSceneNode* GetRoot () const noexcept; [[nodiscard]] const SHSceneNode* GetRoot () const noexcept;
[[nodiscard]] SHSceneNode* GetNode (EntityID entityID) const noexcept; [[nodiscard]] SHSceneNode* GetNode (EntityID entityID) const noexcept;
[[nodiscard]] SHSceneNode* GetParent (EntityID entityID) const noexcept; [[nodiscard]] SHSceneNode* GetParent (EntityID entityID) const noexcept;
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, SHSceneNode* childNode) const noexcept; [[nodiscard]] SHSceneNode* GetChild (EntityID entityID, SHSceneNode* childNode) const noexcept;
@ -111,17 +112,17 @@ namespace SHADE
/* Setter Functions */ /* Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SetParent (EntityID entityID, SHSceneNode* parent) const noexcept; void SetParent (EntityID entityID, SHSceneNode* parent) const noexcept;
void SetParent (EntityID entityID, EntityID parent) const noexcept; void SetParent (EntityID entityID, EntityID parent) const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr); SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr);
bool RemoveNode (EntityID entityID) noexcept; bool RemoveNode (EntityID entityID) noexcept;
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept; bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
void Reset () noexcept; void Reset () noexcept;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -136,7 +137,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHSceneNode* AllocateNode (EntityID entityID); SHSceneNode* AllocateNode (EntityID entityID);
void ReleaseNode (SHSceneNode* node) noexcept; void ReleaseNode (SHSceneNode* node) noexcept;
}; };

View File

@ -37,6 +37,12 @@ namespace SHADE
std::function<void()> SHSceneManager::newScene = []() {}; std::function<void()> SHSceneManager::newScene = []() {};
//void (*SHSceneManager::prevSceneCreate)() = []() {}; //void (*SHSceneManager::prevSceneCreate)() = []() {};
SHSceneGraph& SHSceneManager::GetCurrentSceneGraph() noexcept
{
return currentScene->GetSceneGraph();
}
void SHSceneManager::UpdateSceneManager() noexcept void SHSceneManager::UpdateSceneManager() noexcept
{ {
if (sceneChanged == false) if (sceneChanged == false)

View File

@ -16,11 +16,12 @@
#include "ECS_Base/General/SHFamily.h" #include "ECS_Base/General/SHFamily.h"
#include "SHScene.h" #include "SHScene.h"
#include <functional> #include <functional>
#include "SH_API.h"
namespace SHADE namespace SHADE
{ {
class SHSceneManager class SH_API SHSceneManager
{ {
private: private:
//boolean to check if the scene has been changed //boolean to check if the scene has been changed
@ -57,6 +58,15 @@ namespace SHADE
//boolean to check if the programme has been terminated. //boolean to check if the programme has been terminated.
static bool quit; static bool quit;
/********************************************************************
* \brief
* Get the scene graph of the current scene.
* \return
* A reference to the scene graph of the current active scene.
********************************************************************/
static SHSceneGraph& GetCurrentSceneGraph() noexcept;
/*!************************************************************************* /*!*************************************************************************
* \brief * \brief
* Initialize scene manager and loads a default scene * Initialize scene manager and loads a default scene

View File

@ -1,2 +1,5 @@
erase /s /q *.vcxproj
erase /s /q *.vcxproj.filters
call Premake\premake5 vs2019 call Premake\premake5 vs2019
PAUSE PAUSE