Fixed deletion bugs
This commit is contained in:
parent
6fd6ee61a6
commit
277a3ca011
|
@ -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
|
||||
, 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,30 +162,34 @@ 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()
|
||||
{
|
||||
physicsObjects.clear();
|
||||
// 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 */
|
||||
|
@ -195,25 +197,23 @@ namespace SHADE
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue