Merge branch 'main' into SP3-6-ArraySerialization

This commit is contained in:
Kah Wei 2022-11-10 23:44:07 +08:00
commit 5875107ce2
31 changed files with 609 additions and 420 deletions

View File

@ -124,48 +124,6 @@
Mesh: 144838771 Mesh: 144838771
Material: 123745521 Material: 123745521
Scripts: ~ Scripts: ~
- EID: 5
Name: item
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: -2, z: -5}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 2, y: 2, z: 2}
Renderable Component:
Mesh: 144838771
Material: 123745521
RigidBody Component:
Type: Dynamic
Mass: 1
Drag: 0
Angular Drag: 0
Use Gravity: true
Interpolate: false
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: true
Freeze Rotation Y: true
Freeze Rotation Z: true
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
- Is Trigger: true
Type: Box
Half Extents: {x: 2, y: 2, z: 2}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
Scripts: ~
- EID: 6 - EID: 6
Name: AI Name: AI
IsActive: true IsActive: true
@ -227,3 +185,45 @@
Layer: 4294967295 Layer: 4294967295
Strength: 0.25 Strength: 0.25
Scripts: ~ Scripts: ~
- EID: 5
Name: item
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: -2, z: -5}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 2, y: 2, z: 2}
Renderable Component:
Mesh: 144838771
Material: 123745521
RigidBody Component:
Type: Dynamic
Mass: 1
Drag: 0
Angular Drag: 0
Use Gravity: true
Interpolate: false
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: true
Freeze Rotation Y: true
Freeze Rotation Z: true
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
- Is Trigger: true
Type: Box
Half Extents: {x: 2, y: 2, z: 2}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
Scripts: ~

View File

@ -51,6 +51,7 @@ enum class AssetType : AssetTypeMeta
SCENE, SCENE,
PREFAB, PREFAB,
MATERIAL, MATERIAL,
SCRIPT,
MESH, MESH,
MAX_COUNT MAX_COUNT
}; };
@ -91,12 +92,12 @@ constexpr std::string_view EXTENSIONS[] = {
AUDIO_EXTENSION, AUDIO_EXTENSION,
SHADER_EXTENSION, SHADER_EXTENSION,
SHADER_BUILT_IN_EXTENSION, SHADER_BUILT_IN_EXTENSION,
MATERIAL_EXTENSION,
TEXTURE_EXTENSION, TEXTURE_EXTENSION,
MODEL_EXTENSION, MODEL_EXTENSION,
SCRIPT_EXTENSION,
SCENE_EXTENSION, SCENE_EXTENSION,
PREFAB_EXTENSION, PREFAB_EXTENSION,
MATERIAL_EXTENSION,
SCRIPT_EXTENSION,
AUDIO_WAV_EXTENSION, AUDIO_WAV_EXTENSION,
}; };

View File

