Merge pull request #34 from SHADE-DP/SP3-12-SceneGraph
SP3-12 Scene Graph Fixes BUGFIXES Scene Graph automatically creates a root which is set to MAX_EID Fixed constness of getter functions in Scene Graph & Scene Node
This commit is contained in:
commit
5b6f60ee8a
|
@ -76,7 +76,10 @@ namespace SHADE
|
||||||
|
|
||||||
SHSceneGraph::SHSceneGraph() noexcept
|
SHSceneGraph::SHSceneGraph() noexcept
|
||||||
: root { nullptr }
|
: root { nullptr }
|
||||||
{}
|
{
|
||||||
|
// The root is set to the maximum entity. It should not be interfaced with.
|
||||||
|
root = AllocateNode(MAX_EID);
|
||||||
|
}
|
||||||
|
|
||||||
SHSceneGraph::~SHSceneGraph() noexcept
|
SHSceneGraph::~SHSceneGraph() noexcept
|
||||||
{
|
{
|
||||||
|
@ -90,6 +93,8 @@ namespace SHADE
|
||||||
for (auto* node : entityNodeMap | std::views::values)
|
for (auto* node : entityNodeMap | std::views::values)
|
||||||
ReleaseNode(node);
|
ReleaseNode(node);
|
||||||
|
|
||||||
|
delete root;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
SHLOG_INFO("Scene Graph Destroyed Successfully!")
|
SHLOG_INFO("Scene Graph Destroyed Successfully!")
|
||||||
#endif
|
#endif
|
||||||
|
@ -99,10 +104,25 @@ namespace SHADE
|
||||||
/* Getter Function Definitions */
|
/* Getter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
EntityID SHSceneNode::GetEntityID() const noexcept
|
||||||
|
{
|
||||||
|
return entityID;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHSceneNode* SHSceneNode::GetParent() const noexcept
|
||||||
|
{
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<SHSceneNode*>& SHSceneNode::GetChildren() const noexcept
|
||||||
|
{
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept
|
SHSceneNode* SHSceneNode::GetChild(EntityID childID) const noexcept
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
// Error handling
|
// Error handling
|
||||||
{
|
|
||||||
if (!SHEntityManager::IsValidEID(childID))
|
if (!SHEntityManager::IsValidEID(childID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Child Entity {} is invalid! Unable to get child from Entity {}", childID, entityID)
|
SHLOG_ERROR("Child Entity {} is invalid! Unable to get child from Entity {}", childID, entityID)
|
||||||
|
@ -114,7 +134,7 @@ namespace SHADE
|
||||||
SHLOG_WARNING("Entity {} has no children!", entityID)
|
SHLOG_WARNING("Entity {} has no children!", entityID)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
////////////////////////////////////////
|
||||||
|
|
||||||
// Find child
|
// Find child
|
||||||
const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; };
|
const auto ENTITY_MATCH = [&](const SHSceneNode* node) { return node->GetEntityID() == childID; };
|
||||||
|
@ -129,7 +149,7 @@ namespace SHADE
|
||||||
return *CHILD_ITER;
|
return *CHILD_ITER;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHSceneNode* SHSceneGraph::GetRoot() const noexcept
|
const SHSceneNode* SHSceneGraph::GetRoot() const noexcept
|
||||||
{
|
{
|
||||||
if (root != nullptr)
|
if (root != nullptr)
|
||||||
return root;
|
return root;
|
||||||
|
@ -140,6 +160,8 @@ namespace SHADE
|
||||||
|
|
||||||
SHSceneNode* SHSceneGraph::GetNode(EntityID entityID) const noexcept
|
SHSceneNode* SHSceneGraph::GetNode(EntityID entityID) const noexcept
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error handling
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid! Unable to Get Scene node!", entityID)
|
SHLOG_ERROR("Entity {} is invalid! Unable to Get Scene node!", entityID)
|
||||||
|
@ -152,12 +174,15 @@ namespace SHADE
|
||||||
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to Get Scene node!", entityID)
|
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to Get Scene node!", entityID)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
return NODE_ITER->second;
|
return NODE_ITER->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHSceneNode* SHSceneGraph::GetParent(EntityID entityID) const noexcept
|
SHSceneNode* SHSceneGraph::GetParent(EntityID entityID) const noexcept
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error handling
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid! Unable to get Parent node!", entityID)
|
SHLOG_ERROR("Entity {} is invalid! Unable to get Parent node!", entityID)
|
||||||
|
@ -170,13 +195,15 @@ namespace SHADE
|
||||||
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to get Parent node!", entityID)
|
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to get Parent node!", entityID)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
return NODE_ITER->second->GetParent();
|
return NODE_ITER->second->GetParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, SHSceneNode* childNode) const noexcept
|
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, SHSceneNode* childNode) const noexcept
|
||||||
{
|
{
|
||||||
// Error Handling
|
////////////////////////////////////////
|
||||||
|
// Error handling
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||||
|
@ -203,12 +230,15 @@ namespace SHADE
|
||||||
SHLOG_WARNING("Entity {} is not a child of Entity {}!", childNode->GetEntityID(), entityID)
|
SHLOG_WARNING("Entity {} is not a child of Entity {}!", childNode->GetEntityID(), entityID)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
return *CHILD_ITER;
|
return *CHILD_ITER;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, EntityID childEntityID) const noexcept
|
SHSceneNode* SHSceneGraph::GetChild(EntityID entityID, EntityID childEntityID) const noexcept
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error handling
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||||
|
@ -221,14 +251,15 @@ namespace SHADE
|
||||||
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
return NODE_ITER->second->GetChild(childEntityID);
|
return NODE_ITER->second->GetChild(childEntityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<SHSceneNode*>& SHSceneGraph::GetChildren(EntityID entityID) const noexcept
|
const std::vector<SHSceneNode*>& SHSceneGraph::GetChildren(EntityID entityID) const noexcept
|
||||||
{
|
{
|
||||||
// TODO(Diren): Discuss with team best way to handle this
|
////////////////////////////////////////
|
||||||
|
// Error handling
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||||
|
@ -241,6 +272,7 @@ namespace SHADE
|
||||||
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
||||||
return root->GetChildren();
|
return root->GetChildren();
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
return NODE_ITER->second->GetChildren();
|
return NODE_ITER->second->GetChildren();
|
||||||
}
|
}
|
||||||
|
@ -254,6 +286,7 @@ namespace SHADE
|
||||||
if (parentNode == nullptr)
|
if (parentNode == nullptr)
|
||||||
SHLOG_WARNING("Removing Entity {}'s parent", entityID)
|
SHLOG_WARNING("Removing Entity {}'s parent", entityID)
|
||||||
|
|
||||||
|
// Handle self assignment
|
||||||
if (parentNode == parent)
|
if (parentNode == parent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -264,6 +297,8 @@ namespace SHADE
|
||||||
|
|
||||||
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept
|
void SHSceneGraph::SetParent(EntityID entityID, SHSceneNode* parent) const noexcept
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||||
|
@ -276,12 +311,15 @@ namespace SHADE
|
||||||
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
SHLOG_WARNING("Entity {} cannot be found in the scene!", entityID)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
NODE_ITER->second->SetParent(parent);
|
NODE_ITER->second->SetParent(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept
|
void SHSceneGraph::SetParent(EntityID entityID, EntityID parent) const noexcept
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID)
|
SHLOG_ERROR("Entity {} is invalid! Unable to set parent of an invalid entity!", entityID)
|
||||||
|
@ -307,6 +345,7 @@ namespace SHADE
|
||||||
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID)
|
SHLOG_WARNING("Entity {} cannot be found in the scene! Unable to parent to Entity {}", parent, entityID)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
SHSceneNode* currentNode = NODE_ITER->second;
|
SHSceneNode* currentNode = NODE_ITER->second;
|
||||||
currentNode->SetParent(PARENT_ITER->second);
|
currentNode->SetParent(PARENT_ITER->second);
|
||||||
|
@ -318,22 +357,32 @@ namespace SHADE
|
||||||
|
|
||||||
void SHSceneNode::AddChild(SHSceneNode* newChild) noexcept
|
void SHSceneNode::AddChild(SHSceneNode* newChild) noexcept
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
if (newChild == nullptr)
|
if (newChild == nullptr)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Attempting to add a non-existent child to an entity!")
|
SHLOG_WARNING("Attempting to add a non-existent child to an entity!")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
if (newChild->parent)
|
||||||
|
newChild->parent->RemoveChild(newChild);
|
||||||
|
|
||||||
|
newChild->parent = this;
|
||||||
children.emplace_back(newChild);
|
children.emplace_back(newChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHSceneNode::RemoveChild(EntityID childID) noexcept
|
bool SHSceneNode::RemoveChild(EntityID childID) noexcept
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
if (!SHEntityManager::IsValidEID(childID))
|
if (!SHEntityManager::IsValidEID(childID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid!", childID)
|
SHLOG_ERROR("Entity {} is invalid!", childID)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
SHSceneNode* removedChild = nullptr;
|
SHSceneNode* removedChild = nullptr;
|
||||||
const auto ENTITY_MATCH = [&](SHSceneNode* node)
|
const auto ENTITY_MATCH = [&](SHSceneNode* node)
|
||||||
|
@ -348,18 +397,23 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
children.end() = std::remove_if(children.begin(), children.end(), ENTITY_MATCH);
|
children.end() = std::remove_if(children.begin(), children.end(), ENTITY_MATCH);
|
||||||
|
|
||||||
|
if (removedChild)
|
||||||
removedChild->parent = nullptr;
|
removedChild->parent = nullptr;
|
||||||
|
|
||||||
return removedChild == nullptr;
|
return removedChild != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHSceneNode::RemoveChild(SHSceneNode* childToRemove) noexcept
|
bool SHSceneNode::RemoveChild(SHSceneNode* childToRemove) noexcept
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
if (childToRemove == nullptr)
|
if (childToRemove == nullptr)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Attempting to remove non-existent child from Entity {}", entityID)
|
SHLOG_WARNING("Attempting to remove non-existent child from Entity {}", entityID)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
children.end() = std::remove(children.begin(), children.end(), childToRemove);
|
children.end() = std::remove(children.begin(), children.end(), childToRemove);
|
||||||
childToRemove->parent = nullptr;
|
childToRemove->parent = nullptr;
|
||||||
|
@ -378,11 +432,14 @@ namespace SHADE
|
||||||
|
|
||||||
SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent)
|
SHSceneNode* SHSceneGraph::AddNode(EntityID entityID, SHSceneNode* parent)
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Error Handling
|
||||||
if (!SHEntityManager::IsValidEID(entityID))
|
if (!SHEntityManager::IsValidEID(entityID))
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
SHLOG_ERROR("Entity {} is invalid!", entityID)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
if (auto NODE_ITER = entityNodeMap.find(entityID); NODE_ITER != entityNodeMap.end())
|
if (auto NODE_ITER = entityNodeMap.find(entityID); NODE_ITER != entityNodeMap.end())
|
||||||
{
|
{
|
||||||
|
@ -391,6 +448,10 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
SHSceneNode* newNode = AllocateNode(entityID);
|
SHSceneNode* newNode = AllocateNode(entityID);
|
||||||
|
|
||||||
|
if (parent == nullptr)
|
||||||
|
parent = root;
|
||||||
|
|
||||||
newNode->SetParent(parent);
|
newNode->SetParent(parent);
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
|
|
|
@ -47,9 +47,9 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] EntityID GetEntityID () const noexcept { return entityID ;}
|
[[nodiscard]] EntityID GetEntityID () const noexcept;
|
||||||
[[nodiscard]] SHSceneNode* GetParent () const noexcept { return parent; }
|
[[nodiscard]] SHSceneNode* GetParent () const noexcept;
|
||||||
[[nodiscard]] std::vector<SHSceneNode*>& GetChildren () noexcept { return children; }
|
[[nodiscard]] const std::vector<SHSceneNode*>& GetChildren () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
|
[[nodiscard]] SHSceneNode* GetChild (EntityID childID) const noexcept;
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] SHSceneNode* GetRoot () const noexcept;
|
[[nodiscard]] const SHSceneNode* GetRoot () const noexcept;
|
||||||
[[nodiscard]] SHSceneNode* GetNode (EntityID entityID) const noexcept;
|
[[nodiscard]] SHSceneNode* GetNode (EntityID entityID) const noexcept;
|
||||||
[[nodiscard]] SHSceneNode* GetParent (EntityID entityID) const noexcept;
|
[[nodiscard]] SHSceneNode* GetParent (EntityID entityID) const noexcept;
|
||||||
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, SHSceneNode* childNode) const noexcept;
|
[[nodiscard]] SHSceneNode* GetChild (EntityID entityID, SHSceneNode* childNode) const noexcept;
|
||||||
|
|
Loading…
Reference in New Issue