Merge branch 'main' into SP3-6-c-scripting

# Conflicts:
#	SHADE_Engine/SHADE_Engine.vcxproj
#	SHADE_Engine/SHADE_Engine.vcxproj.filters
#	SHADE_Engine/premake5.lua
This commit is contained in:
Kah Wei 2022-09-13 13:56:39 +08:00
commit 04cae0fad9
29 changed files with 910 additions and 79 deletions

View File

@ -71,7 +71,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>vulkan-1.lib;shlwapi.lib;assimp-vc142-mtd.lib;ktxd.lib;librttr_core_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>vulkan-1.lib;shaderc_shared.lib;shlwapi.lib;assimp-vc142-mtd.lib;ktxd.lib;librttr_core_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>libs;$(VULKAN_SDK)\Lib;..\Dependencies\assimp\lib\Debug;..\Dependencies\assimp\lib\Release;..\Dependencies\RTTR\lib;..\Dependencies\ktx\lib\Debug;..\Dependencies\ktx\lib\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ImportLibrary>bin\Debug_x86_64\SHADE_Engine\SHADE_Engine.lib</ImportLibrary>
</Link>
@ -99,7 +99,7 @@
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>vulkan-1.lib;shlwapi.lib;assimp-vc142-mt.lib;ktx.lib;librttr_core.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>vulkan-1.lib;shaderc_shared.lib;shlwapi.lib;assimp-vc142-mt.lib;ktx.lib;librttr_core.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>libs;$(VULKAN_SDK)\Lib;..\Dependencies\assimp\lib\Debug;..\Dependencies\assimp\lib\Release;..\Dependencies\RTTR\lib;..\Dependencies\ktx\lib\Debug;..\Dependencies\ktx\lib\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ImportLibrary>bin\Release_x86_64\SHADE_Engine\SHADE_Engine.lib</ImportLibrary>
</Link>
@ -108,20 +108,21 @@
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="src\Engine\ECS_Base\Components\SHComponent.h" />
<ClInclude Include="src\Engine\ECS_Base\Components\SHComponentGroup.h" />
<ClInclude Include="src\Engine\ECS_Base\Entity\SHEntity.h" />
<ClInclude Include="src\Engine\ECS_Base\General\SHFamily.h" />
<ClInclude Include="src\Engine\ECS_Base\General\SHHandleGenerator.h" />
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseBase.h" />
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseSet.h" />
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseSetContainer.h" />
<ClInclude Include="src\Engine\ECS_Base\SHECSMacros.h" />
<ClInclude Include="src\Engine\ECS_Base\System\SHComponentManager.h" />
<ClInclude Include="src\Engine\ECS_Base\System\SHEntityManager.h" />
<ClInclude Include="src\Engine\ECS_Base\System\SHSystem.h" />
<ClInclude Include="src\Engine\ECS_Base\System\SHSystemManager.h" />
<ClInclude Include="src\ECS_Base\Components\SHComponent.h" />
<ClInclude Include="src\ECS_Base\Components\SHComponentGroup.h" />
<ClInclude Include="src\ECS_Base\Entity\SHEntity.h" />
<ClInclude Include="src\ECS_Base\General\SHFamily.h" />
<ClInclude Include="src\ECS_Base\General\SHHandleGenerator.h" />
<ClInclude Include="src\ECS_Base\General\SHSparseBase.h" />
<ClInclude Include="src\ECS_Base\General\SHSparseSet.h" />
<ClInclude Include="src\ECS_Base\General\SHSparseSetContainer.h" />
<ClInclude Include="src\ECS_Base\SHECSMacros.h" />
<ClInclude Include="src\ECS_Base\System\SHComponentManager.h" />
<ClInclude Include="src\ECS_Base\System\SHEntityManager.h" />
<ClInclude Include="src\ECS_Base\System\SHSystem.h" />
<ClInclude Include="src\ECS_Base\System\SHSystemManager.h" />
<ClInclude Include="src\Engine\SHEngine.h" />
<ClInclude Include="src\Filesystem\SHFileSystem.h" />
<ClInclude Include="src\Graphics\Buffers\SHVkBuffer.h" />
<ClInclude Include="src\Graphics\Commands\SHCommandPoolResetMode.h" />
<ClInclude Include="src\Graphics\Commands\SHVkCommandBuffer.h" />
@ -194,6 +195,7 @@
<ClInclude Include="src\Resource\SparseSet.hpp" />
<ClInclude Include="src\SHpch.h" />
<ClInclude Include="src\Scene\SHScene.h" />
<ClInclude Include="src\Scene\SHSceneGraph.h" />
<ClInclude Include="src\Scene\SHSceneManager.h" />
<ClInclude Include="src\Scripting\SHDotNetRuntime.h" />
<ClInclude Include="src\Scripting\SHDotNetRuntime.hpp" />
@ -207,13 +209,14 @@
<ClInclude Include="src\Tools\SHUtilities.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Engine\ECS_Base\Components\SHComponent.cpp" />
<ClCompile Include="src\Engine\ECS_Base\Components\SHComponentGroup.cpp" />
<ClCompile Include="src\Engine\ECS_Base\Entity\SHEntity.cpp" />
<ClCompile Include="src\Engine\ECS_Base\System\SHComponentManager.cpp" />
<ClCompile Include="src\Engine\ECS_Base\System\SHEntityManager.cpp" />
<ClCompile Include="src\Engine\ECS_Base\System\SHSystemManager.cpp" />
<ClCompile Include="src\ECS_Base\Components\SHComponent.cpp" />
<ClCompile Include="src\ECS_Base\Components\SHComponentGroup.cpp" />
<ClCompile Include="src\ECS_Base\Entity\SHEntity.cpp" />
<ClCompile Include="src\ECS_Base\System\SHComponentManager.cpp" />
<ClCompile Include="src\ECS_Base\System\SHEntityManager.cpp" />
<ClCompile Include="src\ECS_Base\System\SHSystemManager.cpp" />
<ClCompile Include="src\Engine\SHEngine.cpp" />
<ClCompile Include="src\Filesystem\SHFileSystem.cpp" />
<ClCompile Include="src\Graphics\Buffers\SHVkBuffer.cpp" />
<ClCompile Include="src\Graphics\Commands\SHVkCommandBuffer.cpp" />
<ClCompile Include="src\Graphics\Commands\SHVkCommandPool.cpp" />
@ -270,6 +273,7 @@
<ClCompile Include="src\SHpch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="src\Scene\SHSceneGraph.cpp" />
<ClCompile Include="src\Scene\SHSceneManager.cpp" />
<ClCompile Include="src\Scripting\SHDotNetRuntime.cpp" />
<ClCompile Include="src\Scripting\SHScriptEngine.cpp" />