@ -338,7 +338,7 @@ namespace SHADE
return result; return result;
} }
void SHAssetManager::CompileAsset(AssetPath const& path) noexcept void SHAssetManager::CompileAsset(AssetPath const& path, bool genMeta) noexcept
{ {
if (!std::filesystem::exists(path)) if (!std::filesystem::exists(path))
{ {
@ -360,10 +360,12 @@ namespace SHADE
std::string modelPath = path.string().substr(0, path.string().find_last_of('.')); std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
modelPath += MODEL_EXTENSION; modelPath += MODEL_EXTENSION;
newPath = modelPath; newPath = modelPath;
GenerateNewMeta(newPath);
} }
if (genMeta)
{
GenerateNewMeta(newPath);
}
} }
FolderPointer SHAssetManager::GetRootFolder() noexcept FolderPointer SHAssetManager::GetRootFolder() noexcept
@ -371,6 +373,13 @@ namespace SHADE
return folderRoot; return folderRoot;
} }
void SHAssetManager::RefreshDirectory() noexcept
{
SHFileSystem::DestroyDirectory(folderRoot);
assetCollection.clear();
BuildAssetCollection();
}
bool SHAssetManager::IsRecognised(char const* ext) noexcept bool SHAssetManager::IsRecognised(char const* ext) noexcept
{ {
for (auto const& e : EXTENSIONS) for (auto const& e : EXTENSIONS)

View File

@ -87,9 +87,10 @@ namespace SHADE
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept; static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept; static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
static void CompileAsset(AssetPath const& path) noexcept; static void CompileAsset(AssetPath const& path, bool genMeta) noexcept;
static FolderPointer GetRootFolder() noexcept; static FolderPointer GetRootFolder() noexcept;
static void RefreshDirectory() noexcept;
private: private:

View File

@ -17,6 +17,8 @@
#include <FMOD/fmod_studio.hpp> #include <FMOD/fmod_studio.hpp>
#include <SDL_keyboard.h> #include <SDL_keyboard.h>
const std::string AUDIO_FOLDER_PATH{ std::string(ASSET_ROOT)+ "/Audio/" };
namespace SHADE namespace SHADE
{ {
SHAudioSystem::SHAudioSystem() SHAudioSystem::SHAudioSystem()
@ -79,10 +81,10 @@ namespace SHADE
//SHResourceManager::LoadAllAudio(system, soundList); //SHResourceManager::LoadAllAudio(system, soundList);
LoadBank("../../Assets/Audio/Master.bank"); LoadBank((AUDIO_FOLDER_PATH + "Master.bank").data());
LoadBank("../../Assets/Audio/Master.strings.bank"); LoadBank((AUDIO_FOLDER_PATH + "Master.strings.bank").data());
//LoadBank("../../Assets/Audio/Music.bank"); //LoadBank((AUDIO_FOLDER_PATH + "Music.bank").data());
LoadBank("../../Assets/Audio/footsteps.bank"); LoadBank((AUDIO_FOLDER_PATH + "footsteps.bank").data());
//auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human"); //auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human");
//clip->Play(); //clip->Play();

View File

@ -419,7 +419,7 @@ namespace SHADE
void SHEntityParentCommand::Execute() void SHEntityParentCommand::Execute()
{ {
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
for (auto const& eid : entities) for (auto const& eid : entities)
{ {
if (entityParentData[eid].newParentEID == MAX_EID) if (entityParentData[eid].newParentEID == MAX_EID)
@ -431,7 +431,7 @@ namespace SHADE
void SHEntityParentCommand::Undo() void SHEntityParentCommand::Undo()
{ {
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
for (auto const& eid : entities) for (auto const& eid : entities)
{ {
if (entityParentData[eid].oldParentEID == MAX_EID) if (entityParentData[eid].oldParentEID == MAX_EID)

View File

@ -24,6 +24,9 @@
#include "Serialization/SHSerialization.h" #include "Serialization/SHSerialization.h"
#include "Serialization/Configurations/SHConfigurationManager.h" #include "Serialization/Configurations/SHConfigurationManager.h"
const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" };
namespace SHADE namespace SHADE
{ {
constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | constexpr ImGuiWindowFlags editorMenuBarFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
@ -43,8 +46,7 @@ namespace SHADE
void SHEditorMenuBar::Init() void SHEditorMenuBar::Init()
{ {
SHEditorWindow::Init(); SHEditorWindow::Init();
constexpr std::string_view path = "../../Assets/Editor/Layouts"; for(auto const& entry : std::filesystem::directory_iterator(LAYOUT_FOLDER_PATH))
for(auto const& entry : std::filesystem::directory_iterator(path))
{ {
layoutPaths.push_back(entry.path()); layoutPaths.push_back(entry.path());
} }

View File

@ -65,6 +65,10 @@ RTTR_REGISTRATION
); );
} }
const std::string USER_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/UserLayout.ini" };
const std::string DEFAULT_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/Default.ini" };
const std::string FONT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Fonts/"};
namespace SHADE namespace SHADE
{ {
@ -106,7 +110,7 @@ namespace SHADE
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini"; io->IniFilename = USER_LAYOUT_PATH.data();
io->ConfigWindowsMoveFromTitleBarOnly = true; io->ConfigWindowsMoveFromTitleBarOnly = true;
InitLayout(); InitLayout();
@ -236,20 +240,20 @@ namespace SHADE
{ {
if(!std::filesystem::exists(io->IniFilename)) if(!std::filesystem::exists(io->IniFilename))
{ {
std::filesystem::copy_file("../../Assets/Editor/Layouts/Default.ini", io->IniFilename); std::filesystem::copy_file(DEFAULT_LAYOUT_PATH.data(), io->IniFilename);
} }
//eventually load preferred layout here //eventually load preferred layout here
} }
void SHEditor::InitFonts() noexcept void SHEditor::InitFonts() noexcept
{ {
ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path ImFont* mainFont = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "Segoe UI.ttf").data(), 20.f);//TODO: Change to config based assets path
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f; ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "fa-solid-900.ttf").data(), 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "MaterialIcons-Regular.ttf").data(), 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
io->Fonts->Build(); io->Fonts->Build();
} }

View File

@ -11,9 +11,11 @@ constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 };
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 }; constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 };
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 }; constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 }; constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 }; constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 }; constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 };
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 }; constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 };
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 }; constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 };
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 }; constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 };
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 };
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 };

View File

