Implemented a custom physics engine #316
|
@ -38,4 +38,14 @@ namespace SHADE
|
||||||
SHSceneNode* childRemoved = nullptr;
|
SHSceneNode* childRemoved = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SHSceneInitEvent
|
||||||
|
{
|
||||||
|
uint32_t sceneID = std::numeric_limits<uint32_t>::max();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHSceneExitEvent
|
||||||
|
{
|
||||||
|
uint32_t sceneID = std::numeric_limits<uint32_t>::max();
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -27,7 +27,7 @@ namespace SHADE
|
||||||
: root { nullptr }
|
: root { nullptr }
|
||||||
{
|
{
|
||||||
// The root is set to the maximum entity. It should not be interfaced with.
|
// The root is set to the maximum entity. It should not be interfaced with.
|
||||||
root = AllocateNode(MAX_EID);
|
root = allocateNode(MAX_EID);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHSceneGraph::~SHSceneGraph() noexcept
|
SHSceneGraph::~SHSceneGraph() noexcept
|
||||||
|
@ -239,7 +239,7 @@ namespace SHADE
|
||||||
if (newParent == nullptr)
|
if (newParent == nullptr)
|
||||||
newParent = root;
|
newParent = root;
|
||||||
|
|
||||||
ChangeParent(NODE_ITER->second, newParent);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -284,7 +284,7 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
SHSceneNode* currentNode = NODE_ITER->second;
|
SHSceneNode* currentNode = NODE_ITER->second;
|
||||||
ChangeParent(currentNode, 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);
|
||||||
}
|
}
|
||||||
|
@ -310,7 +310,7 @@ namespace SHADE
|
||||||
return NODE_ITER->second;
|
return NODE_ITER->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHSceneNode* newNode = AllocateNode(entityID);
|
SHSceneNode* newNode = allocateNode(entityID);
|
||||||
|
|
||||||
if (parent == nullptr)
|
if (parent == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -320,7 +320,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ChangeParent(newNode, parent);
|
changeParent(newNode, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newNode;
|
return newNode;
|
||||||
|
@ -347,9 +347,9 @@ namespace SHADE
|
||||||
// Remove reference of current node from parent
|
// Remove reference of current node from parent
|
||||||
SHSceneNode* currentNode = NODE_ITER->second;
|
SHSceneNode* currentNode = NODE_ITER->second;
|
||||||
if (currentNode->parent != nullptr)
|
if (currentNode->parent != nullptr)
|
||||||
RemoveChild(currentNode->parent, currentNode);
|
removeChild(currentNode->parent, currentNode);
|
||||||
|
|
||||||
ReleaseNode(currentNode);
|
releaseNode(currentNode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,16 +357,16 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
// Remove reference of current node from parent
|
// Remove reference of current node from parent
|
||||||
if (nodeToRemove->parent != nullptr)
|
if (nodeToRemove->parent != nullptr)
|
||||||
RemoveChild(nodeToRemove->parent, nodeToRemove);
|
removeChild(nodeToRemove->parent, nodeToRemove);
|
||||||
|
|
||||||
ReleaseNode(nodeToRemove);
|
releaseNode(nodeToRemove);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::Reset() noexcept
|
void SHSceneGraph::Reset() noexcept
|
||||||
{
|
{
|
||||||
for (auto* node : entityNodeMap | std::views::values)
|
for (auto* node : entityNodeMap | std::views::values)
|
||||||
ReleaseNode(node);
|
releaseNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHSceneGraph::IsChildOf(EntityID entityID, SHSceneNode* targetNode) noexcept
|
bool SHSceneGraph::IsChildOf(EntityID entityID, SHSceneNode* targetNode) noexcept
|
||||||
|
@ -456,39 +456,39 @@ namespace SHADE
|
||||||
|
|
||||||
void SHSceneGraph::Traverse (const UnaryFunction& function) const
|
void SHSceneGraph::Traverse (const UnaryFunction& function) const
|
||||||
{
|
{
|
||||||
TraverseAndInvokeFunction(root, function);
|
traverseAndInvokeFunction(root, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Private Function Member Definitions */
|
/* Private Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHSceneNode* SHSceneGraph::AllocateNode(EntityID entityID)
|
SHSceneNode* SHSceneGraph::allocateNode(EntityID entityID)
|
||||||
{
|
{
|
||||||
SHSceneNode* newNode = new SHSceneNode{entityID};
|
SHSceneNode* newNode = new SHSceneNode{entityID};
|
||||||
entityNodeMap.emplace(entityID, newNode);
|
entityNodeMap.emplace(entityID, newNode);
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::ReleaseNode(SHSceneNode* node) noexcept
|
void SHSceneGraph::releaseNode(SHSceneNode* node) noexcept
|
||||||
{
|
{
|
||||||
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->parent != nullptr)
|
if (node->parent != nullptr)
|
||||||
RemoveChild(node->parent, 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())
|
||||||
{
|
{
|
||||||
ChangeParent(child, nullptr);
|
changeParent(child, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
entityNodeMap.erase(node->GetEntityID());
|
entityNodeMap.erase(node->GetEntityID());
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::ChangeParent(SHSceneNode* node, SHSceneNode* newParent)
|
void SHSceneGraph::changeParent(SHSceneNode* node, SHSceneNode* newParent)
|
||||||
{
|
{
|
||||||
// Handle self assignment
|
// Handle self assignment
|
||||||
if (node->parent != nullptr && newParent != nullptr && node->parent->entityID == newParent->entityID)
|
if (node->parent != nullptr && newParent != nullptr && node->parent->entityID == newParent->entityID)
|
||||||
|
@ -496,7 +496,7 @@ namespace SHADE
|
||||||
|
|
||||||
// Remove child
|
// Remove child
|
||||||
if (node->parent)
|
if (node->parent)
|
||||||
RemoveChild(node->parent, node);
|
removeChild(node->parent, node);
|
||||||
|
|
||||||
if (newParent == nullptr)
|
if (newParent == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -506,16 +506,16 @@ namespace SHADE
|
||||||
|
|
||||||
node->parent = newParent;
|
node->parent = newParent;
|
||||||
// Update parent's children
|
// Update parent's children
|
||||||
AddChild(newParent, node);
|
addChild(newParent, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::AddChild(SHSceneNode* node, SHSceneNode* newChild)
|
void SHSceneGraph::addChild(SHSceneNode* node, SHSceneNode* newChild)
|
||||||
{
|
{
|
||||||
SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!")
|
SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!")
|
||||||
SHASSERT(newChild != nullptr, "Attempting to add a non-existent child to a SceneNode!")
|
SHASSERT(newChild != nullptr, "Attempting to add a non-existent child to a SceneNode!")
|
||||||
|
|
||||||
if (newChild->parent)
|
if (newChild->parent)
|
||||||
RemoveChild(newChild->parent, newChild);
|
removeChild(newChild->parent, newChild);
|
||||||
|
|
||||||
newChild->parent = node;
|
newChild->parent = node;
|
||||||
node->children.emplace_back(newChild);
|
node->children.emplace_back(newChild);
|
||||||
|
@ -529,7 +529,7 @@ namespace SHADE
|
||||||
SHEventManager::BroadcastEvent<SHSceneGraphAddChildEvent>(EVENT_DATA, SH_SCENEGRAPH_ADD_CHILD_EVENT);
|
SHEventManager::BroadcastEvent<SHSceneGraphAddChildEvent>(EVENT_DATA, SH_SCENEGRAPH_ADD_CHILD_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::RemoveChild(SHSceneNode* node, SHSceneNode* childToRemove)
|
void SHSceneGraph::removeChild(SHSceneNode* node, SHSceneNode* childToRemove)
|
||||||
{
|
{
|
||||||
SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!")
|
SHASSERT(node != nullptr, "Attempting to modify a non-existent scene node!")
|
||||||
SHASSERT(childToRemove != nullptr, "Attempting to remove a non-existent child from a SceneNode!")
|
SHASSERT(childToRemove != nullptr, "Attempting to remove a non-existent child from a SceneNode!")
|
||||||
|
@ -550,12 +550,12 @@ namespace SHADE
|
||||||
SHEventManager::BroadcastEvent<SHSceneGraphRemoveChildEvent>(EVENT_DATA, SH_SCENEGRAPH_REMOVE_CHILD_EVENT);
|
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)
|
||||||
{
|
{
|
||||||
function(child);
|
function(child);
|
||||||
TraverseAndInvokeFunction(child, function);
|
traverseAndInvokeFunction(child, function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@ namespace SHADE
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Encapsulates a hierarchical tree for objects in the scene.
|
||||||
|
*/
|
||||||
class SH_API SHSceneGraph
|
class SH_API SHSceneGraph
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -64,22 +68,75 @@ namespace SHADE
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Changing the parent of a node will broadcast three events in the following order:
|
||||||
|
* <br/>
|
||||||
|
* 1. SHSceneGraphChangeParentEvent
|
||||||
|
* 2. SHSceneGraphRemoveChildEvent
|
||||||
|
* 3. SHSceneGraphAddChildEvent
|
||||||
|
* <br/><br/>
|
||||||
|
* See the corresponding header file for the contents of the event struct.
|
||||||
|
*/
|
||||||
void SetParent (EntityID entityID, SHSceneNode* newParent) noexcept;
|
void SetParent (EntityID entityID, SHSceneNode* newParent) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Changing the parent of a node will broadcast three events in the following order:
|
||||||
|
* <br/>
|
||||||
|
* 1. SHSceneGraphChangeParentEvent
|
||||||
|
* 2. SHSceneGraphRemoveChildEvent
|
||||||
|
* 3. SHSceneGraphAddChildEvent
|
||||||
|
* <br/><br/>
|
||||||
|
* See the corresponding header file for the contents of the event struct.
|
||||||
|
*/
|
||||||
void SetParent (EntityID entityID, EntityID newParent) noexcept;
|
void SetParent (EntityID entityID, EntityID newParent) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Adding a node will broadcast two events in the following order:
|
||||||
|
* <br/>
|
||||||
|
* 1. SHSceneGraphChangeParentEvent
|
||||||
|
* 2. SHSceneGraphAddChildEvent
|
||||||
|
* <br/><br/>
|
||||||
|
* See the corresponding header file for the contents of the event struct.
|
||||||
|
*/
|
||||||
SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr);
|
SHSceneNode* AddNode (EntityID entityID, SHSceneNode* parent = nullptr);
|
||||||
bool RemoveNode (EntityID entityID) noexcept;
|
|
||||||
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
|
|
||||||
void Reset () noexcept;
|
|
||||||
|
|
||||||
bool IsChildOf (EntityID entityID, SHSceneNode* targetNode) noexcept;
|
/**
|
||||||
bool IsChildOf (EntityID entityID, EntityID targetID) noexcept;
|
* @brief
|
||||||
|
* Removing a node will broadcast the SHSceneGraphRemoveChildEvent.
|
||||||
|
* See the corresponding header file for the contents of the event struct.
|
||||||
|
*/
|
||||||
|
bool RemoveNode (EntityID entityID) noexcept;
|
||||||
|
|
||||||
void Traverse (const UnaryFunction& function) const;
|
/**
|
||||||
|
* @brief
|
||||||
|
* Removing a node will broadcast the SHSceneGraphRemoveChildEvent.
|
||||||
|
* See the corresponding header file for the contents of the event struct.
|
||||||
|
*/
|
||||||
|
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Clears all the scene nodes in the scene graph.
|
||||||
|
*/
|
||||||
|
void Reset () noexcept;
|
||||||
|
|
||||||
|
bool IsChildOf (EntityID entityID, SHSceneNode* targetNode) noexcept;
|
||||||
|
bool IsChildOf (EntityID entityID, EntityID targetID) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Traverses the graph and a depth-first manner and applies the the function onto each node.
|
||||||
|
* @param function
|
||||||
|
* A unary function that takes in a SHSceneNode pointer.
|
||||||
|
*/
|
||||||
|
void Traverse (const UnaryFunction& function) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -93,14 +150,14 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
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 changeParent (SHSceneNode* node, SHSceneNode* newParent);
|
||||||
void AddChild (SHSceneNode* node, SHSceneNode* newChild);
|
void addChild (SHSceneNode* node, SHSceneNode* newChild);
|
||||||
void RemoveChild (SHSceneNode* node, SHSceneNode* childToRemove);
|
void removeChild (SHSceneNode* node, SHSceneNode* childToRemove);
|
||||||
|
|
||||||
static void TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function);
|
static void traverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -17,6 +17,7 @@
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
//#include "FRC/SHFrameRateController.h"
|
//#include "FRC/SHFrameRateController.h"
|
||||||
//#include "ECS_Base/System/SHApplication.h"
|
//#include "ECS_Base/System/SHApplication.h"
|
||||||
|
#include "SHSceneEvents.h"
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -55,10 +56,11 @@ namespace SHADE
|
||||||
if (currentScene)
|
if (currentScene)
|
||||||
{
|
{
|
||||||
currentScene->Free();
|
currentScene->Free();
|
||||||
|
SHEventManager::BroadcastEvent<SHSceneExitEvent>(SHSceneExitEvent{ currentSceneID }, SH_SCENE_ON_EXIT_EVENT);
|
||||||
|
|
||||||
currentScene->Unload();
|
currentScene->Unload();
|
||||||
SHEntityManager::DestroyAllEntity();
|
SHEntityManager::DestroyAllEntity();
|
||||||
delete currentScene;
|
delete currentScene;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!prevSceneReload)
|
if (!prevSceneReload)
|
||||||
{
|
{
|
||||||
|
@ -84,6 +86,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
currentScene->Load();
|
currentScene->Load();
|
||||||
currentScene->Init();
|
currentScene->Init();
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHSceneInitEvent>(SHSceneInitEvent{ currentSceneID }, SH_SCENE_ON_INIT_EVENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // restarting scene
|
else // restarting scene
|
||||||
|
@ -91,6 +95,8 @@ namespace SHADE
|
||||||
nextSceneID = UINT32_MAX;
|
nextSceneID = UINT32_MAX;
|
||||||
|
|
||||||
currentScene->Free();
|
currentScene->Free();
|
||||||
|
SHEventManager::BroadcastEvent<SHSceneExitEvent>(SHSceneExitEvent{ currentSceneID }, SH_SCENE_ON_EXIT_EVENT);
|
||||||
|
|
||||||
if (cleanReload == true)
|
if (cleanReload == true)
|
||||||
{
|
{
|
||||||
cleanReload = false;
|
cleanReload = false;
|
||||||
|
@ -103,6 +109,7 @@ namespace SHADE
|
||||||
SHEntityManager::DestroyAllEntity();
|
SHEntityManager::DestroyAllEntity();
|
||||||
|
|
||||||
currentScene->Init();
|
currentScene->Init();
|
||||||
|
SHEventManager::BroadcastEvent<SHSceneInitEvent>(SHSceneInitEvent{ currentSceneID }, SH_SCENE_ON_INIT_EVENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,20 +15,17 @@
|
||||||
// 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 "SHSceneGraph.h"
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
/* Forward Declarations */
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class SHSceneGraph;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Encapsulates an object in the scene that is part of the scene's hierarchy.
|
||||||
|
*/
|
||||||
class SH_API SHSceneNode
|
class SH_API SHSceneNode
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -66,7 +63,7 @@ namespace SHADE
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SetActive (bool newActiveState) noexcept;
|
void SetActive (bool newActiveState) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in New Issue