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" #include "SHPhysicsObjectManager.h"
// Project Headers // Project Headers
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Tools/SHUtilities.h" #include "Tools/SHUtilities.h"
namespace SHADE namespace SHADE
@ -22,10 +23,11 @@ namespace SHADE
/* Static Data Member Definitions */ /* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHPhysicsObjectManager::CommandFunctionPtr SHPhysicsObjectManager::componentFunc[2][2] SHPhysicsObjectManager::CommandFunctionPtr SHPhysicsObjectManager::componentFunc[2][3]
{ {
addRigidBody , addCollider addRigidBody , addCollider
, removeRigidBody , removeCollider , removeRigidBody , removeCollider
, addCollisionShape , removeCollisionShape
}; };
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -152,11 +154,7 @@ namespace SHADE
if (COMMAND.command == QueueCommand::Command::INVALID || COMMAND.component == PhysicsComponents::INVALID) if (COMMAND.command == QueueCommand::Command::INVALID || COMMAND.component == PhysicsComponents::INVALID)
continue; continue;
// Find the physics Object & retrieve components. Create an object if none exists. // Get physics components
SHPhysicsObject* physicsObject = GetPhysicsObject(COMMAND.eid);
if (!physicsObject)
physicsObject = createPhysicsObject(COMMAND.eid);
const PhysicsComponentGroup COMPONENT_GROUP const PhysicsComponentGroup COMPONENT_GROUP
{ {
.eid = COMMAND.eid .eid = COMMAND.eid
@ -164,56 +162,58 @@ namespace SHADE
, .colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(COMMAND.eid) , .colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(COMMAND.eid)
}; };
if (COMMAND.component == PhysicsComponents::COLLISION_SHAPE) // 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 (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
if (!COMPONENT_GROUP.rigidBodyComponent && !COMPONENT_GROUP.colliderComponent) if (!COMPONENT_GROUP.rigidBodyComponent && !COMPONENT_GROUP.colliderComponent)
{
destroyPhysicsObject(COMMAND.eid); 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() void SHPhysicsObjectManager::RemoveAllObjects()
{ {
// Destroy all objects and clear
for (auto& physicsObject : physicsObjects | std::views::values)
{
world->destroyRigidBody(physicsObject.GetRigidBody());
physicsObject.rp3dBody = nullptr;
}
physicsObjects.clear(); physicsObjects.clear();
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Private Function Member Definitions */ /* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHPhysicsObject* SHPhysicsObjectManager::createPhysicsObject(EntityID eid) noexcept SHPhysicsObject* SHPhysicsObjectManager::createPhysicsObject(EntityID eid) noexcept
{ {
auto& newPhysicsObject = physicsObjects.emplace(eid, SHPhysicsObject{ eid, factory, world }).first->second;
// Force transforms to sync // Force transforms to sync
const auto* TRANSFORM = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
SHVec3 worldPos = SHVec3::Zero; SHVec3 worldPos = SHVec3::Zero;
SHQuaternion worldRot = SHQuaternion::Identity; SHQuaternion worldRot = SHQuaternion::Identity;
if (!TRANSFORM) const SHTransformComponent* TRANSFORM = nullptr;
{ if (SHEntityManager::IsValidEID(eid))
SHLOGV_ERROR("Unable to sync transforms with Physics Object for Entity {}", eid); TRANSFORM = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
}
else if (TRANSFORM)
{ {
worldPos = TRANSFORM->GetWorldPosition(); worldPos = TRANSFORM->GetWorldPosition();
worldRot = TRANSFORM->GetWorldOrientation(); worldRot = TRANSFORM->GetWorldOrientation();
} }
const rp3d::Transform RP3D_TRANSFORM{ worldPos, worldRot }; const rp3d::Transform RP3D_TRANSFORM{ worldPos, worldRot };
auto& newPhysicsObject = physicsObjects.emplace(eid, SHPhysicsObject{ eid, factory, world }).first->second;
newPhysicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM); newPhysicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM);
newPhysicsObject.prevTransform = RP3D_TRANSFORM; newPhysicsObject.prevTransform = RP3D_TRANSFORM;
@ -222,10 +222,20 @@ namespace SHADE
void SHPhysicsObjectManager::destroyPhysicsObject(EntityID eid) noexcept 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); 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!") SHASSERT(physicsObject != nullptr, "Valid physics object required to add body!")
@ -241,7 +251,7 @@ namespace SHADE
physicsObject->SyncRigidBody(*componentGroup.rigidBodyComponent); 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!") SHASSERT(physicsObject != nullptr, "Valid physics object required to add collider!")
@ -258,7 +268,7 @@ namespace SHADE
physicsObject->SyncColliders(*componentGroup.colliderComponent); 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!") SHASSERT(physicsObject != nullptr, "Valid physics object required to remove body!")
@ -266,25 +276,25 @@ namespace SHADE
physicsObject->SetStaticBody(); 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!") SHASSERT(physicsObject != nullptr, "Valid physics object required to remove collider!")
physicsObject->RemoveAllCollisionShapes(); 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!") 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!") 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; SHColliderComponent* colliderComponent = nullptr;
}; };
using CommandFunctionPtr = void(*)(SHPhysicsObject*, const PhysicsComponentGroup&); using CommandFunctionPtr = void(*)(const QueueCommand&, SHPhysicsObject*, const PhysicsComponentGroup&);
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Data Members */ /* 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::PhysicsCommon* factory = nullptr;
rp3d::PhysicsWorld* world = nullptr; rp3d::PhysicsWorld* world = nullptr;
@ -165,14 +165,13 @@ namespace SHADE
SHPhysicsObject* createPhysicsObject (EntityID eid) noexcept; SHPhysicsObject* createPhysicsObject (EntityID eid) noexcept;
void destroyPhysicsObject (EntityID eid) noexcept; void destroyPhysicsObject (EntityID eid) noexcept;
static void addRigidBody (SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup); static void addRigidBody (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void addCollider (SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup); static void addCollider (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void removeRigidBody (SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup); static void removeRigidBody (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void removeCollider (SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup); static void removeCollider (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void addCollisionShape (SHPhysicsObject* physicsObject, int shapeIndex);
static void removeCollisionShape (SHPhysicsObject* physicsObject, int shapeIndex);
static void addCollisionShape (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
static void removeCollisionShape (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
}; };
} // namespace SHADE } // namespace SHADE

View File

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

View File

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