Fixed deletion bugs

This commit is contained in:
Diren D Bharwani 2022-11-13 17:42:48 +08:00
parent 6fd6ee61a6
commit 277a3ca011
4 changed files with 65 additions and 59 deletions

View File

@ -14,6 +14,7 @@
#include "SHPhysicsObjectManager.h"
// Project Headers
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Tools/SHUtilities.h"
namespace SHADE
@ -22,10 +23,11 @@ namespace SHADE
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHPhysicsObjectManager::CommandFunctionPtr SHPhysicsObjectManager::componentFunc[2][2]
SHPhysicsObjectManager::CommandFunctionPtr SHPhysicsObjectManager::componentFunc[2][3]
{
addRigidBody , addCollider
, removeRigidBody , removeCollider
addRigidBody , addCollider
, removeRigidBody , removeCollider
, addCollisionShape , removeCollisionShape
};
/*-----------------------------------------------------------------------------------*/
@ -152,11 +154,7 @@ namespace SHADE
if (COMMAND.command == QueueCommand::Command::INVALID || COMMAND.component == PhysicsComponents::INVALID)
continue;
// Find the physics Object & retrieve components. Create an object if none exists.
SHPhysicsObject* physicsObject = GetPhysicsObject(COMMAND.eid);
if (!physicsObject)
physicsObject = createPhysicsObject(COMMAND.eid);
// Get physics components
const PhysicsComponentGroup COMPONENT_GROUP
{
.eid = COMMAND.eid
@ -164,56 +162,58 @@ namespace SHADE
, .colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(COMMAND.eid)
};
if (COMMAND.component == PhysicsComponents::COLLISION_SHAPE)
{
if (COMMAND.command == QueueCommand::Command::ADD)
addCollisionShape(physicsObject, COMMAND.shapeIndex);
if (COMMAND.command == QueueCommand::Command::REMOVE)
removeCollisionShape(physicsObject, COMMAND.shapeIndex);
}
else // Rigid Body or Collider
{
componentFunc[SHUtilities::ConvertEnum(COMMAND.command)][SHUtilities::ConvertEnum(COMMAND.component)](physicsObject, COMPONENT_GROUP);
}
// If main components are missing, destroy object
// Delete any object that is missing both components
// We infer that a remove command has been pushed for these, but we will ignore those if both components have already been removed.
if (!COMPONENT_GROUP.rigidBodyComponent && !COMPONENT_GROUP.colliderComponent)
{
destroyPhysicsObject(COMMAND.eid);
continue;
}
// Find the physics Object. If none found and attempting to add, create an object.
SHPhysicsObject* physicsObject = GetPhysicsObject(COMMAND.eid);
if (!physicsObject && COMMAND.command == QueueCommand::Command::ADD)
physicsObject = createPhysicsObject(COMMAND.eid);
componentFunc[SHUtilities::ConvertEnum(COMMAND.command)][SHUtilities::ConvertEnum(COMMAND.component)](COMMAND, physicsObject, COMPONENT_GROUP);
}
}
void SHPhysicsObjectManager::RemoveAllObjects()
{
// Destroy all objects and clear
for (auto& physicsObject : physicsObjects | std::views::values)
{
world->destroyRigidBody(physicsObject.GetRigidBody());
physicsObject.rp3dBody = nullptr;
}
physicsObjects.clear();
}
/*-----------------------------------------------------------------------------------*/
/* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHPhysicsObject* SHPhysicsObjectManager::createPhysicsObject(EntityID eid) noexcept
{
auto& newPhysicsObject = physicsObjects.emplace(eid, SHPhysicsObject{ eid, factory, world }).first->second;
// Force transforms to sync
const auto* TRANSFORM = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
SHVec3 worldPos = SHVec3::Zero;
SHQuaternion worldRot = SHQuaternion::Identity;
if (!TRANSFORM)
{
SHLOGV_ERROR("Unable to sync transforms with Physics Object for Entity {}", eid);
}
else
const SHTransformComponent* TRANSFORM = nullptr;
if (SHEntityManager::IsValidEID(eid))
TRANSFORM = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
if (TRANSFORM)
{
worldPos = TRANSFORM->GetWorldPosition();
worldRot = TRANSFORM->GetWorldOrientation();
}
const rp3d::Transform RP3D_TRANSFORM{ worldPos, worldRot };
auto& newPhysicsObject = physicsObjects.emplace(eid, SHPhysicsObject{ eid, factory, world }).first->second;
newPhysicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM);
newPhysicsObject.prevTransform = RP3D_TRANSFORM;
@ -222,10 +222,20 @@ namespace SHADE
void SHPhysicsObjectManager::destroyPhysicsObject(EntityID eid) noexcept
{
const auto ITER = physicsObjects.find(eid);
if (ITER == physicsObjects.end())
{
// Assume the object has already been successfully destroyed
return;
}
world->destroyRigidBody(ITER->second.GetRigidBody());
ITER->second.rp3dBody = nullptr;
physicsObjects.erase(eid);
}
void SHPhysicsObjectManager::addRigidBody(SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup)
void SHPhysicsObjectManager::addRigidBody(const QueueCommand&, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup)
{
SHASSERT(physicsObject != nullptr, "Valid physics object required to add body!")
@ -241,7 +251,7 @@ namespace SHADE
physicsObject->SyncRigidBody(*componentGroup.rigidBodyComponent);
}
void SHPhysicsObjectManager::addCollider(SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup)
void SHPhysicsObjectManager::addCollider(const QueueCommand&, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup)
{
SHASSERT(physicsObject != nullptr, "Valid physics object required to add collider!")
@ -258,7 +268,7 @@ namespace SHADE
physicsObject->SyncColliders(*componentGroup.colliderComponent);
}
void SHPhysicsObjectManager::removeRigidBody(SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup)
void SHPhysicsObjectManager::removeRigidBody(const QueueCommand&, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup)
{
SHASSERT(physicsObject != nullptr, "Valid physics object required to remove body!")
@ -266,25 +276,25 @@ namespace SHADE
physicsObject->SetStaticBody();
}
void SHPhysicsObjectManager::removeCollider(SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup)
void SHPhysicsObjectManager::removeCollider(const QueueCommand&, SHPhysicsObject* physicsObject, const PhysicsComponentGroup&)
{
SHASSERT(physicsObject != nullptr, "Valid physics object required to remove collider!")
physicsObject->RemoveAllCollisionShapes();
}
void SHPhysicsObjectManager::addCollisionShape(SHPhysicsObject* physicsObject, int shapeIndex)
void SHPhysicsObjectManager::addCollisionShape(const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup&)
{
SHASSERT(physicsObject != nullptr, "Valid physics object required to add collision shape!")
physicsObject->AddCollisionShape(shapeIndex);
physicsObject->AddCollisionShape(command.shapeIndex);
}
void SHPhysicsObjectManager::removeCollisionShape(SHPhysicsObject* physicsObject, int shapeIndex)
void SHPhysicsObjectManager::removeCollisionShape(const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup&)
{
SHASSERT(physicsObject != nullptr, "Valid physics object required to remove collision shape!")
physicsObject->RemoveCollisionShape(shapeIndex);
physicsObject->RemoveCollisionShape(command.shapeIndex);
}

View File

@ -144,13 +144,13 @@ namespace SHADE
SHColliderComponent* colliderComponent = nullptr;
};
using CommandFunctionPtr = void(*)(SHPhysicsObject*, const PhysicsComponentGroup&);
using CommandFunctionPtr = void(*)(const QueueCommand&, SHPhysicsObject*, const PhysicsComponentGroup&);
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
static CommandFunctionPtr componentFunc[2][2]; // Used only for rigid body & collider components. Collision shapes are handled separately.
static CommandFunctionPtr componentFunc[2][3]; // 2 commands, 3 components
rp3d::PhysicsCommon* factory = nullptr;
rp3d::PhysicsWorld* world = nullptr;
@ -165,14 +165,13 @@ namespace SHADE
SHPhysicsObject* createPhysicsObject (EntityID eid) noexcept;
void destroyPhysicsObject (EntityID eid) noexcept;
static void addRigidBody (SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void addCollider (SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void removeRigidBody (SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void removeCollider (SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void addCollisionShape (SHPhysicsObject* physicsObject, int shapeIndex);
static void removeCollisionShape (SHPhysicsObject* physicsObject, int shapeIndex);
static void addRigidBody (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void addCollider (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void removeRigidBody (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void removeCollider (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void addCollisionShape (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void removeCollisionShape (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
};
} // namespace SHADE

View File

@ -246,12 +246,11 @@ namespace SHADE
#ifdef SHEDITOR
auto* editor = SHSystemManager::GetSystem<SHEditor>();
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
if (editor && editor->editorState != SHEditor::State::STOP)
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
ADDED_ID == RIGID_BODY_ID ? objectManager.AddRigidBody(EID) : objectManager.AddCollider(EID);
#else
ADDED_ID == RIGID_BODY_ID ? objectManager.AddRigidBody(EID) : objectManager.AddCollider(EID);
@ -279,19 +278,16 @@ namespace SHADE
#ifdef SHEDITOR
auto* editor = SHSystemManager::GetSystem<SHEditor>();
if (editor)
{
if (editor->editorState != SHEditor::State::STOP)
REMOVED_ID == RIGID_BODY_ID ? objectManager.RemoveRigidBody(EID) : objectManager.RemoveCollider(EID);
}
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
REMOVED_ID == RIGID_BODY_ID ? objectManager.RemoveRigidBody(EID) : objectManager.RemoveCollider(EID);
#else
REMOVED_ID == RIGID_BODY_ID ? objectManager.RemoveRigidBody(EID) : objectManager.RemoveCollider(EID);
#endif
}
return EVENT_DATA->handle;

View File

@ -183,6 +183,7 @@ namespace SHADE
scriptingSystem->ExecuteCollisionFunctions();
// Since this function never runs when editor in not in play, execute the function anyway
physicsSystem->collisionListener.CleanContainers();
}
}