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