Implemented a custom physics engine #316
|
@ -38,4 +38,14 @@ namespace SHADE
|
|||
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
|
|
@ -27,7 +27,7 @@ namespace SHADE
|
|||
: root { nullptr }
|
||||
{
|
||||
// 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
|
||||
|
@ -239,7 +239,7 @@ namespace SHADE
|
|||
if (newParent == nullptr)
|
||||
newParent = root;
|
||||
|
||||
ChangeParent(NODE_ITER->second, newParent);
|
||||
changeParent(NODE_ITER->second, newParent);
|
||||
|
||||
SHEventManager::BroadcastEvent<SHSceneGraphChangeParentEvent>(EVENT_DATA, SH_SCENEGRAPH_CHANGE_PARENT_EVENT);
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ namespace SHADE
|
|||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ namespace SHADE
|
|||
return NODE_ITER->second;
|
||||
}
|
||||
|
||||
SHSceneNode* newNode = AllocateNode(entityID);
|
||||
SHSceneNode* newNode = allocateNode(entityID);
|
||||
|
||||
if (parent == nullptr)
|
||||
{
|
||||
|
@ -320,7 +320,7 @@ namespace SHADE
|
|||
}
|
||||
else
|
||||
{
|
||||
ChangeParent(newNode, parent);
|
||||
changeParent(newNode, parent);
|
||||
}
|
||||
|
||||
return newNode;
|
||||
|
@ -347,9 +347,9 @@ namespace SHADE
|
|||
// Remove reference of current node from parent
|
||||
SHSceneNode* currentNode = NODE_ITER->second;
|
||||
if (currentNode->parent != nullptr)
|
||||
RemoveChild(currentNode->parent, currentNode);
|
||||
removeChild(currentNode->parent, currentNode);
|
||||
|
||||
ReleaseNode(currentNode);
|
||||
releaseNode(currentNode);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -357,16 +357,16 @@ namespace SHADE
|
|||
{
|
||||
// Remove reference of current node from parent
|
||||
if (nodeToRemove->parent != nullptr)
|
||||
RemoveChild(nodeToRemove->parent, nodeToRemove);
|
||||
removeChild(nodeToRemove->parent, nodeToRemove);
|
||||
|
||||
ReleaseNode(nodeToRemove);
|
||||
releaseNode(nodeToRemove);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SHSceneGraph::Reset() noexcept
|
||||
{
|
||||
for (auto* node : entityNodeMap | std::views::values)
|
||||
ReleaseNode(node);
|
||||
releaseNode(node);
|
||||
}
|
||||
|
||||
bool SHSceneGraph::IsChildOf(EntityID entityID, SHSceneNode* targetNode) noexcept
|
||||
|
@ -456,39 +456,39 @@ namespace SHADE
|
|||
|
||||
void SHSceneGraph::Traverse (const UnaryFunction& function) const
|
||||
{
|
||||
TraverseAndInvokeFunction(root, function);
|
||||
traverseAndInvokeFunction(root, function);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Private Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHSceneNode* SHSceneGraph::AllocateNode(EntityID entityID)
|
||||
SHSceneNode* SHSceneGraph::allocateNode(EntityID entityID)
|
||||
{
|
||||
SHSceneNode* newNode = new SHSceneNode{entityID};
|
||||
entityNodeMap.emplace(entityID, newNode);
|
||||
return newNode;
|
||||
}
|
||||
|
||||
void SHSceneGraph::ReleaseNode(SHSceneNode* node) noexcept
|
||||
void SHSceneGraph::releaseNode(SHSceneNode* node) noexcept
|
||||
{
|
||||
SHASSERT(node != nullptr, "Attempting to release Invalid Node!")
|
||||
|
||||
// Remove parent's reference to this node if there is a parent
|
||||
if (node->parent != nullptr)
|
||||
RemoveChild(node->parent, node);
|
||||
removeChild(node->parent, node);
|
||||
|
||||
// Remove child's references to this node. Children end up as floating nodes.
|
||||
for (auto* child : node->GetChildren())
|
||||
{
|
||||
ChangeParent(child, nullptr);
|
||||
changeParent(child, nullptr);
|
||||
}
|
||||
|
||||
entityNodeMap.erase(node->GetEntityID());
|
||||
delete node;
|
||||
}
|
||||
|
||||
void SHSceneGraph::ChangeParent(SHSceneNode* node, SHSceneNode* newParent)
|
||||
void SHSceneGraph::changeParent(SHSceneNode* node, SHSceneNode* newParent)
|
||||
{
|
||||
// Handle self assignment
|
||||
if (node->parent != nullptr && newParent != nullptr && node->parent->entityID == newParent->entityID)
|
||||
|
@ -496,7 +496,7 @@ namespace SHADE
|
|||
|
||||
// Remove child
|
||||
if (node->parent)
|
||||
RemoveChild(node->parent, node);
|
||||
removeChild(node->parent, node);
|
||||
|
||||
if (newParent == nullptr)
|
||||
{
|
||||
|
@ -506,16 +506,16 @@ namespace SHADE
|
|||
|
||||
node->parent = newParent;
|
||||
// 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(newChild != nullptr, "Attempting to add a non-existent child to a SceneNode!")
|
||||
|
||||
if (newChild->parent)
|
||||
RemoveChild(newChild->parent, newChild);
|
||||
removeChild(newChild->parent, newChild);
|
||||
|
||||
newChild->parent = node;
|
||||
node->children.emplace_back(newChild);
|
||||
|
@ -529,7 +529,7 @@ namespace SHADE
|
|||
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(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);
|
||||
}
|
||||
|
||||
void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function)
|
||||
void SHSceneGraph::traverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function)
|
||||
{
|
||||
for (auto* child : node->children)
|
||||
{
|
||||
function(child);
|
||||
TraverseAndInvokeFunction(child, function);
|
||||
traverseAndInvokeFunction(child, function);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,10 @@ namespace SHADE
|
|||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Encapsulates a hierarchical tree for objects in the scene.
|
||||
*/
|
||||
class SH_API SHSceneGraph
|
||||
{
|
||||
public:
|
||||
|
@ -64,22 +68,75 @@ namespace SHADE
|
|||
/* 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;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* 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);
|
||||
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:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -93,14 +150,14 @@ namespace SHADE
|
|||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
SHSceneNode* AllocateNode (EntityID entityID);
|
||||
void ReleaseNode (SHSceneNode* node) noexcept;
|
||||
SHSceneNode* allocateNode (EntityID entityID);
|
||||
void releaseNode (SHSceneNode* node) noexcept;
|
||||
|
||||
void ChangeParent (SHSceneNode* node, SHSceneNode* newParent);
|
||||
void AddChild (SHSceneNode* node, SHSceneNode* newChild);
|
||||
void RemoveChild (SHSceneNode* node, SHSceneNode* childToRemove);
|
||||
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);
|
||||
};
|
||||
|
||||
} // namespace SHADE
|
|
@ -17,6 +17,7 @@
|
|||
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||
//#include "FRC/SHFrameRateController.h"
|
||||
//#include "ECS_Base/System/SHApplication.h"
|
||||
#include "SHSceneEvents.h"
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
@ -55,10 +56,11 @@ namespace SHADE
|
|||
if (currentScene)
|
||||
{
|
||||
currentScene->Free();
|
||||
SHEventManager::BroadcastEvent<SHSceneExitEvent>(SHSceneExitEvent{ currentSceneID }, SH_SCENE_ON_EXIT_EVENT);
|
||||
|
||||
currentScene->Unload();
|
||||
SHEntityManager::DestroyAllEntity();
|
||||
delete currentScene;
|
||||
|
||||
}
|
||||
if (!prevSceneReload)
|
||||
{
|
||||
|
@ -84,6 +86,8 @@ namespace SHADE
|
|||
{
|
||||
currentScene->Load();
|
||||
currentScene->Init();
|
||||
|
||||
SHEventManager::BroadcastEvent<SHSceneInitEvent>(SHSceneInitEvent{ currentSceneID }, SH_SCENE_ON_INIT_EVENT);
|
||||
}
|
||||
}
|
||||
else // restarting scene
|
||||
|
@ -91,6 +95,8 @@ namespace SHADE
|
|||
nextSceneID = UINT32_MAX;
|
||||
|
||||
currentScene->Free();
|
||||
SHEventManager::BroadcastEvent<SHSceneExitEvent>(SHSceneExitEvent{ currentSceneID }, SH_SCENE_ON_EXIT_EVENT);
|
||||
|
||||
if (cleanReload == true)
|
||||
{
|
||||
cleanReload = false;
|
||||
|
@ -103,6 +109,7 @@ namespace SHADE
|
|||
SHEntityManager::DestroyAllEntity();
|
||||
|
||||
currentScene->Init();
|
||||
SHEventManager::BroadcastEvent<SHSceneInitEvent>(SHSceneInitEvent{ currentSceneID }, SH_SCENE_ON_INIT_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,20 +15,17 @@
|
|||
// Project Headers
|
||||
#include "ECS_Base/Entity/SHEntity.h"
|
||||
#include "SH_API.h"
|
||||
#include "SHSceneGraph.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Forward Declarations */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
class SHSceneGraph;
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Encapsulates an object in the scene that is part of the scene's hierarchy.
|
||||
*/
|
||||
class SH_API SHSceneNode
|
||||
{
|
||||
private:
|
||||
|
@ -66,7 +63,7 @@ namespace SHADE
|
|||
/* Setter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
void SetActive (bool newActiveState) noexcept;
|
||||
void SetActive (bool newActiveState) noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
Loading…
Reference in New Issue