@ -12,6 +12,7 @@
#include "SHFileSystem.h" #include "SHFileSystem.h"
#include <filesystem> #include <filesystem>
#include <queue> #include <queue>
#include <stack>
#include "Assets/SHAssetMetaHandler.h" #include "Assets/SHAssetMetaHandler.h"
@ -24,23 +25,37 @@ namespace SHADE
return true; return true;
} }
bool SHFileSystem::IsCompilable(std::string ext) noexcept
{
for (auto const& external : EXTERNALS)
{
if (ext == external)
{
return true;
}
}
return false;
}
void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept
{ {
std::queue<FolderPointer> folderQueue; std::stack<FolderPointer> folderStack;
root = new SHFolder("root"); root = new SHFolder("root");
root->path = path; root->path = path;
folderQueue.push(root); folderStack.push(root);
while (!folderQueue.empty()) while (!folderStack.empty())
{ {
auto const folder = folderQueue.front(); auto const folder = folderStack.top();
folderQueue.pop(); folderStack.pop();
std::vector<SHAsset> assets; std::vector<SHAsset> assets;
for (auto const& dirEntry : std::filesystem::directory_iterator(folder->path)) for (auto& dirEntry : std::filesystem::directory_iterator(folder->path))
{ {
auto const& path = dirEntry.path(); auto path = dirEntry.path();
path.make_preferred();
if (!dirEntry.is_directory()) if (!dirEntry.is_directory())
{ {
if (path.extension().string() == META_EXTENSION) if (path.extension().string() == META_EXTENSION)
@ -55,14 +70,15 @@ namespace SHADE
path.stem().string(), path.stem().string(),
path.string(), path.string(),
path.extension().string(), path.extension().string(),
nullptr nullptr,
IsCompilable(path.extension().string())
); );
} }
continue; continue;
} }
auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) }; auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) };
folderQueue.push(newFolder); folderStack.push(newFolder);
} }
for (auto const& asset : assets) for (auto const& asset : assets)
@ -71,6 +87,9 @@ namespace SHADE
for(auto& file : folder->files) for(auto& file : folder->files)
{ {
if (file.name == asset.name) if (file.name == asset.name)
{
AssetPath path{ file.path };
if (SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()) == asset.type)
{ {
file.assetMeta = &assetCollection[asset.id]; file.assetMeta = &assetCollection[asset.id];
break; break;
@ -80,3 +99,23 @@ namespace SHADE
} }
} }
} }
void SHFileSystem::DestroyDirectory(FolderPointer root) noexcept
{
std::stack<FolderPointer> folderStack;
folderStack.push(root);
while(!folderStack.empty())
{
auto const folder = folderStack.top();
folderStack.pop();
for (auto const& ptr : folder->subFolders)
{
folderStack.push(ptr);
}
delete folder;
}
}
}

View File

@ -20,9 +20,9 @@ namespace SHADE
{ {
public: public:
static void BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept; static void BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept;
static void DestroyDirectory(FolderPointer root) noexcept;
private: private:
static bool DeleteFolder(FolderPointer location) noexcept; static bool DeleteFolder(FolderPointer location) noexcept;
static bool IsCompilable(std::string ext) noexcept;
}; };
} }

View File

@ -33,6 +33,7 @@ namespace SHADE
FilePath path; FilePath path;
FileExt ext; FileExt ext;
SHAsset const* assetMeta; SHAsset const* assetMeta;
bool compilable;
}; };
class SHFolder class SHFolder

View File