View File

@ -1,23 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="ECS_Base">
<UniqueIdentifier>{1AB26817-067F-C322-2F98-B1CA1BC4F8B0}</UniqueIdentifier>
</Filter>
<Filter Include="ECS_Base\Components">
<UniqueIdentifier>{EFD23933-5B34-1741-E4A1-5DF350024E00}</UniqueIdentifier>
</Filter>
<Filter Include="ECS_Base\Entity">
<UniqueIdentifier>{261D0942-92A8-7606-9BB9-F9FA07C4D206}</UniqueIdentifier>
</Filter>
<Filter Include="ECS_Base\General">
<UniqueIdentifier>{07FEB307-F3F6-D259-1C29-B8DE0881B265}</UniqueIdentifier>
</Filter>
<Filter Include="ECS_Base\System">
<UniqueIdentifier>{EE037863-5A8F-E527-63A0-681CCFAA4128}</UniqueIdentifier>
</Filter>
<Filter Include="Engine">
<UniqueIdentifier>{DBC7D3B0-C769-FE86-B024-12DB9C6585D7}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\ECS_Base">
<UniqueIdentifier>{7FF59BF8-EB80-09BD-F491-8CB1609C65BD}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\ECS_Base\Components">
<UniqueIdentifier>{340D0110-201D-ADE0-89D6-11FF75059C79}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\ECS_Base\Entity">
<UniqueIdentifier>{EBFC8BDC-D7F6-B42E-C063-4B3FACFC1A9B}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\ECS_Base\General">
<UniqueIdentifier>{6CD692F2-D80D-DB89-E117-3FAD4DCE0183}</UniqueIdentifier>
</Filter>
<Filter Include="Engine\ECS_Base\System">
<UniqueIdentifier>{B3E3FAFD-9FDD-2350-884A-BA6074E389BC}</UniqueIdentifier>
<Filter Include="Filesystem">
<UniqueIdentifier>{8A8E2B37-7646-6D84-DF4D-46E0CB240875}</UniqueIdentifier>
</Filter>
<Filter Include="Graphics">
<UniqueIdentifier>{1653CE33-0220-293F-2B39-17E717655ECD}</UniqueIdentifier>
@ -117,48 +120,51 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Engine\ECS_Base\Components\SHComponent.h">
<Filter>Engine\ECS_Base\Components</Filter>
<ClInclude Include="src\ECS_Base\Components\SHComponent.h">
<Filter>ECS_Base\Components</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\Components\SHComponentGroup.h">
<Filter>Engine\ECS_Base\Components</Filter>
<ClInclude Include="src\ECS_Base\Components\SHComponentGroup.h">
<Filter>ECS_Base\Components</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\Entity\SHEntity.h">
<Filter>Engine\ECS_Base\Entity</Filter>
<ClInclude Include="src\ECS_Base\Entity\SHEntity.h">
<Filter>ECS_Base\Entity</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\General\SHFamily.h">
<Filter>Engine\ECS_Base\General</Filter>
<ClInclude Include="src\ECS_Base\General\SHFamily.h">
<Filter>ECS_Base\General</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\General\SHHandleGenerator.h">
<Filter>Engine\ECS_Base\General</Filter>
<ClInclude Include="src\ECS_Base\General\SHHandleGenerator.h">
<Filter>ECS_Base\General</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseBase.h">
<Filter>Engine\ECS_Base\General</Filter>
<ClInclude Include="src\ECS_Base\General\SHSparseBase.h">
<Filter>ECS_Base\General</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseSet.h">
<Filter>Engine\ECS_Base\General</Filter>
<ClInclude Include="src\ECS_Base\General\SHSparseSet.h">
<Filter>ECS_Base\General</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\General\SHSparseSetContainer.h">
<Filter>Engine\ECS_Base\General</Filter>
<ClInclude Include="src\ECS_Base\General\SHSparseSetContainer.h">
<Filter>ECS_Base\General</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\SHECSMacros.h">
<Filter>Engine\ECS_Base</Filter>
<ClInclude Include="src\ECS_Base\SHECSMacros.h">
<Filter>ECS_Base</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\System\SHComponentManager.h">
<Filter>Engine\ECS_Base\System</Filter>
<ClInclude Include="src\ECS_Base\System\SHComponentManager.h">
<Filter>ECS_Base\System</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\System\SHEntityManager.h">
<Filter>Engine\ECS_Base\System</Filter>
<ClInclude Include="src\ECS_Base\System\SHEntityManager.h">
<Filter>ECS_Base\System</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\System\SHSystem.h">
<Filter>Engine\ECS_Base\System</Filter>
<ClInclude Include="src\ECS_Base\System\SHSystem.h">
<Filter>ECS_Base\System</Filter>
</ClInclude>
<ClInclude Include="src\Engine\ECS_Base\System\SHSystemManager.h">
<Filter>Engine\ECS_Base\System</Filter>
<ClInclude Include="src\ECS_Base\System\SHSystemManager.h">
<Filter>ECS_Base\System</Filter>
</ClInclude>
<ClInclude Include="src\Engine\SHEngine.h">
<Filter>Engine</Filter>
</ClInclude>
<ClInclude Include="src\Filesystem\SHFileSystem.h">
<Filter>Filesystem</Filter>
</ClInclude>
<ClInclude Include="src\Graphics\Buffers\SHVkBuffer.h">
<Filter>Graphics\Buffers</Filter>
</ClInclude>
@ -373,6 +379,9 @@
<ClInclude Include="src\Scene\SHScene.h">
<Filter>Scene</Filter>
</ClInclude>
<ClInclude Include="src\Scene\SHSceneGraph.h">
<Filter>Scene</Filter>
</ClInclude>
<ClInclude Include="src\Scene\SHSceneManager.h">
<Filter>Scene</Filter>
</ClInclude>
@ -408,27 +417,30 @@
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Engine\ECS_Base\Components\SHComponent.cpp">
<Filter>Engine\ECS_Base\Components</Filter>
<ClCompile Include="src\ECS_Base\Components\SHComponent.cpp">
<Filter>ECS_Base\Components</Filter>
</ClCompile>
<ClCompile Include="src\Engine\ECS_Base\Components\SHComponentGroup.cpp">
<Filter>Engine\ECS_Base\Components</Filter>
<ClCompile Include="src\ECS_Base\Components\SHComponentGroup.cpp">
<Filter>ECS_Base\Components</Filter>
</ClCompile>
<ClCompile Include="src\Engine\ECS_Base\Entity\SHEntity.cpp">
<Filter>Engine\ECS_Base\Entity</Filter>
<ClCompile Include="src\ECS_Base\Entity\SHEntity.cpp">
<Filter>ECS_Base\Entity</Filter>
</ClCompile>
<ClCompile Include="src\Engine\ECS_Base\System\SHComponentManager.cpp">
<Filter>Engine\ECS_Base\System</Filter>
<ClCompile Include="src\ECS_Base\System\SHComponentManager.cpp">
<Filter>ECS_Base\System</Filter>
</ClCompile>
<ClCompile Include="src\Engine\ECS_Base\System\SHEntityManager.cpp">
<Filter>Engine\ECS_Base\System</Filter>
<ClCompile Include="src\ECS_Base\System\SHEntityManager.cpp">
<Filter>ECS_Base\System</Filter>
</ClCompile>
<ClCompile Include="src\Engine\ECS_Base\System\SHSystemManager.cpp">
<Filter>Engine\ECS_Base\System</Filter>
<ClCompile Include="src\ECS_Base\System\SHSystemManager.cpp">
<Filter>ECS_Base\System</Filter>
</ClCompile>
<ClCompile Include="src\Engine\SHEngine.cpp">
<Filter>Engine</Filter>
</ClCompile>
<ClCompile Include="src\Filesystem\SHFileSystem.cpp">
<Filter>Filesystem</Filter>
</ClCompile>
<ClCompile Include="src\Graphics\Buffers\SHVkBuffer.cpp">
<Filter>Graphics\Buffers</Filter>
</ClCompile>
@ -589,6 +601,9 @@
<Filter>Resource</Filter>
</ClCompile>
<ClCompile Include="src\SHpch.cpp" />
<ClCompile Include="src\Scene\SHSceneGraph.cpp">
<Filter>Scene</Filter>
</ClCompile>
<ClCompile Include="src\Scene\SHSceneManager.cpp">
<Filter>Scene</Filter>
</ClCompile>

