From 277a3ca0116075c37350b0dd1cba61a0721edde1 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Sun, 13 Nov 2022 17:42:48 +0800 Subject: [PATCH] Fixed deletion bugs --- .../PhysicsObject/SHPhysicsObjectManager.cpp | 90 ++++++++++--------- .../PhysicsObject/SHPhysicsObjectManager.h | 17 ++-- .../src/Physics/System/SHPhysicsSystem.cpp | 16 ++-- .../System/SHPhysicsSystemRoutines.cpp | 1 + 4 files changed, 65 insertions(+), 59 deletions(-) diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp index 3820ccbe..13f525e6 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.cpp @@ -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(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(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(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); } diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.h b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.h index 91dcce5f..d8c9b805 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.h +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObjectManager.h @@ -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 \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 361e7c9e..5763e2ea 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -246,12 +246,11 @@ namespace SHADE #ifdef SHEDITOR - auto* editor = SHSystemManager::GetSystem(); + const auto* EDITOR = SHSystemManager::GetSystem(); - 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(); - if (editor) - { - if (editor->editorState != SHEditor::State::STOP) - REMOVED_ID == RIGID_BODY_ID ? objectManager.RemoveRigidBody(EID) : objectManager.RemoveCollider(EID); - } + const auto* EDITOR = SHSystemManager::GetSystem(); + + 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; diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp index 26c740cc..059202e5 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp @@ -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(); } }