@ -1,7 +1,7 @@
/**************************************************************************************** /****************************************************************************************
* \file SHSceneGraph.cpp * \file SHSceneGraph.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520 * \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Scene Graph & Scene Nodes. * \brief Implementation for a Scene Graph.
* *
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent * disclosure of this file or its contents without the prior written consent
@ -16,8 +16,6 @@
// Project Headers // Project Headers
#include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHEntityManager.h"
#include "Events/SHEventManager.hpp" #include "Events/SHEventManager.hpp"
#include "Tools/SHLogger.h"
#include "Tools/SHException.h"
namespace SHADE namespace SHADE
{ {
@ -25,56 +23,6 @@ namespace SHADE
/* Constructors & Destructor Definitions */ /* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept
: active { true }
, entityID { eid }
, parent { parent }
{}
SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept
: active { rhs.active }
, entityID { rhs.entityID }
, parent { rhs.parent }
{
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
}
SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept
: active { rhs.active }
, 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;
active = rhs.active;
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
{
active = rhs.active;
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 SHSceneGraph::SHSceneGraph() noexcept
: root { nullptr } : root { nullptr }
{ {
@ -110,56 +58,6 @@ namespace SHADE
/* Getter Function Definitions */ /* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
bool SHSceneNode::IsActive() const noexcept
{
return active;
}
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
{
////////////////////////////////////////
// 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;
}
const SHSceneNode* SHSceneGraph::GetRoot() const noexcept const SHSceneNode* SHSceneGraph::GetRoot() const noexcept
{ {
if (root != nullptr) if (root != nullptr)
@ -313,41 +211,7 @@ namespace SHADE
/* Setter Function Definitions */ /* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHSceneNode::SetParent(SHSceneNode* parentNode) noexcept void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* newParent) noexcept
{
if (parentNode == nullptr)
{
SHLOG_WARNING("Removing Entity {}'s parent", entityID)
if (parent)
parent->RemoveChild(this);
return;
}
// Handle self assignment
if (parent && parentNode->entityID == parent->entityID)
return;
if (parent)
parent->RemoveChild(this);
parent = parentNode;
// Update parent's children
parent->AddChild(this);
}
void SHSceneNode::SetActive(bool newActiveState) noexcept
{
active = newActiveState;
for (auto* child : children)
{
SetActive(newActiveState);
}
}
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept
{ {
//////////////////////////////////////// ////////////////////////////////////////
// Error Handling // Error Handling
@ -369,30 +233,31 @@ namespace SHADE
{ {
.node = NODE_ITER->second .node = NODE_ITER->second
, .oldParent = NODE_ITER->second->GetParent() , .oldParent = NODE_ITER->second->GetParent()
, .newParent = parent ? parent : root , .newParent = newParent ? newParent : root
}; };
if (parent == nullptr) if (newParent == nullptr)
parent = root; newParent = root;
NODE_ITER->second->SetParent(parent); ChangeParent(NODE_ITER->second, newParent);
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
} }
void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept void SHSceneGraph::SetParent(EntityID entityID, EntityID newParent) noexcept
{ {
//////////////////////////////////////// ////////////////////////////////////////
// Error Handling // 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)
return; return;
} }
if (!SHEntityManager::IsValidEID(parent)) if (!SHEntityManager::IsValidEID(newParent))
{ {
SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", parent, entityID) SHLOG_ERROR("Parent Entity {} is invalid! Unable to set Entity {}'s parent!", newParent, entityID)
return; return;
} }
@ -403,10 +268,10 @@ namespace SHADE
return; return;
} }
auto PARENT_ITER = entityNodeMap.find(parent); auto PARENT_ITER = entityNodeMap.find(newParent);
if (PARENT_ITER == entityNodeMap.end()) if (PARENT_ITER == entityNodeMap.end())
{ {
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID) SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to parent to Entity {}", newParent, entityID)
return; return;
} }
//////////////////////////////////////// ////////////////////////////////////////
@ -419,7 +284,7 @@ namespace SHADE
}; };
SHSceneNode* currentNode = NODE_ITER->second; SHSceneNode* currentNode = NODE_ITER->second;
currentNode->SetParent(PARENT_ITER->second); ChangeParent(currentNode, PARENT_ITER->second);
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
} }
@ -428,84 +293,6 @@ namespace SHADE
/* Public Function Member Definitions */ /* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHSceneNode::AddChild(SHSceneNode* newChild) noexcept
{
////////////////////////////////////////
// Error Handling
if (newChild == nullptr)
{
SHLOG_WARNING("Attempting to add a non-existent child to an entity!")
return;
}
////////////////////////////////////////
if (newChild->parent)
newChild->parent->RemoveChild(newChild);
newChild->parent = this;
children.emplace_back(newChild);
}
bool SHSceneNode::RemoveChild(EntityID childID) noexcept
{
////////////////////////////////////////
// Error Handling
if (!SHEntityManager::IsValidEID(childID))
{
SHLOG_ERROR("Entity {} is invalid!", childID)
return false;
}
////////////////////////////////////////
auto childIter = std::find_if(children.begin(), children.end(), [&](SHSceneNode* node)
{
return node->GetEntityID() == childID;
});
if (childIter == children.end())
{
SHLOG_WARNING("Unable to remove Entity {} from Entity {} since it is not it's child!", childID, entityID)
return false;
}
(*childIter)->parent = nullptr;
childIter = children.erase(childIter);
return true;
}
bool SHSceneNode::RemoveChild(SHSceneNode* childToRemove) noexcept
{
////////////////////////////////////////
// Error Handling
if (childToRemove == nullptr)
{
SHLOG_WARNING("Attempting to remove non-existent child from Entity {}", entityID)
return false;
}
////////////////////////////////////////
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;
return true;
}
void SHSceneNode::RemoveAllChildren() noexcept
{
for (const auto child : children)
child->parent = nullptr;
children.clear();
}
SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent) SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent)
{ {
//////////////////////////////////////// ////////////////////////////////////////
@ -528,13 +315,12 @@ namespace SHADE
if (parent == nullptr) if (parent == nullptr)
{ {
// Specific handling for root to avoid a warning when removing a non-existent child // Specific handling for root to avoid a warning when removing a non-existent child
parent = root;
newNode->parent = root; newNode->parent = root;
root->children.emplace_back(newNode); root->children.emplace_back(newNode);
} }
else else
{ {
newNode->SetParent(parent); ChangeParent(newNode, parent);
} }
return newNode; return newNode;
@ -542,6 +328,8 @@ namespace SHADE
bool SHSceneGraph::RemoveNode(EntityID entityID) noexcept bool SHSceneGraph::RemoveNode(EntityID entityID) noexcept
{ {
////////////////////////////////////////
// Error Handling
if (!SHEntityManager::IsValidEID(entityID)) if (!SHEntityManager::IsValidEID(entityID))
{ {
SHLOG_ERROR("Entity {} is invalid!", entityID) SHLOG_ERROR("Entity {} is invalid!", entityID)
@ -554,12 +342,12 @@ namespace SHADE
SHLOG_ERROR("Entity {} does not exist in the scene!", entityID) SHLOG_ERROR("Entity {} does not exist in the scene!", entityID)
return false; return false;
} }
////////////////////////////////////////
// Remove reference of current node from parent // Remove reference of current node from parent
SHSceneNode* currentNode = NODE_ITER->second; SHSceneNode* currentNode = NODE_ITER->second;
SHSceneNode* parent = currentNode->GetParent(); if (currentNode->parent != nullptr)
if (parent != nullptr) RemoveChild(currentNode->parent, currentNode);
parent->RemoveChild(currentNode);
ReleaseNode(currentNode); ReleaseNode(currentNode);
return true; return true;
@ -568,9 +356,8 @@ namespace SHADE
bool SHSceneGraph::RemoveNode(SHSceneNode* nodeToRemove) noexcept bool SHSceneGraph::RemoveNode(SHSceneNode* nodeToRemove) noexcept
{ {
// Remove reference of current node from parent // Remove reference of current node from parent
SHSceneNode* parent = nodeToRemove->GetParent(); if (nodeToRemove->parent != nullptr)
if (parent != nullptr) RemoveChild(nodeToRemove->parent, nodeToRemove);
parent->RemoveChild(nodeToRemove);
ReleaseNode(nodeToRemove); ReleaseNode(nodeToRemove);
return true; return true;
@ -582,6 +369,91 @@ namespace SHADE
ReleaseNode(node); ReleaseNode(node);
} }
bool SHSceneGraph::IsChildOf(EntityID entityID, SHSceneNode* targetNode) noexcept
{
////////////////////////////////////////
// Error Handling
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return false;
}
auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", entityID)
return false;
}
////////////////////////////////////////
// Handle self-checks
if (NODE_ITER->second == targetNode)
{
SHLOG_WARNING("Entity {} cannot be a child of itself!", entityID)
return false;
}
// Search for a matching target until the root
const SHSceneNode* CURRENT_TARGET = NODE_ITER->second->parent;
while (CURRENT_TARGET != root)
{
if (CURRENT_TARGET == targetNode)
return true;
CURRENT_TARGET = CURRENT_TARGET->parent;
}
return false;
}
bool SHSceneGraph::IsChildOf(EntityID entityID, EntityID targetID) noexcept
{
////////////////////////////////////////
// Error Handling
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return false;
}
if (!SHEntityManager::IsValidEID(targetID))
{
SHLOG_ERROR("Entity {} is invalid!", targetID)
return false;
}
auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", entityID)
return false;
}
auto TARGET_ITER = entityNodeMap.find(targetID);
if (TARGET_ITER == entityNodeMap.end())
{
SHLOG_ERROR("Entity {} cannot be found in the scene! Unable to check child!", targetID)
return false;
}
////////////////////////////////////////
const SHSceneNode* CURRENT_TARGET = NODE_ITER->second->parent;
while (CURRENT_TARGET != root)
{
if (CURRENT_TARGET == TARGET_ITER->second)
return true;
CURRENT_TARGET = CURRENT_TARGET->parent;
}
return false;
}
void SHSceneGraph::Traverse (const UnaryFunction& function) const void SHSceneGraph::Traverse (const UnaryFunction& function) const
{ {
TraverseAndInvokeFunction(root, function); TraverseAndInvokeFunction(root, function);
@ -594,11 +466,6 @@ namespace SHADE
SHSceneNode* SHSceneGraph::AllocateNode(EntityID entityID) SHSceneNode* SHSceneGraph::AllocateNode(EntityID entityID)
{ {
SHSceneNode* newNode = new SHSceneNode{entityID}; SHSceneNode* newNode = new SHSceneNode{entityID};
//#ifdef _DEBUG
// SHLOG_INFO("Allocated a new Scene Node for Entity {}!", entityID)
//#endif
entityNodeMap.emplace(entityID, newNode); entityNodeMap.emplace(entityID, newNode);
return newNode; return newNode;
} }
@ -608,19 +475,81 @@ namespace SHADE
SHASSERT(node != nullptr, "Attempting to release Invalid Node!") SHASSERT(node != nullptr, "Attempting to release Invalid Node!")
// Remove parent's reference to this node if there is a parent // Remove parent's reference to this node if there is a parent
if (node->GetParent() != nullptr) if (node->parent != nullptr)
node->GetParent()->RemoveChild(node); RemoveChild(node->parent, node);
// Remove child's references to this node. Children end up as floating nodes. // Remove child's references to this node. Children end up as floating nodes.
for (auto* child : node->GetChildren()) for (auto* child : node->GetChildren())
{ {
child->SetParent(nullptr); ChangeParent(child, nullptr);
} }
entityNodeMap.erase(node->GetEntityID()); entityNodeMap.erase(node->GetEntityID());
delete node; delete node;
} }
void SHSceneGraph::ChangeParent(SHSceneNode* node, SHSceneNode* newParent)
{
// Handle self assignment
if (node->parent != nullptr && newParent != nullptr && node->parent->entityID == newParent->entityID)
return;
// Remove child
if (node->parent)
RemoveChild(node->parent, node);
if (newParent == nullptr)
{
SHLOG_WARNING("Removing Entity {}'s parent", node->entityID)
return;
}
node->parent = newParent;
// Update parent's children
AddChild(newParent, node);
}
void SHSceneGraph::AddChild(SHSceneNode* node, SHSceneNode* newChild)
{
SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!")
SHASSERT(newChild != nullptr, "Attempting to add a non-existent child to a SceneNode!")
if (newChild->parent)
RemoveChild(newChild->parent, newChild);
newChild->parent = node;
node->children.emplace_back(newChild);
const SHSceneGraphAddChildEvent EVENT_DATA
{
.parent = node
, .childAdded = newChild
};
SHEventManager::BroadcastEvent<SHSceneGraphAddChildEvent>(EVENT_DATA, SH_SCENEGRAPH_ADD_CHILD_EVENT);
}
void SHSceneGraph::RemoveChild(SHSceneNode* node, SHSceneNode* childToRemove)
{
SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!")
SHASSERT(childToRemove != nullptr, "Attempting to remove a non-existent child from a SceneNode!")
auto childIter = std::find(node->children.begin(), node->children.end(), childToRemove);
if (childIter == node->children.end())
return;
childIter = node->children.erase(childIter);
childToRemove->parent = nullptr;
const SHSceneGraphRemoveChildEvent EVENT_DATA
{
.parent = node
, .childRemoved = childToRemove
};
SHEventManager::BroadcastEvent<SHSceneGraphRemoveChildEvent>(EVENT_DATA, SH_SCENEGRAPH_REMOVE_CHILD_EVENT);
}
void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function) void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function)
{ {
for (auto* child : node->children) for (auto* child : node->children)

View File

@ -1,7 +1,7 @@
/**************************************************************************************** /****************************************************************************************
* \file SHSceneGraph.h * \file SHSceneGraph.h
* \author Diren D Bharwani, diren.dbharwani, 390002520 * \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Scene Graph & Scene Nodes. * \brief Interface for a Scene Graph.
* *
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent * disclosure of this file or its contents without the prior written consent
@ -15,81 +15,15 @@
// Project Headers // Project Headers
#include "ECS_Base/Entity/SHEntity.h" #include "ECS_Base/Entity/SHEntity.h"
#include "SH_API.h" #include "SH_API.h"
#include "SHSceneNode.h"
#include "SHSceneGraphEvents.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHSceneGraph;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
class SH_API SHSceneNode
{
private:
/*---------------------------------------------------------------------------------*/
/* Friends */
/*---------------------------------------------------------------------------------*/
friend class SHSceneGraph;
public:
/*---------------------------------------------------------------------------------*/
/* 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]] bool IsActive () const noexcept;
[[nodiscard]] EntityID GetEntityID () const noexcept;
[[nodiscard]] SHSceneNode* GetParent () const noexcept;
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetParent (SHSceneNode* parentNode) noexcept;
void SetActive (bool newActiveState) noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void AddChild (SHSceneNode* newChild) noexcept;
bool RemoveChild (EntityID childID) noexcept;
bool RemoveChild (SHSceneNode* childToRemove) noexcept;
void RemoveAllChildren () noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
bool active;
EntityID entityID;
SHSceneNode* parent;
std::vector<SHSceneNode*> children;
};
class SH_API SHSceneGraph class SH_API SHSceneGraph
{ {
public: public:
@ -130,8 +64,8 @@ namespace SHADE
/* Setter Functions */ /* Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SetParent (EntityID entityID, SHSceneNode* parent) const noexcept; void SetParent (EntityID entityID, SHSceneNode* newParent) noexcept;
void SetParent (EntityID entityID, EntityID parent) const noexcept; void SetParent (EntityID entityID, EntityID newParent) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
@ -142,6 +76,9 @@ namespace SHADE
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept; bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
void Reset () noexcept; void Reset () noexcept;
bool IsChildOf (EntityID entityID, SHSceneNode* targetNode) noexcept;
bool IsChildOf (EntityID entityID, EntityID targetID) noexcept;
void Traverse (const UnaryFunction& function) const; void Traverse (const UnaryFunction& function) const;
private: private:
@ -158,18 +95,12 @@ namespace SHADE
SHSceneNode* AllocateNode (EntityID entityID); SHSceneNode* AllocateNode (EntityID entityID);
void ReleaseNode (SHSceneNode* node) noexcept; void ReleaseNode (SHSceneNode* node) noexcept;
void ChangeParent (SHSceneNode* node, SHSceneNode* newParent);
void AddChild (SHSceneNode* node, SHSceneNode* newChild);
void RemoveChild (SHSceneNode* node, SHSceneNode* childToRemove);
static void TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function); static void TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function);
}; };
/*-----------------------------------------------------------------------------------*/
/* Event Data Definitions */
/*-----------------------------------------------------------------------------------*/
struct SHSceneGraphChangeParentEvent
{
SHSceneNode* node;
SHSceneNode* oldParent;
SHSceneNode* newParent;
};
} // namespace SHADE } // namespace SHADE

View File

@ -0,0 +1,41 @@
/****************************************************************************************
* \file SHSceneGraphEvents.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for Scene Graph Events.
*
* \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
// Project Headers
#include "SHSceneNode.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Event Data Definitions */
/*-----------------------------------------------------------------------------------*/
struct SHSceneGraphChangeParentEvent
{
SHSceneNode* node;
SHSceneNode* oldParent;
SHSceneNode* newParent;
};
struct SHSceneGraphAddChildEvent
{
SHSceneNode* parent;
SHSceneNode* childAdded;
};
struct SHSceneGraphRemoveChildEvent
{
SHSceneNode* parent;
SHSceneNode* childRemoved;
};
} // namespace SHADE

View File

@ -0,0 +1,143 @@
/****************************************************************************************
* \file SHSceneNode.c[[
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Scene Node.
*
* \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 "SHSceneNode.h"
// Project Headers
#include "ECS_Base/Managers/SHEntityManager.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept
: active { true }
, entityID { eid }
, parent { parent }
{}
SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept
: active { rhs.active }
, entityID { rhs.entityID }
, parent { rhs.parent }
{
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
}
SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept
: active { rhs.active }
, 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;
active = rhs.active;
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
{
active = rhs.active;
entityID = rhs.entityID;
parent = rhs.parent;
children.clear();
std::ranges::copy(rhs.children.begin(), rhs.children.end(), std::back_inserter(children));
return *this;
}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
bool SHSceneNode::IsActive() const noexcept
{
return active;
}
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
{
////////////////////////////////////////
// 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;
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHSceneNode::SetActive(bool newActiveState) noexcept
{
active = newActiveState;
for (auto* child : children)
{
SetActive(newActiveState);
}
}
} // namespace SHADE

View File

@ -0,0 +1,82 @@
/****************************************************************************************
* \file SHSceneNode.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Scene Node.
*
* \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"
#include "SH_API.h"
#include "SHSceneGraph.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHSceneGraph;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SH_API SHSceneNode
{
private:
/*---------------------------------------------------------------------------------*/
/* Friends */
/*---------------------------------------------------------------------------------*/
friend class SHSceneGraph;
public:
/*---------------------------------------------------------------------------------*/
/* 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]] bool IsActive () const noexcept;
[[nodiscard]] EntityID GetEntityID () const noexcept;
[[nodiscard]] SHSceneNode* GetParent () const noexcept;
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetActive (bool newActiveState) noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
bool active;
EntityID entityID;
SHSceneNode* parent;
std::vector<SHSceneNode*> children;
};
} // namespace SHADE

View File

@ -26,13 +26,15 @@ of DigiPen Institute of Technology is prohibited.
#include "Events/SHEventManager.hpp" #include "Events/SHEventManager.hpp"
#include "Physics/SHPhysicsSystem.h" #include "Physics/SHPhysicsSystem.h"
#include "Assets/SHAssetMacros.h"
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Static Definitions */ /* Static Definitions */
/*----------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------*/
const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE"); const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE");
const std::string SHScriptEngine::CSPROJ_DIR = "..\\..\\TempScriptsFolder"; const std::string SHScriptEngine::CSPROJ_DIR = std::string(ASSET_ROOT) + "/Scripts";
const std::string SHScriptEngine::CSPROJ_PATH = std::string(CSPROJ_DIR) + "\\SHADE_Scripting.csproj"; const std::string SHScriptEngine::CSPROJ_PATH = std::string(CSPROJ_DIR) + "\\SHADE_Scripting.csproj";
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -262,18 +264,18 @@ namespace SHADE
</ItemGroup>\n\ </ItemGroup>\n\
<ItemGroup>\n\ <ItemGroup>\n\
<Reference Include=\"SHADE_Managed\">\n\ <Reference Include=\"SHADE_Managed\">\n\
<HintPath Condition=\"Exists('..\\bin\\Debug\\SHADE_Managed.dll')\">..\\bin\\Debug\\SHADE_Managed.dll</HintPath>\n\ <HintPath Condition=\"Exists('..\\..\\bin\\Debug\\SHADE_Managed.dll')\">..\\..\\bin\\Debug\\SHADE_Managed.dll</HintPath>\n\
<HintPath Condition=\"Exists('..\\bin\\Release\\SHADE_Managed.dll')\">..\\bin\\Release\\SHADE_Managed.dll</HintPath>\n\ <HintPath Condition=\"Exists('..\\..\\bin\\Release\\SHADE_Managed.dll')\">..\\..\\bin\\Release\\SHADE_Managed.dll</HintPath>\n\
</Reference>\n\ </Reference>\n\
<Reference Include=\"SHADE_CSharp\">\n\ <Reference Include=\"SHADE_CSharp\">\n\
<HintPath Condition=\"Exists('..\\bin\\Debug\\SHADE_Managed.dll')\">..\\bin\\Debug\\SHADE_CSharp.dll</HintPath>\n\ <HintPath Condition=\"Exists('..\\..\\bin\\Debug\\SHADE_Managed.dll')\">..\\..\\bin\\Debug\\SHADE_CSharp.dll</HintPath>\n\
<HintPath Condition=\"Exists('..\\bin\\Release\\SHADE_Managed.dll')\">..\\bin\\Release\\SHADE_CSharp.dll</HintPath>\n\ <HintPath Condition=\"Exists('..\\..\\bin\\Release\\SHADE_Managed.dll')\">..\\..\\bin\\Release\\SHADE_CSharp.dll</HintPath>\n\
</Reference>\n\ </Reference>\n\
</ItemGroup>\n\ </ItemGroup>\n\
</Project>"; </Project>";
// Attempt to create the file // Attempt to create the file
std::ofstream file(path); std::ofstream file(path, std::ios::out | std::ios::trunc);
if (!file.is_open()) if (!file.is_open())
throw std::runtime_error("Unable to create CsProj file!"); throw std::runtime_error("Unable to create CsProj file!");

View File

@ -25,8 +25,8 @@ namespace SHADE
class SH_API SHConfigurationManager class SH_API SHConfigurationManager
{ {
public: public:
static constexpr std::string_view applicationConfigPath{"../../Assets/Application.SHConfig"}; static inline std::string applicationConfigPath{ std::string(ASSET_ROOT) + "/Application.SHConfig"};
static constexpr std::string_view editorConfigPath{"../../Assets/Editor/Editor.SHConfig"}; static inline std::string editorConfigPath{ std::string(ASSET_ROOT) + "/Editor/Editor.SHConfig"};
static void SaveApplicationConfig(); static void SaveApplicationConfig();
static SHApplicationConfig& LoadApplicationConfig(WindowData* wndData = nullptr); static SHApplicationConfig& LoadApplicationConfig(WindowData* wndData = nullptr);

View File

@ -105,7 +105,7 @@ namespace SHADE
{ {
if (!valid) if (!valid)
throw gcnew System::NullReferenceException(); throw gcnew System::NullReferenceException();
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph(); auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
if (newParent == nullptr) if (newParent == nullptr)
SCENE_GRAPH.SetParent(entity, nullptr); SCENE_GRAPH.SetParent(entity, nullptr);