View File

@ -60,6 +60,7 @@ project "SHADE_Engine"
"imgui",
"spdlog",
"vulkan-1.lib",
"shaderc_shared.lib",
"shlwapi.lib"
}

View File

@ -34,7 +34,7 @@ namespace SHADE
//The Container of all Componentgroups
static std::vector<SHComponentGroup> componentGroups;
friend class SHSceneNode;
friend struct SHSceneNode;

View File

@ -0,0 +1,135 @@
#include "SHpch.h"
#include "SHFileSystem.h"
#include "fileapi.h"
#include <filesystem>
#include <cassert>
#include <queue>
namespace SHADE
{
char const FOLDER_MAX_COUNT {15};
std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> SHFileSystem::folders;
FolderPointer SHFileSystem::root {nullptr};
SHFolder::SHFolder(FolderHandle id, FolderName name)
:id{ id }, name{ name }, subFolders(0), folded{ false }, path{""}
{
}
FolderLocation SHFileSystem::CreateNewFolderHere(FolderName name, FolderLocation here) noexcept
{
if (here == 0)
{
if (!folders.contains(0))
{
folders[0] = std::make_unique<SHFolder>(0, "root");
}
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
auto const location = static_cast<FolderLocation>(count);
CreateFolder(folders[0]->path, here, location, name);
return location;
}
assert(folders.contains(here), "Folder creation location does not exist/invalid\n");
auto const count = static_cast<FolderCounter>(folders[here]->subFolders.size());
FolderHandle location = here;
location <<= FOLDER_BIT_ALLOCATE;
location |= count;
assert(count < FOLDER_MAX_COUNT, "Max subfolders reached\n");
CreateFolder(folders[0]->path, here, location, name);
return location;
}
bool SHFileSystem::DeleteFolder(FolderPointer location) noexcept
{
assert(folders.contains(location->id), "Delete target does not exist/invalid.\n");
for (auto const& subFolder : folders[location->id]->subFolders)
{
DeleteFolder(subFolder);
}
RemoveDirectoryA(folders[location->id]->path.c_str());
return true;
}
void SHFileSystem::StartupFillDirectories(FolderPath path) noexcept
{
std::queue<FolderPointer> folderQueue;
folderQueue.push(RegisterFolder(path, 0, 0, "Root"));
while (!folderQueue.empty())
{
auto folder = folderQueue.front();
folderQueue.pop();
FolderCounter count = 0;
for (auto const& dirEntry : std::filesystem::directory_iterator(folder->path))
{
if (!dirEntry.is_directory())
{
continue;
}
FolderLocation location = folder->id;
location <<= FOLDER_BIT_ALLOCATE;
location |= ++count;
std::string name = dirEntry.path().string();
name = name.substr(name.find_last_of('/') + 1, name.length() - name.find_last_of('/'));
FolderPointer newFolder{ RegisterFolder(
dirEntry.path().string(),
folder->id,
location,
name)
};
folderQueue.push(newFolder);
folder->subFolders.push_back(newFolder);
}
}
}
FolderPointer SHFileSystem::CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept
{
assert(
CreateDirectoryA(path.c_str(), nullptr),
"Failed to create folder\n"
);
folders[location] = std::make_unique<SHFolder>(location, name);
folders[location]->path = path;
folders[parent]->subFolders.push_back(folders[location].get());
return FolderMakeHelper(path, parent, location, name);
}
FolderPointer SHFileSystem::RegisterFolder(FolderPath path, FolderLocation parent, FolderHandle location,
FolderName name) noexcept
{
return FolderMakeHelper(path, parent, location, name);
}
FolderPointer SHFileSystem::FolderMakeHelper(FolderPath path, FolderLocation parent, FolderHandle location,
FolderName name) noexcept
{
folders[location] = std::make_unique<SHFolder>(location, name);
folders[location]->path = path;
folders[parent]->subFolders.push_back(folders[location].get());
return folders[location].get();
}
}

