Added ActiveInHierarchy property to Scene Nodes #293

Merged
direnbharwani merged 3 commits from SP3-12-SceneGraph into main 2022-12-13 21:58:14 +08:00
5 changed files with 119 additions and 42 deletions

View File

@ -186,6 +186,27 @@ namespace SHADE
return NODE_ITER->second->GetChildren(); return NODE_ITER->second->GetChildren();
} }
bool SHSceneGraph::IsActive(EntityID entityID) const noexcept
{
////////////////////////////////////////
// Error handling
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return false;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID)
return false;
}
////////////////////////////////////////
return NODE_ITER->second->IsActive();
}
bool SHSceneGraph::IsActiveInHierarchy(EntityID entityID) const noexcept bool SHSceneGraph::IsActiveInHierarchy(EntityID entityID) const noexcept
{ {
//////////////////////////////////////// ////////////////////////////////////////
@ -204,24 +225,7 @@ namespace SHADE
} }
//////////////////////////////////////// ////////////////////////////////////////
// Recurse up the tree until the root. If any parent is inactive, this node is inactive in the hierarchy. return NODE_ITER->second->IsActiveInHierarchy();
const SHSceneNode* PARENT_NODE = NODE_ITER->second->parent;
while (PARENT_NODE->GetEntityID() != root->GetEntityID())
{
if (!PARENT_NODE->IsActive())
return false;
if (!PARENT_NODE->parent)
{
SHLOGV_ERROR("Entity {}'s node that is not the root has no parent!", PARENT_NODE->GetEntityID())
return false;
}
PARENT_NODE = PARENT_NODE->parent;
}
return true;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -306,6 +310,27 @@ namespace SHADE
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT); SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
} }
void SHSceneGraph::SetActive(EntityID entityID, bool isActive) noexcept
{
////////////////////////////////////////
// Error handling
if (!SHEntityManager::IsValidEID(entityID))
{
SHLOG_ERROR("Entity {} is invalid!", entityID)
return;
}
const auto NODE_ITER = entityNodeMap.find(entityID);
if (NODE_ITER == entityNodeMap.end())
{
SHLOG_ERROR("Entity {} cannot be found in the scene!", entityID)
return;
}
////////////////////////////////////////
NODE_ITER->second->SetActive(isActive);
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */ /* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -58,6 +58,7 @@ namespace SHADE
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, EntityID childEntityID) const noexcept; [[nodiscard]] SHSceneNode* GetChild (EntityID entityID, EntityID childEntityID) const noexcept;
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren (EntityID entityID) const noexcept; [[nodiscard]] const std::vector<SHSceneNode*>& GetChildren (EntityID entityID) const noexcept;
[[nodiscard]] bool IsActive (EntityID entityID) const noexcept;
[[nodiscard]] bool IsActiveInHierarchy (EntityID entityID) const noexcept; [[nodiscard]] bool IsActiveInHierarchy (EntityID entityID) const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -67,6 +68,8 @@ namespace SHADE
void SetParent (EntityID entityID, SHSceneNode* newParent) noexcept; void SetParent (EntityID entityID, SHSceneNode* newParent) noexcept;
void SetParent (EntityID entityID, EntityID newParent) noexcept; void SetParent (EntityID entityID, EntityID newParent) noexcept;
void SetActive (EntityID entityID, bool isActive) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -24,6 +24,7 @@ namespace SHADE
SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept SHSceneNode::SHSceneNode(EntityID eid, SHSceneNode* parent) noexcept
: active { true } : active { true }
, isActiveInHierarchy { true }
, entityID { eid } , entityID { eid }
, parent { parent } , parent { parent }
{} {}
@ -31,6 +32,7 @@ namespace SHADE
SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept SHSceneNode::SHSceneNode(const SHSceneNode& rhs) noexcept
: active { rhs.active } : active { rhs.active }
, isActiveInHierarchy { rhs.isActiveInHierarchy }
, entityID { rhs.entityID } , entityID { rhs.entityID }
, parent { rhs.parent } , parent { rhs.parent }
{ {
@ -39,6 +41,7 @@ namespace SHADE
SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept SHSceneNode::SHSceneNode(SHSceneNode&& rhs) noexcept
: active { rhs.active } : active { rhs.active }
, isActiveInHierarchy { rhs.isActiveInHierarchy }
, entityID { rhs.entityID } , entityID { rhs.entityID }
, parent { rhs.parent } , parent { rhs.parent }
{ {
@ -51,6 +54,7 @@ namespace SHADE
return *this; return *this;
active = rhs.active; active = rhs.active;
isActiveInHierarchy = rhs.isActiveInHierarchy;
entityID = rhs.entityID; entityID = rhs.entityID;
parent = rhs.parent; parent = rhs.parent;
@ -63,6 +67,7 @@ namespace SHADE
SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept SHSceneNode& SHSceneNode::operator=(SHSceneNode&& rhs) noexcept
{ {
active = rhs.active; active = rhs.active;
isActiveInHierarchy = rhs.isActiveInHierarchy;
entityID = rhs.entityID; entityID = rhs.entityID;
parent = rhs.parent; parent = rhs.parent;
@ -81,6 +86,11 @@ namespace SHADE
return active; return active;
} }
bool SHSceneNode::IsActiveInHierarchy() const noexcept
{
return isActiveInHierarchy;
}
EntityID SHSceneNode::GetEntityID() const noexcept EntityID SHSceneNode::GetEntityID() const noexcept
{ {
return entityID; return entityID;
@ -133,6 +143,30 @@ namespace SHADE
void SHSceneNode::SetActive(bool newActiveState) noexcept void SHSceneNode::SetActive(bool newActiveState) noexcept
{ {
active = newActiveState; active = newActiveState;
isActiveInHierarchy = newActiveState;
// Set the entity's active state
// TODO(Daniel / Diren): Sync it based on active in hierarchy or active state.
SHEntityManager::GetEntityByID(entityID)->SetActive(active);
// Recurse down the children to set the active in hierarchy state
recursiveSetActiveInHierarchy(active, children);
}
/*-----------------------------------------------------------------------------------*/
/* Private Member Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHSceneNode::recursiveSetActiveInHierarchy(bool activeInHierarchy, const std::vector<SHSceneNode*>& childrenToSet) noexcept
{
if (childrenToSet.empty())
return;
for (auto* child : childrenToSet)
{
child->isActiveInHierarchy = activeInHierarchy;
recursiveSetActiveInHierarchy(activeInHierarchy, child->children);
}
} }
} // namespace SHADE } // namespace SHADE

View File

@ -43,7 +43,7 @@ namespace SHADE
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
~SHSceneNode () = default; ~SHSceneNode () noexcept = 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;
@ -56,6 +56,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] bool IsActive () const noexcept; [[nodiscard]] bool IsActive () const noexcept;
[[nodiscard]] bool IsActiveInHierarchy () const noexcept;
[[nodiscard]] EntityID GetEntityID () const noexcept; [[nodiscard]] EntityID GetEntityID () const noexcept;
[[nodiscard]] SHSceneNode* GetParent () const noexcept; [[nodiscard]] SHSceneNode* GetParent () const noexcept;
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept; [[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
@ -74,9 +75,16 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
bool active; bool active;
bool isActiveInHierarchy;
EntityID entityID; EntityID entityID;
SHSceneNode* parent; SHSceneNode* parent;
std::vector<SHSceneNode*> children; std::vector<SHSceneNode*> children;
/*---------------------------------------------------------------------------------*/
/* Member Functions */
/*---------------------------------------------------------------------------------*/
static void recursiveSetActiveInHierarchy(bool activeInHierarchy, const std::vector<SHSceneNode*>& childrenToSet) noexcept;
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -76,7 +76,13 @@ namespace SHADE
{ {
if (!valid) if (!valid)
throw gcnew System::NullReferenceException(); throw gcnew System::NullReferenceException();
return GetNativeEntity().GetActive(); auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(GetEntity());
if (!node)
{
Debug::LogWarning("Attempting to access a GameObject's Active state which does not exist. Assuming inactive.");
return false;
}
return node->IsActive();
} }
bool GameObject::IsActiveInHierarchy::get() bool GameObject::IsActiveInHierarchy::get()
{ {
@ -88,7 +94,7 @@ namespace SHADE
Debug::LogWarning("Attempting to access a GameObject's ActiveInHierarchy state which does not exist. Assuming inactive."); Debug::LogWarning("Attempting to access a GameObject's ActiveInHierarchy state which does not exist. Assuming inactive.");
return false; return false;
} }
return node->IsActive(); return node->IsActiveInHierarchy();
} }
Entity GameObject::EntityId::get() Entity GameObject::EntityId::get()
{ {
@ -148,7 +154,8 @@ namespace SHADE
{ {
if (!valid) if (!valid)
throw gcnew System::NullReferenceException(); throw gcnew System::NullReferenceException();
GetNativeEntity().SetActive(active);
SHSceneManager::GetCurrentSceneGraph().SetActive(GetEntity(), active);
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/