View File

@ -0,0 +1,57 @@
#pragma once
#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
namespace SHADE
{
class SHFolder;
typedef unsigned char FolderCounter;
typedef unsigned char FileCounter;
typedef uint64_t FolderLocation;
typedef uint64_t FolderHandle;
typedef std::string FolderName;
typedef std::string FolderPath;
typedef SHFolder* FolderPointer;
constexpr char FOLDER_BIT_ALLOCATE{ 4 };
constexpr char FOLDER_MAX_DEPTH{ 16 };
class SHFolder
{
public:
SHFolder(FolderHandle id, FolderName name);
FolderHandle id;
FolderName name;
std::vector<FolderPointer> subFolders;
bool folded;
private:
FolderPath path;
friend class SHFileSystem;
};
class SHFileSystem
{
public:
static FolderLocation CreateNewFolderHere(FolderName name, FolderLocation here = 0) noexcept;
static bool DeleteFolder(FolderPointer location) noexcept;
static void StartupFillDirectories(FolderPath path) noexcept;
private:
static FolderPointer root;
static std::unordered_map<FolderLocation, std::unique_ptr<SHFolder>> folders;
static FolderPointer CreateFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
static FolderPointer RegisterFolder(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
static FolderPointer FolderMakeHelper(FolderPath path, FolderLocation parent, FolderHandle location, FolderName name) noexcept;
};
}

View File

@ -22,6 +22,7 @@
#include <string>
#include <algorithm>
#include <array>
#include <ranges>
#include <utility>
#include <unordered_map>
#include <map>

View File

@ -0,0 +1,475 @@
/****************************************************************************************
* \file SHSceneGraph.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Scene Graph & Scene Nodes.
*
* \copyright Copyright (C) 2022 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>
// Primary Header
#include "SHSceneGraph.h"
// Project Headers
#include "ECS_Base/System/SHEntityManager.h"
#include "Tools/SHLogger.h"
#include "Tools/SHException.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept
: isActive { true }
, entityID { eid }
, parent { parent }
{}
SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept
: isActive { rhs.isActive }
, entityID { rhs.entityID }
, parent { rhs.parent }
{
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
}
SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept
: isActive { rhs.isActive }
, entityID { rhs.entityID }
, parent { rhs.parent }
{
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
}
SHSceneNode& SHSceneNode::operator=(const SHSceneNode& rhs) noexcept
{
if (this == &rhs)
return *this;
isActive = rhs.isActive;
entityID = rhs.entityID;
parent = rhs.parent;
children.clear();
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
return *this;
}
SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept
{
isActive = rhs.isActive;
entityID = rhs.entityID;
parent = rhs.parent;
children.clear();
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
return *this;
}
SHSceneGraph::SHSceneGraph() noexcept
: root { nullptr }
{}
SHSceneGraph::~SHSceneGraph() noexcept
{
SHASSERT(root != nullptr, "Unable to destroy a Scene without a root node!")
#ifdef _DEBUG
SHLOG_INFO("Destroying Scene Graph...")
#endif
// Go through the map and release all the nodes
for (auto* node : entityNodeMap | std::views::values)
ReleaseNode(node);
#ifdef _DEBUG
SHLOG_INFO("Scene Graph Destroyed Successfully!")
#endif
}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept
{
// Error handling
{
if (!SHEntityManager::IsValidEID(childID))
{
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;
}
}
// Find child
const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; };
const auto CHILD_ITER = std::ranges::find_if(children.begin(), children.end(),ENTITY_MATCH);
if (CHILD_ITER == children.end())
{
SHLOG_WARNING("Entity {} is not a child of Entity {}! Unable to retrieve child node!", childID, entityID)
return nullptr;
}
return *CHILD_ITER;
}
SHSceneNode* SHSceneGraph::GetRoot() const noexcept
{
if (root != nullptr)
return root;
SHLOG_WARNING("Scene has no root object!")
return nullptr;
}
SHSceneNode* SHSceneGraph::GetNode(EntityID entityID) const noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid! Unable to Get Scene node!", entityID)
return nullptr;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to Get Scene node!", entityID)
return nullptr;
}
return NODE_ITER->second;
}
SHSceneNode* SHSceneGraph::GetParent(EntityID entityID) const noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid! Unable to get Parent node!", entityID)
return nullptr;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to get Parent node!", entityID)
return nullptr;
}
return NODE_ITER->second->GetParent();
}
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, SHSceneNode* childNode) const noexcept
{
// Error Handling
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return nullptr;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
return nullptr;
}
const auto& children = NODE_ITER->second->GetChildren();
if (children.empty())
{
SHLOG_WARNING("Entity {} has no children!", entityID)
return nullptr;
}
const auto CHILD_ITER = std::ranges::find(children.begin(), children.end(), childNode);
if (CHILD_ITER == children.end())
{
SHLOG_WARNING("Entity {} is not a child of Entity {}!", childNode->GetEntityID(), entityID)
return nullptr;
}
return *CHILD_ITER;
}
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, EntityID childEntityID) const noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return nullptr;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
return nullptr;
}
return NODE_ITER->second->GetChild(childEntityID);
}
const std::vector<SHSceneNode*>& SHSceneGraph::GetChildren(EntityID entityID) const noexcept
{
// TODO(Diren): Discuss with team best way to handle this
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return root->GetChildren();
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
return root->GetChildren();
}
return NODE_ITER->second->GetChildren();
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHSceneNode::SetParent(SHSceneNode* parentNode) noexcept
{
if (parentNode == nullptr)
SHLOG_WARNING("Removing Entity {}'s parent", entityID)
if (parentNode == parent)
return;
parent = parentNode;
// Update parent's children
parent->AddChild(this);
}
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
return;
}
NODE_ITER->second->SetParent(parent);
}
void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID)
return;
}
if (!SHEntityManager::IsValidEID(parent))
{
SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", parent, entityID)
return;
}
auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to set parent!", entityID)
return;
}
auto PARENT_ITER = entityNodeMap.find(entityID);
if (PARENT_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID)
return;
}
SHSceneNode* currentNode = NODE_ITER->second;
currentNode->SetParent(PARENT_ITER->second);
}
/*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHSceneNode::AddChild(SHSceneNode* newChild) noexcept
{
if (newChild == nullptr)
{
SHLOG_WARNING("Attempting to add a non-existent child to an entity!")
return;
}
children.emplace_back(newChild);
}
bool SHSceneNode::RemoveChild(EntityID childID) noexcept
{
if (!SHEntityManager::IsValidEID(childID))
{
SHLOG_ERROR("Entity {} is invalid!", childID)
return false;
}
SHSceneNode* removedChild = nullptr;
const auto ENTITY_MATCH = [&](SHSceneNode* node)
{
if (node->GetEntityID() == childID)
{
removedChild = node;
return true;
}
return false;
};
children.end() = std::remove_if(children.begin(), children.end(), ENTITY_MATCH);
removedChild->parent = nullptr;
return removedChild == nullptr;
}
bool SHSceneNode::RemoveChild(SHSceneNode* childToRemove) noexcept
{
if (childToRemove == nullptr)
{
SHLOG_WARNING("Attempting to remove non-existent child from Entity {}", entityID)
return false;
}
children.end() = std::remove(children.begin(), children.end(), childToRemove);
childToRemove->parent = nullptr;
return true;
}
void SHSceneNode::RemoveAllChildren() noexcept
{
for (const auto child : children)
child->parent = nullptr;
children.clear();
}
SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent)
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return nullptr;
}
if (auto NODE_ITER = entityNodeMap.find(entityID); NODE_ITER != entityNodeMap.end())
{
SHLOG_WARNING("Entity {} already exists in the scene!", entityID)
return NODE_ITER->second;
}
SHSceneNode* newNode = AllocateNode(entityID);
newNode->SetParent(parent);
return newNode;
}
bool SHSceneGraph::RemoveNode(EntityID entityID) noexcept
{
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return false;
}
auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_WARNING("Entity {} does not exist in the scene!", entityID)
return false;
}
// Remove reference of current node from parent
SHSceneNode* currentNode = NODE_ITER->second;
SHSceneNode* parent = currentNode->GetParent();
if (parent != nullptr)
parent->RemoveChild(currentNode);
ReleaseNode(currentNode);
return true;
}
bool SHSceneGraph::RemoveNode(SHSceneNode* nodeToRemove) noexcept
{
// Remove reference of current node from parent
SHSceneNode* parent = nodeToRemove->GetParent();
if (parent != nullptr)
parent->RemoveChild(nodeToRemove);
ReleaseNode(nodeToRemove);
return true;
}
void SHSceneGraph::Reset() noexcept
{
for (auto* node : entityNodeMap | std::views::values)
ReleaseNode(node);
}
/*-----------------------------------------------------------------------------------*/
/* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHSceneNode* SHSceneGraph::AllocateNode(EntityID entityID)
{
SHSceneNode* newNode = new SHSceneNode{entityID};
#ifdef _DEBUG
SHLOG_INFO("Allocated a new Scene Node for Entity {}!", entityID)
#endif
entityNodeMap.emplace(entityID, newNode);
return newNode;
}
void SHSceneGraph::ReleaseNode(SHSceneNode* node) noexcept
{
SHASSERT(node != nullptr, "Attempting to release Invalid Node!")
// Remove parent's reference to this node if there is a parent
if (node->GetParent() != nullptr)
node->GetParent()->RemoveChild(node);
// Remove child's references to this node. Children end up as floating nodes.
for (auto* child : node->GetChildren())
{
child->SetParent(nullptr);
}
entityNodeMap.erase(node->GetEntityID());
delete node;
}
} // namespace SHADE

View File

@ -0,0 +1,143 @@
/****************************************************************************************
* \file SHSceneGraph.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Scene Graph & Scene Nodes.
*
* \copyright Copyright (C) 2022 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.
****************************************************************************************/
#pragma once
#include <vector>
// Project Headers
#include "ECS_Base/Entity/SHEntity.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SHSceneNode
{
public:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
bool isActive;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
~SHSceneNode () = default;
SHSceneNode (EntityID eid, SHSceneNode* parent = nullptr) noexcept;
SHSceneNode (const SHSceneNode& rhs) noexcept;
SHSceneNode (SHSceneNode&& rhs) noexcept;
SHSceneNode& operator= (const SHSceneNode& rhs) noexcept;
SHSceneNode& operator= (SHSceneNode&& rhs) noexcept;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] EntityID GetEntityID () const noexcept { return entityID ;}
[[nodiscard]] SHSceneNode* GetParent () const noexcept { return parent; }
[[nodiscard]] std::vector<SHSceneNode*>& GetChildren () noexcept { return children; }
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetParent (SHSceneNode* parentNode) noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void AddChild (SHSceneNode* newChild) noexcept;
bool RemoveChild (EntityID childID) noexcept;
bool RemoveChild (SHSceneNode* childToRemove) noexcept;
void RemoveAllChildren () noexcept;
private:
EntityID entityID;
SHSceneNode* parent;
std::vector<SHSceneNode*> children;
};
class SHSceneGraph
{
public:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
using EntityNodeMap = std::unordered_map<EntityID, SHSceneNode*>;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHSceneGraph () noexcept;
~SHSceneGraph () noexcept;
SHSceneGraph (const SHSceneGraph&) = delete;
SHSceneGraph (SHSceneGraph&&) = delete;
SHSceneGraph& operator= (const SHSceneGraph&) = delete;
SHSceneGraph& operator= (SHSceneGraph&&) = delete;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] SHSceneNode* GetRoot () const noexcept;
[[nodiscard]] SHSceneNode* GetNode (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, EntityID childEntityID) const noexcept;
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren (EntityID entityID) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetParent (EntityID entityID, SHSceneNode* parent) const noexcept;
void SetParent (EntityID entityID, EntityID parent) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr);
bool RemoveNode (EntityID entityID) noexcept;
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
void Reset () noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
SHSceneNode* root;
EntityNodeMap entityNodeMap;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
SHSceneNode* AllocateNode (EntityID entityID);
void ReleaseNode (SHSceneNode* node) noexcept;
};
} // namespace SHADE

View File

@ -10,11 +10,11 @@
*********************************************************************/
#include "SHpch.h"
#include "SHSceneManager.h"
#include "Engine/ECS_Base/System/SHComponentManager.h"
#include "ECS_Base/System/SHComponentManager.h"
//#include "Input/SHInputManager.h"
//#include "Engine/Rendering/Window/SHRenderingWindow.h"
#include "Engine/ECS_Base/System/SHEntityManager.h"
#include "Engine/ECS_Base/System/SHSystemManager.h"
//#include "Rendering/Window/SHRenderingWindow.h"
#include "ECS_Base/System/SHEntityManager.h"
#include "ECS_Base/System/SHSystemManager.h"
//#include "FRC/SHFrameRateController.h"
//#include "ECS_Base/System/SHApplication.h"

View File

@ -13,7 +13,7 @@
#define SH_SCENE_MANAGER_H
#include "Engine/ECS_Base/General/SHFamily.h"
#include "ECS_Base/General/SHFamily.h"
#include "SHScene.h"
#include <functional>